恐怖黎明吧 关注:207,884贴子:2,654,376

【技术研究】大箱子Mod研究帖,已经证实可以实现

只看楼主收藏回复

自从出了mod工具后我就开始研究大箱子工具,结果发现游戏的关于共享箱子的逻辑部分都是写死的,在游戏dll和exe里面,然后我就开始调试游戏主程序,今天终于有了进展。
目前我是把游戏箱子的4个按钮改了,第一页功能不变,第二页的功能改成了向下翻页,第三页改成了向前翻页,因为同一个按钮不能连点两次,所以我把第四页改成无作用。然后把总页数改成了8页,由于游戏存档格式是支持超过4页的,所以能够正确存档,下面是初步效果视频。
视频来自:优酷

不过直接修改游戏UI是很困难的,不但每次更新都要跟着改,而且steam版必须先破解steamstub才行,所以我考虑把这个做成修改器通过按键实现,CE修改器是支持自动汇编的。


IP属地:北京1楼2016-05-02 14:56回复
    好高端~顶大神


    IP属地:广东来自Android客户端2楼2016-05-02 14:59
    回复
      下面是修改关键位置讲解,需要Ollydbg或类似调试器或者CE,而且要有一定汇编基础
      Game.dll需要修改两个函数,分别是
      GAME::GameEngine::AddTransferSack
      GAME::GameEngine::RestoreNumberOfTransferSack
      game.dll中的函数全部导出了,修改起来很方便
      GAME::GameEngine::AddTransferSack这个函数用来给共享箱子添加一页,代码如下:
      014DC450 G>/$ 55 push ebp
      014DC451 |. 8BEC mov ebp,esp
      014DC453 |. 6A FF push -1
      014DC455 |. 68 9F066701 push Game.0167069F ; SE 句柄安装
      014DC45A |. 64:A1 00000000 mov eax,dword ptr fs:[0]
      014DC460 |. 50 push eax
      014DC461 |. 64:8925 00000000 mov dword ptr fs:[0],esp
      014DC468 |. 51 push ecx
      014DC469 |. 8B81 64280000 mov eax,dword ptr ds:[ecx+2864]
      014DC46F |. 2B81 60280000 sub eax,dword ptr ds:[ecx+2860]
      014DC475 |. 56 push esi
      014DC476 |. 8DB1 60280000 lea esi,dword ptr ds:[ecx+2860]
      014DC47C |. C1F8 02 sar eax,2
      014DC47F |. 83F8 04 cmp eax,4
      014DC482 73 41 jnb short Game.014DC4C5
      014DC484 |. 6A 34 push 34 ; /Arg1 = 00000034
      014DC486 |. E8 CF811800 call Game.0166465A ; \Game.1006465A
      014DC48B |. 83C4 04 add esp,4
      014DC48E |. 8945 F0 mov [local.4],eax
      014DC491 |. 8BC8 mov ecx,eax
      014DC493 |. C745 FC 00000000 mov [local.1],0
      014DC49A |. E8 B1200200 call Game.GAME::InventorySack::InventorySack
      014DC49F |. C745 FC FFFFFFFF mov [local.1],-1
      注意014DC47F这行的cmp eax,4就是硬编码的箱子页数,大于这个数是无法添加的,我们进行如下修改
      014DC47F |. 83F8 04 cmp eax,4
      014DC482 90 nop
      014DC483 90 nop
      修改为空指令
      接下来是这个函数GAME::GameEngine::RestoreNumberOfTransferSack,是读取共享箱子文件时调用的
      014DC4E0 G> $ 55 push ebp
      014DC4E1 . 8BEC mov ebp,esp
      014DC4E3 . 6A FF push -1
      014DC4E5 . 68 9F066701 push Game.0167069F ; SE 句柄安装
      014DC4EA . 64:A1 00000000 mov eax,dword ptr fs:[0]
      014DC4F0 . 50 push eax
      014DC4F1 . 64:8925 00000000 mov dword ptr fs:[0],esp
      014DC4F8 . 51 push ecx
      014DC4F9 . 8B81 64280000 mov eax,dword ptr ds:[ecx+2864]
      ...
      ...
      014DC520 > /8B47 04 mov eax,dword ptr ds:[edi+4]
      014DC523 . |2B07 sub eax,dword ptr ds:[edi]
      014DC525 . |C1F8 02 sar eax,2
      014DC528 |83F8 04 cmp eax,4
      014DC52B |73 30 jnb short Game.014DC55D
      014DC52D . |6A 34 push 34 ; /Arg1 = 00000034
      014DC52F . |E8 26811800 call Game.0166465A ; \Game.1006465A
      014DC534 . |83C4 04 add esp,4
      014DC537 . |8945 F0 mov dword ptr ss:[ebp-10],eax
      014DC53A . |8BC8 mov ecx,eax
      014DC53C . |C745 FC 00000000 mov dword ptr ss:[ebp-4],0
      014DC543 . |E8 08200200 call Game.GAME::InventorySack::InventorySack
      014DC548 . |C745 FC FFFFFFFF mov dword ptr ss:[ebp-4],-1
      还是014DC528这行的cmp eax,4
      修改为
      014DC528 83F8 04 cmp eax,4
      014DC52B 90 nop
      014DC52C 90 nop
      这样游戏就可以读取多于4页的箱子了


      IP属地:北京3楼2016-05-02 15:07
      回复
        楼上的天书你们好啊


        IP属地:河北来自Android客户端4楼2016-05-02 15:10
        回复
          支持


          来自Android客户端6楼2016-05-02 15:14
          回复
            制作组5月3号更新日志,敬请期待大型独立dlc-大箱子


            IP属地:江西来自iPhone客户端7楼2016-05-02 15:21
            回复
              接下来是Grim Dawn.exe控制共享箱子的关键位置
              游戏主程序有3个关键位置,分别对应了初始化箱子界面,按钮回调函数和添加箱子页数,要查找位置首先需要通过反向查找Game.dll的相关引用
              第一个是添加箱子页数的函数
              01137220 $ 55 push ebp
              01137221 . 8BEC mov ebp,esp
              01137223 . 6A FF push -1
              01137225 . 68 D8BC2201 push Grim_Daw.0122BCD8 ; SE 句柄安装
              0113722A . 64:A1 00000000 mov eax,dword ptr fs:[0]
              ..
              ..
              011372E8 . 8D47 01 lea eax,dword ptr ds:[edi+1]
              011372EB . 2B0B sub ecx,dword ptr ds:[ebx]
              011372ED . C1F9 02 sar ecx,2
              011372F0 . 3BC8 cmp ecx,eax
              011372F2 .^ 73 B3 jnb short Grim_Daw.011372A7
              011372F4 . 8B0D 040F2401 mov ecx,dword ptr ds:[<&Game.GAME::gGameEngine>] ; Game.GAME::gGameEngine
              011372FA . 52 push edx
              011372FB . 8B09 mov ecx,dword ptr ds:[ecx]
              011372FD . FF15 240F2401 call dword ptr ds:[<&Game.GAME::GameEngine::GetMainPlay>; Game.GAME::GameEngine::GetMainPlayer
              01137303 . 8BC8 mov ecx,eax ; |
              01137305 . FF15 64112401 call dword ptr ds:[<&Game.GAME::Character::SubtractMone>; \GAME::Character::SubtractMoney
              0113730B . 8B0D 040F2401 mov ecx,dword ptr ds:[<&Game.GAME::gGameEngine>] ; Game.GAME::gGameEngine
              01137311 . 8B09 mov ecx,dword ptr ds:[ecx]
              01137313 . FF15 50272401 call dword ptr ds:[<&Game.GAME::GameEngine::AddTransfer>; Game.GAME::GameEngine::AddTransferSack
              ..
              ..
              01137331 . 8B0D 040F2401 mov ecx,dword ptr ds:[<&Game.GAME::gGameEngine>] ; Game.GAME::gGameEngine
              01137337 . 57 push edi ; /Arg1
              01137338 . 8B09 mov ecx,dword ptr ds:[ecx] ; |
              0113733A . FF15 48272401 call dword ptr ds:[<&Game.GAME::GameEngine::SetSelected>; \GAME::GameEngine::SetSelectedTransferSackNumber
              位置如上,可通过Game.GAME::GameEngine::AddTransferSack反向查找得到
              这个函数是有1个参数就是所需金钱,填0即可无限添加箱子页数
              第二个关键函数是共享箱子初始化函数
              01137A70 /. 55 push ebp
              01137A71 |. 8BEC mov ebp,esp
              01137A73 |. 6A FF push -1
              01137A75 |. 68 53062301 push Grim_Daw.01230653 ; SE 句柄安装
              01137A7A |. 64:A1 00000000 mov eax,dword ptr fs:[0]
              01137A80 |. 50 push eax
              ..
              ..
              01137AE4 |. 8D45 E8 lea eax,[local.6]
              01137AE7 |. 50 push eax
              01137AE8 |. 8D45 D0 lea eax,[local.12]
              01137AEB |. 50 push eax
              01137AEC |. FF15 18012401 call dword ptr ds:[<&Engine.GAME::Engine::GetSaveManage>; Engine.GAME::Engine::GetSaveManager
              01137AF2 |. 8BC8 mov ecx,eax ; |
              01137AF4 |. FF15 14012401 call dword ptr ds:[<&Engine.GAME::SaveManager::DirectRe>; \GAME::SaveManager::DirectRead
              01137AFA |. 84C0 test al,al
              01137AFC |. 74 69 je short Grim_Daw.01137B67
              01137AFE |. 8D8D A8FBFFFF lea ecx,[local.278]
              01137B04 |. E8 F7AA0E00 call Grim_Daw.01222600
              01137B09 |. C645 FC 01 mov byte ptr ss:[ebp-4],1
              01137B0D |. 8D8D A8FBFFFF lea ecx,[local.278]
              01137B13 |. FF75 EC push [local.5]
              01137B16 |. FF75 E8 push [local.6]
              01137B19 |. E8 A2AC0E00 call Grim_Daw.012227C0
              01137B1E |. 84C0 test al,al
              01137B20 |. 74 15 je short Grim_Daw.01137B37
              01137B22 |. 8B0D 040F2401 mov ecx,dword ptr ds:[<&Game.GAME::gGameEngine>] ; Game.GAME::gGameEngine
              01137B28 |. 8D85 A8FBFFFF lea eax,[local.278]
              01137B2E |. 50 push eax
              01137B2F |. 8B09 mov ecx,dword ptr ds:[ecx]
              01137B31 |. FF15 54272401 call dword ptr ds:[<&Game.GAME::GameEngine::ReadPlayerT>; Game.GAME::GameEngine::ReadPlayerTransfer
              01137B37 |> C645 FC 00 mov byte ptr ss:[ebp-4],0
              01137B3B |. FF75 A8 push [local.22]
              ..
              ..
              01137BB8 |. 8B43 04 mov eax,dword ptr ds:[ebx+4]
              01137BBB |. 2B03 sub eax,dword ptr ds:[ebx]
              01137BBD |. C1F8 02 sar eax,2
              注意下面是关键的跳转,决定了有几个箱子可以使用,如果只修改了game.dll会导致游戏无法显示除第一页以外的内容
              01137BC0 |. 83F8 02 cmp eax,2 ; Switch (cases 2..4)
              01137BC3 |. 75 10 jnz short Grim_Daw.01137BD5
              01137BC5 |. C687 57030000 00 mov byte ptr ds:[edi+357],0 ; Case 2 of switch 01137BC0
              01137BCC |. C687 83070000 01 mov byte ptr ds:[edi+783],1
              01137BD3 |. EB 60 jmp short Grim_Daw.01137C35
              01137BD5 |> 83F8 03 cmp eax,3
              01137BD8 |. 75 1E jnz short Grim_Daw.01137BF8
              01137BDA |. C687 51040000 00 mov byte ptr ds:[edi+451],0 ; Case 3 of switch 01137BC0
              01137BE1 |. C687 54040000 00 mov byte ptr ds:[edi+454],0
              01137BE8 |. C687 BB040000 00 mov byte ptr ds:[edi+4BB],0
              01137BEF |. C687 E7080000 01 mov byte ptr ds:[edi+8E7],1
              01137BF6 |. EB 2F jmp short Grim_Daw.01137C27
              01137BF8 |> 83F8 04 cmp eax,4
              注意此处需要修改
              01137BFB /75 46 jnz short Grim_Daw.01137C43
              此处为关键跳转,修改后多于4页的箱子会显示4个按钮
              01137BFB 90 nop
              01137BFC 90 nop
              此函数可以通过反向查找GAME::GameEngine::ReadPlayerTransfer函数找到


              IP属地:北京8楼2016-05-02 15:30
              回复
                第三个关键位置就是按下按钮的回调函数,这段对应了7种情况,分别是4页箱子按钮和3个购买按钮
                01136E70 /. 55 push ebp
                01136E71 |. 8BEC mov ebp,esp
                01136E73 |. 83E4 F8 and esp,FFFFFFF8
                01136E76 |. 51 push ecx
                01136E77 |. 837D 08 00 cmp [arg.1],0
                01136E7B |. 56 push esi
                01136E7C |. 8BF1 mov esi,ecx
                01136E7E |. 0F85 46010000 jnz Grim_Daw.01136FCA
                01136E84 |. 8B4D 0C mov ecx,[arg.2]
                01136E87 |. 8D46 30 lea eax,dword ptr ds:[esi+30]
                01136E8A |. 3BC8 cmp ecx,eax
                01136E8C |. 75 33 jnz short Grim_Daw.01136EC1
                01136E8E |. 8B0D 040F2401 mov ecx,dword ptr ds:[<&Game.GAME::gGameEngine>] ; Game.GAME::gGameEngine
                01136E94 |. 6A 00 push 0 ; /Arg1 = 00000000
                01136E96 |. 8B09 mov ecx,dword ptr ds:[ecx] ; |
                01136E98 |. FF15 48272401 call dword ptr ds:[<&Game.GAME::GameEngine::SetSelected>; \GAME::GameEngine::SetSelectedTransferSackNumber
                01136E9E |. C786 F40A0000 00000000 mov dword ptr ds:[esi+AF4],0
                01136EA8 |. 8B86 EC0A0000 mov eax,dword ptr ds:[esi+AEC]
                01136EAE |. 2B86 E80A0000 sub eax,dword ptr ds:[esi+AE8]
                01136EB4 |. C1F8 02 sar eax,2
                位置如上,可通过GAME::GameEngine::SetSelectedTransferSackNumber反向查找得到
                01136ECB |. 8B0D 040F2401 mov ecx,dword ptr ds:[<&Game.GAME::gGameEngine>] ; Game.GAME::gGameEngine
                以下代码是用来切换箱子页数的,需要修改
                01136ED1 6A 01 push 1
                01136ED3 8B09 mov ecx,dword ptr ds:[ecx]
                01136ED5 FF15 48272401 call dword ptr ds:[<&Game.GAME::GameEngine::SetSelected>; Game.GAME::GameEngine::SetSelectedTransferSackNumber
                修改为
                01136ED1 E9 29821000 jmp Grim_Daw.0123F0FF
                01136ED6 90 nop
                01136ED7 90 nop
                01136ED8 90 nop
                01136ED9 90 nop
                01136EDA 90 nop
                01136EDB |. C786 F40A0000 01000000 mov dword ptr ds:[esi+AF4],1
                01136EE5 |. 8B86 EC0A0000 mov eax,dword ptr ds:[esi+AEC]
                01136EEB |. 2B86 E80A0000 sub eax,dword ptr ds:[esi+AE8]
                01136EF1 |. C1F8 02 sar eax,2
                01136EF4 |. 83F8 01 cmp eax,1
                01136EF7 |. EB 36 jmp short Grim_Daw.01136F2F
                01136EF9 |> 8D86 F8020000 lea eax,dword ptr ds:[esi+2F8]
                01136EFF |. 3BC8 cmp ecx,eax
                01136F01 |. 75 4F jnz short Grim_Daw.01136F52
                01136F03 |. 8B0D 040F2401 mov ecx,dword ptr ds:[<&Game.GAME::gGameEngine>] ; Game.GAME::gGameEngine
                同样这是第三页的
                01136F09 6A 02 push 2
                01136F0B 8B09 mov ecx,dword ptr ds:[ecx]
                01136F0D FF15 48272401 call dword ptr ds:[<&Game.GAME::GameEngine::SetSelected>; Game.GAME::GameEngine::SetSelectedTransferSackNumber
                修改为
                01136F09 E9 22821000 jmp Grim_Daw.0123F130
                01136F0E 90 nop
                01136F0F 90 nop
                01136F10 90 nop
                01136F11 90 nop
                01136F12 90 nop
                01136F13 |. C786 F40A0000 02000000 mov dword ptr ds:[esi+AF4],2
                01136F1D |. 8B86 EC0A0000 mov eax,dword ptr ds:[esi+AEC]
                01136F23 |. 2B86 E80A0000 sub eax,dword ptr ds:[esi+AE8]
                可以看到修改的代码是跳转到其他地方的,因为地方不够,我们需要补充一些代码:
                0123F0FF 83BE F40A0000 00 cmp dword ptr ds:[esi+AF4],0
                0123F106 7F 05 jg short Grim_Daw.0123F10D
                0123F108 ^ E9 877DEFFF jmp Grim_Daw.01136E94
                0123F10D 52 push edx
                0123F10E 8B96 F40A0000 mov edx,dword ptr ds:[esi+AF4]
                0123F114 4A dec edx
                0123F115 52 push edx
                0123F116 8B09 mov ecx,dword ptr ds:[ecx]
                0123F118 FF15 48272401 call dword ptr ds:[<&Game.GAME::GameEngine::SetSelected>; Game.GAME::GameEngine::SetSelectedTransferSackNumber
                0123F11E 8996 F40A0000 mov dword ptr ds:[esi+AF4],edx
                0123F124 5A pop edx
                0123F125 ^ E9 BB7DEFFF jmp Grim_Daw.01136EE5
                上面的代码用来把当前箱子页号减1
                0123F12A 00 db 00
                0123F12B 00 db 00
                0123F12C 00 db 00
                0123F12D 00 db 00
                0123F12E 00 db 00
                0123F12F 00 db 00
                0123F130 52 push edx
                0123F131 8B96 F40A0000 mov edx,dword ptr ds:[esi+AF4]
                0123F137 42 inc edx
                0123F138 52 push edx
                0123F139 8B09 mov ecx,dword ptr ds:[ecx]
                0123F13B FF15 48272401 call dword ptr ds:[<&Game.GAME::GameEngine::SetSelected>; Game.GAME::GameEngine::SetSelectedTransferSackNumber
                0123F141 52 push edx
                0123F142 8D8E C40A0000 lea ecx,dword ptr ds:[esi+AC4]
                0123F148 E8 13C1FBFF call Grim_Daw.011FB260
                0123F14D 5A pop edx
                0123F14E ^ E9 CA7DEFFF jmp Grim_Daw.01136F1D
                上面的代码用来把当前箱子页号加1


                IP属地:北京10楼2016-05-02 15:37
                回复
                  不……不明觉厉……


                  IP属地:江苏来自Android客户端12楼2016-05-02 16:20
                  回复
                    这个必须支持


                    IP属地:广东来自Android客户端13楼2016-05-02 16:24
                    回复
                      楼主牛逼


                      IP属地:浙江来自iPhone客户端14楼2016-05-02 17:30
                      回复
                        不明觉厉


                        IP属地:湖北15楼2016-05-02 17:33
                        回复
                          支持楼主!
                          虽然我自己不用,但是我估计很多玩家都非常期待大箱子MOD。哈哈哈


                          16楼2016-05-02 17:34
                          回复
                            楼主在为万千GD玩家做出伟大贡献!妈的必须支持!爱死你了!


                            IP属地:上海来自iPhone客户端17楼2016-05-02 17:34
                            回复
                              66666我从头到脚各部位建了一个号,这个有实现的可能性就没那么麻烦了。


                              IP属地:湖北来自iPhone客户端18楼2016-05-02 17:39
                              回复