好久之前寫的天龍八部輔助思路分享
關於某網遊的二叉樹分析和luaHook實現
最近在研究一個網遊,裡面用兒叉樹的結構,至於怎麼找到這顆二叉樹的,網上教程這麼多,我就不說了,重點講下這顆二叉樹。
其中1是左子樹執行的流程,2是右子樹執行的流程。
其實這個圖是個排序二叉樹,這裡兒叉樹跟edi(經分析,這個edi是某怪物ID)做比較,類似二分搜尋這樣的。
自己畫了個圖,方便自己理解。
void CGameDlg::TLBianLi(ULONG CurAddr){ //bl=[根+0x15] bl為0時進入遍歷 ULONG RightAddr,LeftAddr,tempAddr; float X,Y; BYTE root_15; char GuaiWustr[16]="null"; _asm { push eax mov eax,CurAddr add eax,0x15 mov eax,[eax] mov root_15,al pop eax } if(root_15==0){ //當前結點 //[[[[eax+0x10]+0x1EC]+0x4]+0x34]是怪物名 eax =CurAddr //[[[[[9CD654]+0x70]+0x1EC]+0x4]+000024A0]血 ReadProcessMemory(hp,(LPVOID)((DWORD)CurAddr+0x10),&tempAddr,4,NULL); //[eax+0x10]+48 ReadProcessMemory(hp,(LPVOID)((DWORD)tempAddr+0x48),&X,4,NULL); ReadProcessMemory(hp,(LPVOID)((DWORD)tempAddr+0x50),&Y,4,NULL); ReadProcessMemory(hp,(LPVOID)((DWORD)tempAddr+0x01EC),&tempAddr,4,NULL); ReadProcessMemory(hp,(LPVOID)((DWORD)tempAddr+0x04),&tempAddr,4,NULL); ReadProcessMemory(hp,(LPVOID)((DWORD)tempAddr+0x34),&GuaiWustr,10,NULL); GuaiWustr_CStr=(char*)GuaiWustr; //[CurAddr+0xc]是GuaiWuID ReadProcessMemory(hp,(PVOID)((DWORD)CurAddr+0xc),&GuaiWuID,4,NULL); str.Format(L"%8x %8s %8.2f %8.2f",GuaiWuID,GuaiWustr_CStr,X,Y); m_listGuaiWu.AddString(str); //左樹mov 根,[根] _asm { push eax mov eax,CurAddr mov eax,[eax] mov LeftAddr,eax pop eax } TLBianLi(LeftAddr); //右樹mov 根,[根+0x8] _asm { push eax mov eax,CurAddr add eax,0x8 mov eax,[eax] mov RightAddr,eax pop eax } TLBianLi(RightAddr); } }
現在再來說遊戲如果用了lua我們怎麼呼叫怎麼找到關鍵的lua
還是那樣,要先找到遊戲中的某lua呼叫的地方,網上教程這麼多我就不說怎麼找了,說說怎麼實現相關的luaHook吧。
=============lua_call=============
007251E1 |. 8B0D 884F3401 mov ecx,dword ptr ds:[0x1344F88] ; lua
007251E7 |. 8B11 mov edx,dword ptr ds:[ecx]
007251E9 |. FF52 3C call dword ptr ds:[edx+0x3C]
007251EC |. 8B00 mov eax,dword ptr ds:[eax]
007251EE |. 53 push ebx
007251EF |. 50 push eax
007251F0 |. FF15 5CE38400 call dword ptr ds:[0x84E35C] ; luaplus.lua_dostring
007251F6 |. 8B45 E4 mov eax,[local.7]
007251F9 |. 83C4 08 add esp,0x8
=====================================
hook的方法就是inline hook那樣了,其實也沒什麼好說的,會了inline hook,其實是很簡單的
第一次在csdn寫部落格 試試 大家隨便 看看 話說怎麼傳壓縮包void __declspec(naked) Mylua(){ //執行自己的程式碼 _asm { pushad mov lua_str,ebx//儲存lua的字串 其中ebx儲存了lua的字串 } //lua_Mycode(); _asm popad //跳回原來的地方 _asm { mov ecx,dword ptr ds:[0x1344F88] jmp HookLuaBackAddr //這個地址是HookLuaAddr+6 0x007251E7 } } //儲存原來的資料 BYTE oldGameCode[6]={0x8B,0x0D,0x88,0x4F,0x34,0x01}; void lua_hook(){ //儲存原來的資料 //修改程式碼 E9 (DWORD)&Mylua-HookLuaAddr -5 5個位元組 jmp Mylua ULONG jmpAddr =(ULONG)Mylua-HookLuaAddr -0x5; _asm { push eax push ebx mov eax,HookLuaAddr mov byte ptr ds:[eax],0xE9 mov ebx,jmpAddr mov dword ptr ds:[eax+1],ebx pop ebx pop eax } //AfxMessageBox(L"hook"); } void lua_unHook(){ //恢復所在位置的程式碼 _asm { push eax push ebx push ecx mov eax,HookLuaAddr lea ebx,oldGameCode mov ecx,[ebx] mov word ptr ds:[eax],cx mov ecx,[ebx+2] mov dword ptr ds:[eax+2],ecx //mov HookLuaAddr[0...5],oldGameCode[0...5] pop ecx pop ebx pop eax } }