1. 程式人生 > >好久之前寫的天龍八部輔助思路分享

好久之前寫的天龍八部輔助思路分享



關於某網遊的二叉樹分析和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,其實是很簡單的

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
  }
  
}
第一次在csdn寫部落格 試試 大家隨便 看看 話說怎麼傳壓縮包