魔兽地图编辑器吧 关注:64,769贴子:3,833,278

为Lua引擎注册DzApi函数

只看楼主收藏回复

原理很简单:
使用memory hack 内置DLL实现,但是不知道为什么这东西并没有在贴吧普及。
mem hack 使用的是贴吧内置JAPI1.4的相关代码
为lua注册dzapi函数的DLL源码中直接从YDWE项目中复制粘贴了部分代码过来(ps:懒!!!)


IP属地:湖南1楼2021-04-05 22:07回复


    目前只做了 编辑器版本的,平台好像跟编辑器环境不一样。
    只做了最简单的测试
    系统环境:win 10 18362


    IP属地:湖南2楼2021-04-05 22:14
    回复
      /*************************** dz_w3_plugin.dll ***************************/
      /* ida 搜索 DzLoadToc
      .text:10029A41 C7 85 A8 FD FF FF C0 92 07 10 mov [ebp+var_258], offset aDzloadtoc ; "DzLoadToc"
      .text:10029A4B C7 85 AC FD FF FF CC 92 07 10 mov [ebp+var_254], offset aSV_0 ; "(S)V"
      .text:10029A55 C7 85 B0 FD FF FF A0 71 02 10 mov [ebp+var_250], offset sub_100271A0
      .text:10029A5F C7 85 B4 FD FF FF D4 92 07 10 mov [ebp+var_24C], offset aDzframesetpoin ; "DzFrameSetPoint"
      .text:10029A69 C7 85 B8 FD FF FF E4 92 07 10 mov [ebp+var_248], offset aIiiirrV ; "(IIIIRR)V"
      .text:10029A73 C7 85 BC FD FF FF 40 72 02 10 mov [ebp+var_244], offset sub_10027240
      */


      IP属地:湖南3楼2021-04-05 22:28
      回复
        /* 通过函数调用 找到 下面的函数(函数名我已重命名)
        .text:10016860
        .text:10016860 ; =============== S U B R O U T I N E =======================================
        .text:10016860
        .text:10016860 ; 调用该函数,然后hook DzApi_register 这个函数将数据添加到lua引擎的japi库,然后返回.
        .text:10016860 ; Attributes: bp-based frame
        .text:10016860
        .text:10016860 Init_DzApi proc near ; CODE XREF: .text:10016887↓p
        .text:10016860 55 push ebp
        .text:10016861 8B EC mov ebp, esp
        .text:10016863 E8 78 E2 00 00 call Dz_Map_Api
        .text:10016868 E8 C3 89 01 00 call Dz_HardWare_Api
        .text:1001686D E8 0E A5 01 00 call Dz_SyncData_Api
        .text:10016872 E8 19 2F 01 00 call Dz_UI_Api
        .text:10016877 E8 14 C1 01 00 call Dz_Other_Api
        .text:1001687C 5D pop ebp
        .text:1001687D C3 retn
        .text:1001687D Init_DzApi endp
        */


        IP属地:湖南4楼2021-04-05 22:29
        回复
          /*Dz_SyncData_Api
          .text:10030D7D CC CC CC align 10h
          .text:10030D80
          .text:10030D80 ; =============== S U B R O U T I N E =======================================
          .text:10030D80
          .text:10030D80 ; Attributes: bp-based frame
          .text:10030D80
          .text:10030D80 Dz_SyncData_Api proc near ; CODE XREF: Init_DzApi+D↑p
          .text:10030D80
          .text:10030D80 var_44 = dword ptr -44h
          .text:10030D80 var_40 = dword ptr -40h
          .text:10030D80 var_3C = dword ptr -3Ch
          .text:10030D80 var_38 = dword ptr -38h
          .text:10030D80 var_34 = dword ptr -34h
          .text:10030D80 var_30 = dword ptr -30h
          .text:10030D80 var_2C = dword ptr -2Ch
          .text:10030D80 var_28 = dword ptr -28h
          .text:10030D80 var_24 = dword ptr -24h
          .text:10030D80 var_20 = dword ptr -20h
          .text:10030D80 var_1C = dword ptr -1Ch
          .text:10030D80 var_18 = dword ptr -18h
          .text:10030D80 var_14 = dword ptr -14h
          .text:10030D80 var_10 = dword ptr -10h
          .text:10030D80 var_C = dword ptr -0Ch
          .text:10030D80 var_8 = dword ptr -8
          .text:10030D80 var_4 = dword ptr -4
          .text:10030D80
          .text:10030D80 55 push ebp
          .text:10030D81 8B EC mov ebp, esp
          .text:10030D83 83 EC 44 sub esp, 44h
          .text:10030D86 A1 6C 40 08 10 mov eax, ___security_cookie
          .text:10030D8B 33 C5 xor eax, ebp
          .text:10030D8D 89 45 FC mov [ebp+var_4], eax
          .text:10030D90 C7 45 CC 60 09 03 10 mov [ebp+var_34], offset sub_10030960
          .text:10030D97 C7 45 D0 3C A1 07 10 mov [ebp+var_30], offset aDztriggerregis_9 ; "DzTriggerRegisterSyncData"
          .text:10030D9E C7 45 D4 58 A1 07 10 mov [ebp+var_2C], offset aHtriggerSbV ; "(Htrigger;SB)V"
          .text:10030DA5 C7 45 D8 F0 0A 03 10 mov [ebp+var_28], offset sub_10030AF0
          .text:10030DAC C7 45 DC 68 A1 07 10 mov [ebp+var_24], offset aDzsyncdata ; "DzSyncData"
          .text:10030DB3 C7 45 E0 74 A1 07 10 mov [ebp+var_20], offset aSsV ; "(SS)V"
          .text:10030DBA C7 45 E4 30 0D 03 10 mov [ebp+var_1C], offset sub_10030D30
          .text:10030DC1 C7 45 E8 7C A1 07 10 mov [ebp+var_18], offset aDzgettriggersy ; "DzGetTriggerSyncData"
          .text:10030DC8 C7 45 EC 94 A1 07 10 mov [ebp+var_14], offset aS_1 ; "()S"
          .text:10030DCF C7 45 F0 60 0D 03 10 mov [ebp+var_10], offset sub_10030D60
          .text:10030DD6 C7 45 F4 98 A1 07 10 mov [ebp+var_C], offset aDzgettriggersy_0 ; "DzGetTriggerSyncPlayer"
          .text:10030DDD C7 45 F8 B0 A1 07 10 mov [ebp+var_8], offset aHplayer_1 ; "()Hplayer;"
          .text:10030DE4 8D 45 CC lea eax, [ebp+var_34]
          .text:10030DE7 89 45 C0 mov [ebp+var_40], eax
          .text:10030DEA 8B 4D C0 mov ecx, [ebp+var_40]
          .text:10030DED 89 4D C8 mov [ebp+var_38], ecx
          .text:10030DF0 8B 55 C0 mov edx, [ebp+var_40]
          .text:10030DF3 83 C2 30 add edx, 30h ; '0'
          .text:10030DF6 89 55 BC mov [ebp+var_44], edx
          .text:10030DF9 EB 09 jmp short loc_10030E04
          .text:10030DFB ; ---------------------------------------------------------------------------
          .text:10030DFB
          .text:10030DFB loc_10030DFB: ; CODE XREF: Dz_SyncData_Api+AB↓j
          .text:10030DFB 8B 45 C8 mov eax, [ebp+var_38]
          .text:10030DFE 83 C0 0C add eax, 0Ch
          .text:10030E01 89 45 C8 mov [ebp+var_38], eax
          .text:10030E04
          .text:10030E04 loc_10030E04: ; CODE XREF: Dz_SyncData_Api+79↑j
          .text:10030E04 8B 4D C8 mov ecx, [ebp+var_38]
          .text:10030E07 3B 4D BC cmp ecx, [ebp+var_44]
          .text:10030E0A 74 21 jz short loc_10030E2D
          .text:10030E0C 8B 55 C8 mov edx, [ebp+var_38]
          .text:10030E0F 89 55 C4 mov [ebp+var_3C], edx
          .text:10030E12 8B 45 C4 mov eax, [ebp+var_3C]
          .text:10030E15 8B 48 08 mov ecx, [eax+8]
          .text:10030E18 51 push ecx
          .text:10030E19 8B 55 C4 mov edx, [ebp+var_3C]
          .text:10030E1C 8B 42 04 mov eax, [edx+4]
          .text:10030E1F 50 push eax
          .text:10030E20 8B 4D C4 mov ecx, [ebp+var_3C]
          .text:10030E23 8B 11 mov edx, [ecx]
          .text:10030E25 52 push edx
          .text:10030E26 E8 B5 9E FE FF call DzApi_Register
          .text:10030E2B EB CE jmp short loc_10030DFB
          .text:10030E2D ; ---------------------------------------------------------------------------
          .text:10030E2D
          .text:10030E2D loc_10030E2D: ; CODE XREF: Dz_SyncData_Api+8A↑j
          .text:10030E2D 8B 4D FC mov ecx, [ebp+var_4]
          .text:10030E30 33 CD xor ecx, ebp ; StackCookie
          .text:10030E32 E8 89 5A 00 00 call @__security_check_cookie@4 ; __security_check_cookie(x)
          .text:10030E37 8B E5 mov esp, ebp
          .text:10030E39 5D pop ebp
          .text:10030E3A C3 retn
          .text:10030E3A Dz_SyncData_Api endp
          .text:10030E26 E8 B5 9E FE FF call DzApi_Register
          通过该函数注册DzApi函数
          */


          IP属地:湖南5楼2021-04-05 22:30
          回复
            /*DzApi_Register
            text:1001ACE0
            .text:1001ACE0 ; =============== S U B R O U T I N E =======================================
            .text:1001ACE0
            .text:1001ACE0 ; Attributes: bp-based frame
            .text:1001ACE0
            .text:1001ACE0 DzApi_Register proc near ; CODE XREF: Dz_Map_Api+4BA↓p
            .text:1001ACE0 ; Dz_UI_Api+898↓p ...
            .text:1001ACE0
            .text:1001ACE0 arg_0 = dword ptr 8
            .text:1001ACE0 arg_4 = dword ptr 0Ch
            .text:1001ACE0 arg_8 = dword ptr 10h
            .text:1001ACE0
            .text:1001ACE0 55 push ebp
            .text:1001ACE1 8B EC mov ebp, esp
            .text:1001ACE3 8B 45 10 mov eax, [ebp+arg_8]
            .text:1001ACE7 8B 4D 0C mov ecx, [ebp+arg_4]
            .text:1001ACE6 50 push eax ; int
            .text:1001ACEA 51 push ecx ; int
            .text:1001ACEB 8B 55 08 mov edx, [ebp+arg_0]
            .text:1001ACEE 52 push edx ; int
            .text:1001ACEF 68 08 52 07 10 push offset aFunctionRegist_10 ; "FUNCTION_RegisterNativeFunction"
            .text:1001ACF4 E8 87 0E 00 00 call sub_1001BB80
            .text:1001ACF9 83 C4 10 add esp, 10h
            .text:1001ACFC 5D pop ebp
            .text:1001ACFD C2 0C 00 retn 0Ch
            .text:1001ACFD DzApi_Register endp
            观察此函数,可以发现传递了三个参数进来,这三个参数就是japi注册需要使用的三个参数:参数返回值 函数名 函数地址
            再进一步的细节我觉得并不需要我们关心
            */


            IP属地:湖南6楼2021-04-05 22:31
            回复
              /*
              现在来说说DzApi大致的注册流程(在编辑器中使用的时候)
              1.通过Init_DzApi注册所有的DzApi函数
              Init_DzApi中
              call Dz_Map_Api
              call Dz_HardWare_Api
              call Dz_SyncData_Api
              call Dz_UI_Api
              call Dz_Other_Api
              2.以Dz_SyncData_Api为例
              在函数中将japi三元组存储在局部变量中 (三元组:参数返回值、函数名、函数地址)
              然后调用 DzApi_Register 来注册dzapi(实质就是japi)函数
              ps:DzApi_Register到底是如何去注册dzapi函数我并不关心,我想获得的只是三元组而已.有兴趣可以自己继续深入
              */


              IP属地:湖南7楼2021-04-05 22:36
              回复
                *
                现在我们已经拿到DzApi所有函数的三元组,应该怎么添加到lua引擎中去呢?
                首先我们来看看 YDWE 是如何添加japi函数吧
                */
                /*************************** yd_lua_engine.dll ***************************/
                /*
                这是YDWE初始化lua引擎的部分源码
                static void initialize_lua()
                {
                const char* buf = 0;
                size_t len = 0;
                if (storm_s::instance().load_file("script\\war3map.lua", (const void**)&buf, &len))
                {
                lua_State* L = getMainL();
                if (luaL_loadbuffer(L, buf, len, "@script\\war3map.lua") != LUA_OK) {
                printf("%s\n", lua_tostring(L, -1));
                lua_pop(L, 1);
                storm_s::instance().unload_file(buf);
                return;
                }
                safe_call(L, 0, 0, true);
                storm_s::instance().unload_file(buf);
                }
                else
                {
                jass::table_hook("Cheat", (uintptr_t*)&RealCheat, (uintptr_t)FakeCheat);
                jass::japi_table_add((uintptr_t)EXExecuteScript, "EXExecuteScript", "(S)S");
                }
                }
                可以在else中看到 如果你在jass中使用了 Cheat 那么会为japi的表中添加一个japi函数 EXExecuteScript
                那么我们只要找到 jass::japi_table_add 这个函数的地址就行了
                */


                IP属地:湖南8楼2021-04-05 22:37
                回复
                  /*在OD中搜索字符串 EXExecuteScript
                  66FB10A3 | 68 2074FC66 | push yd_lua_engine.66FC7420| 66FC7420:"EXExecuteScript"
                  66FB10A8 | 68 F713FC66 | push yd_lua_engine.66FC13F7|
                  66FB10AD | FF15 5854FC66 | call dword ptr ds:[<&?japi_add@jass@warcraft3@base@@YA_NIPBD0@ |
                  我们可以看到 66FB10AD | FF15 5854FC66 这一段就是 call jass::japi_table_add这个函数了
                  通过硬编码计算我们可以得到 jass::japi_table_add 的函数地址
                  */


                  IP属地:湖南9楼2021-04-05 22:38
                  回复
                    /*
                    至此,我们已经得到我们需要的所有信息,准备编写代码向lua引擎中注册DzApi函数
                    简单说下我的思路,当然你采用其他思路也行,最终目标是向lua引擎中的japi_table中注册DzApi函数。
                    1.找到Init_DzApi函数地址
                    2.找到DzApi_Register函数地址
                    3.找到jass::japi_table_add函数地址
                    4.hook DzApi_Register 函数,让DzApi_Register执行的时候向lua引擎注册DzApi函数
                    5.执行Init_DzApi函数
                    */


                    IP属地:湖南10楼2021-04-05 22:39
                    收起回复
                      本层回复,附上DLL源码.
                      编译环境:VS2019


                      IP属地:湖南11楼2021-04-05 22:43
                      收起回复
                        你需要掌握的知识:
                        1.memory hack
                        参考资料:
                        可以在hive上搜索memory hack
                        github 搜索 DracoL1ch
                        俄国佬的论坛 xgm 上搜索 memory hack 或 mem hack
                        2.理解japi的实现原理
                        这个可以在咸鱼维基自己去看japi
                        2篇文章为主
                        JAPI基本原理及应用(未完待续.....) 作者:rahxephon
                        JAPI基本原理及应用(续) 作者: actboy168
                        链接我就不放了,免得抽楼.


                        IP属地:湖南12楼2021-04-05 22:51
                        收起回复
                          不懂


                          IP属地:山东来自Android客户端13楼2021-04-05 23:25
                          回复


                            IP属地:四川来自Android客户端14楼2021-04-06 06:43
                            回复
                              好东西,不过我都是用execfunc来调用dzapi的…


                              IP属地:广东来自Android客户端15楼2021-04-06 07:58
                              回复