合金彈頭 逆向分析與外掛制作報告【內聯HOOK】
一、工具及遊戲介紹
使用工具:Ollydbg,PEID,Cheat Engine
實現功能:玩家無敵
目標:找到全局數據,或關鍵代碼塊。
遊戲版本:合金彈頭1-5代珍藏版
二、逆向邏輯
1、初始判斷【CE數據】
通過遊戲試玩,發現玩家是一次性死亡,但在復活開始階段,有閃光的無敵狀態。
可利用這點,實現無敵。
剛開始先通過CE找到類似秒數的 復活狀態信息數據,並找到修改數據的代碼段。
2、OD調試【OD追蹤關鍵代碼塊】
在秒數數據下硬件寫入斷點,得到修改數據的代碼。
回溯跟蹤分析,分析DL的來源,追蹤關鍵代碼塊。
在函數入口處下條件斷點。
往上分析,發現削減數據,DL來源於【EBX*4+0x5FE0A8】,
經多次驗證,EBX == 0x0,所以數據來源0x5FE0A8
此地址數據一直在變化,下硬件寫入斷點,得到相關計算的功能代碼。
跟蹤分析,發現此函數返回未削減的數值,並準備調用削減功能代碼。
進入分析。
發現函數從固定地址0x711470 + EAX偏移(模塊內),取出中間堆數據地址(堆內)。
再通過 中間堆數據地址 + ECX偏移,得到放在 堆中的無敵狀態數值。
通過得到無敵狀態數值,調用削減功能代碼,進行削減後,
再發往0x5FE0A8處,再賦回堆0x39C60CB處。
3、分析和實現
所以,此處可對 EAX偏移,ECX偏移,進行判斷。
準確鎖定狀態數據,並進行Hook代碼。
實現內聯HOOK,完成無敵。
三、總結:
1、總體邏輯
﹒﹒﹒﹒﹒﹒﹒﹒﹒Hook中間代碼實現 ↓ 實現數據恒定
﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒(取出修改)
﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒↓↓↓--------------↑↑↑
固定數據------------>>>中間數據--------->>>中間堆數據
(復活初始賦值) ﹒(多種數據臨時存放點) ﹒(無敵狀態數據)
﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒(0x5FE0A8) ﹒﹒﹒﹒﹒(0x39C60CB)
﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒↓↓↓----------------↑↑↑
﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒﹒(修改存放)
2、Hook Opcode
83 F1 01 3D 70 1C 71 00 75 0B 81 F9 84 04 10 00 75 03 B0 99 C3 8A 04 11 C3
3、功能代碼
//找到進程 HANDLE ReProcess = 0; PROCESSENTRY32 pe32; pe32.dwSize = sizeof(pe32); HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); BOOL bMore = ::Process32First(hProcessSnap, &pe32); //多字節轉寬字節 WCHAR proname[20] = {}; MultiByteToWideChar(CP_ACP, MB_COMPOSITE, "WinKawaks.exe", 20, proname, 20); while (bMore) { if (wcscmp(pe32.szExeFile, proname) == 0) { ReProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID); printf("找到了\n"); break; } bMore = Process32Next(hProcessSnap, &pe32); } HANDLE process; process = OpenProcess(PROCESS_ALL_ACCESS, FALSE, 0xeb4); //Hook 地點 DWORD attibute; VirtualProtectEx(ReProcess, (LPVOID)0x00444779, 0x6, PAGE_READWRITE, &attibute); //jmp HookOpcode BYTE OPecode1[] = { ‘\xE9‘, ‘\xB8‘, ‘\xC2‘, ‘\x07‘, ‘\x00‘, ‘\x90‘ }; DWORD num; WriteProcessMemory(ReProcess, (LPVOID)0x00444779, OPecode1, 6, &num); VirtualProtectEx(ReProcess, (LPVOID)0x00444779, 0x6, attibute, &attibute); //Hook Opcode VirtualProtectEx(ReProcess, (LPVOID)0x004c0a36, 0x25, PAGE_READWRITE, &attibute); //HookOpcode BYTE OPecode2[] = { ‘\x83‘, ‘\xF1‘, ‘\x01‘, ‘\x3D‘, ‘\x70‘, ‘\x1C‘, ‘\x71‘, ‘\x00‘, ‘\x75‘, ‘\x0B‘, ‘\x81‘, ‘\xF9‘, ‘\x84‘, ‘\x04‘, ‘\x10‘, ‘\x00‘, ‘\x75‘, ‘\x03‘, ‘\xB0‘, ‘\x99‘, ‘\xC3‘, ‘\x8A‘, ‘\x04‘, ‘\x11‘, ‘\xC3‘ }; WriteProcessMemory(ReProcess, (LPVOID)0x004c0a36, OPecode2, 25, &num); VirtualProtectEx(ReProcess, (LPVOID)0x004c0a36, 0x25, attibute, &attibute); CloseHandle(ReProcess);
四、效果
完成無敵:
個人總結:
雖然只是個小外掛,但找出了類似儲存遊戲數據的地方。雖然不太確定,但往這條路分析下去,以此達到其它功能,潛力還是蠻大的。
附件:
合金彈頭外掛.exe
KID
合金彈頭 逆向分析與外掛制作報告【內聯HOOK】