遊戲資料的捕捉(鬱金香學習筆記)

whatday發表於2013-07-20

目錄:

1.得到角色物件屬性

2.得到吃藥的CALL

3.得到快捷鍵CALL

4.得到選中怪物的ID地址

5.得到怪物列表

6.得到怪物屬性

7.得到顯示血條CALL

8.得到普通攻擊CALL

9.得到撿物品CALL

10.得到揹包列表地址

11.得到喊話CALL

12.座標相關資訊

13.得到綜合記憶體資訊

14.得到買賣物品CALL

15.關於OD除錯多執行緒的問題

16.遊戲多開實現

17.輔助程式設計注意事項

最近學習鬱金香視訊 寫下學習筆記以便以後查詢.

 
1.得到角色物件屬性
角色屬性是一個物件,通過生命值的變化 得到生命值地址 檢視附近的記憶體得到其他屬性
 角色物件基地址 02EE5B98
02EE5BE8    角色名字
02EE5C68    生命地址    dword
+4        內功        dword
+8        憤怒值        dword 千分比
+C        生命上限    dword    
+10        內功上限    dword
+14        3E8        
+18        經驗值        2dword
+20        下一級經驗值    2dword
+28        0A
+2C        歷練        dword
+30        心        dword
+34        氣        dword
+38        體        dword
+3C        魂        dword
+40        0
+44        0
+48        攻擊        dword
+4C        防禦        dword
+50        命中        dword
+54        迴避        dword
+58        武功命中    dword?
+5C        武功防禦    dword?
+60        0
+64        金錢
+68        0    

2.得到吃藥的CALL
通過數量定位 小量金創藥數量地址 2F8DAE24
CE監測訪問數量的程式碼得到
//吃藥call地址
push 0        //物品欄ID
push 1        //數量
push 0
call    00757700
提取特徵碼 A1648110038B8498040400008BB0B80200000BB0BC0200007433

3.得到快捷鍵CALL
用快捷鍵吃藥 吃藥call是在快捷鍵call中的 跟蹤往上一層來到快捷鍵call
F1-F10快捷鍵
0065BF07    50              push    eax                    //0-9
0065BF0E    E8 BD65FFFF     call    00652520
提取特徵碼為 741F83BCB104040000000F84F40900008B84B10404000083784800 便於更新程式的時候好定位
        
4.得到選中怪物的ID地址
選中不同的怪物有不同的ID來定位
可以通過CE來監控 變化的值 未變化的值
得到選中怪物ID所在地址 [312DF1C]+1478

5.得到怪物列表
通過監測 改寫選中怪物ID的程式碼 可以看到一個值填充了 選中ID
004AF442    8981 78140000   mov     dword ptr [ecx+0x1478], eax      ; 指定選中怪的ID
跟蹤上下文可以發現
004AF470 - 8B 0C 85 20DF1203     - mov ecx,[eax*4+0312DF20]
eax是怪物ID 也是陣列ID 這個陣列一般就是怪物列表地址了

6.得到怪物屬性
通過怪物列表得到怪物物件 選中不同怪物 以及打死怪物 怪物距離的不同 得到怪物屬性
怪物列表地址
0312DF20
{
    + ID*4 怪物物件地址
    {
        +0    怪物各種功能的函式指標列表
        +8    型別 怪2E
        +C    ID/陣列下標
        +31C    角色離怪物的距離
        +320    怪物的名字
        +37C    怪物復活過程
        +380    怪物生死狀態 0為生 1為死
        +1018    怪物座標X
        +1020    怪物座標Y
    }
}

其中的怪物生死狀態 可以通過CE來鎖定選中的怪ID 打死後它會自動刷出 這樣便於觀察怪物物件記憶體中的各種屬性
有些屬性是浮點型 比如座標 距離 所以用OD觀察資料時要用相應的資料型別來觀察

7.得到顯示血條CALL
手動改寫選中怪物ID時 發現沒有滑鼠選中時的血條 跟蹤選中怪的ID程式碼
發現在之前有一個call 經測試是顯示血條的call

選中怪顯示血條call 使用條件最好是沒有選中怪 要不然出現多個怪顯示血條
  mov     esi, 0x2B1EBE18
  mov     eax, dword ptr [esi]
  mov     edx, dword ptr [eax+0x4]
  push    0                  //這個push以後經過了一個跳轉猜到下一個push的 很容易漏掉    
  push    0x1
  push    0x44F
  mov     ecx, esi
  call    edx
  mov     eax, dword ptr [esi+0xC]
  mov     ecx, dword ptr [0x312DF1C]
  mov     dword ptr [ecx+0x1478], eax
提取特徵碼 83C410EB108B068B50046A01684F0400008BCEFFD2

8.得到普通攻擊CALL
監測 訪問選中怪物ID的程式碼 在按下攻擊以後出現的程式碼 這個程式碼一般是在普通攻擊call中的
逐一測試發現 普通攻擊call
0064DA3F    8B0D 1CDF1203   mov     ecx, dword ptr [0x312DF1C]
0064DA45    E8 D689E5FF     call    004A6470
提取特徵碼 8B88D802000080B9E9290000000F8408020000578BBE7814000039BE9014000075218B8694140000
其中通過普通攻擊發現 選中怪物的物件的地址 [312DF1C]


9.得到撿物品CALL
通過丟物品 撿物品發現滑鼠選中的物件ID都放在 [312DF1C]+1478 地址裡的,怪物 NPC 物品都是通用的
撿丟物品 監測 訪問此地址 可以得到一條撿物品call內部的程式碼 從而得到撿物品call 這種方法比較難跟蹤

另一個方法是 因為普攻 和撿物屬於同一類 動作 大部分程式設計師會把它們放到一個case裡邊
如:
  switch(動作號)
  {
    case 普攻ID:{呼叫普攻call}
    case 撿物ID:{相應的call}
    case 打坐ID:{相應的call}
    case 走跑ID:{相應的call}
    case 逃脫ID:{相應的call}
    case 組隊ID:{相應的call}
    case 交易ID:{相應的call}
    ...
    ...
    default:
  }
恰好前邊得到了普攻call的呼叫地方 用IDA檢視檢視很輕鬆可以得到其他幾個call
分別是
跑走: 0064DA51                 call    sub_64CE10
運氣: 0064DA71                 call    sub_64CEA0
普攻: 0064DA95            call    sub_4A6470
撿物: 0064DAB9                 call    sub_4A66C0
其他以此類推...

在跟蹤call的引數得到 程式碼
0076CBB4    8B0D FC2FEA00   mov     ecx, dword ptr [0xEA2FFC]
0076CBBA    8B89 74020000   mov     ecx, dword ptr [ecx+0x274]

最終call完整呼叫引數如下:
A.
mov ecx, dword ptr [0xEA2FFC]
mov ecx, dword ptr [ecx+0x274]
call 64CDC0

B.運氣call
mov ecx, dword ptr [0xEA2FFC]
mov ecx, dword ptr [ecx+0x274]
call    64CEA0            
以此類推...

10.得到揹包列表地址
揹包資料結構一般為:
物品揹包陣列(基址1)
 +4 物品物件1
 +8 物品物件2
   +??
   +?? 物品數量
   +?? 物品名稱
   +?? 功能說明
每個物品格 對應一個物件 這些物件是連續的陣列

從人蔘數量下手 得到數量地址 監控訪問地址的程式碼 人蔘所在物品欄的臨時基址
0DD97468,搜尋此地址得到幾個程式碼 分別監控訪問,滑鼠移動人蔘換不同的物品格,可以得到程式碼:
0076B9D1 - 3B 3D 64811003        - cmp edi,[03108164]
0076B9D7 - 75 2A                 - jne 0076BA03
0076B9D9 - 8B 84 B7 04040000     - mov eax,[edi+esi*4+00000404]
很明顯[edi+esi*4+00000404]這個是關鍵 edi的值可能揹包基地址但是發現其值是19eBA4C0 也是一個臨時地址往上看程式碼
發現cmp edi,[03108164] 可以推測[03108164]就是存放每次遊戲揹包基地址的地方了

綜合上邊發現 OD觀察記憶體得到:
物品欄基地址 [03108164]
     +404 裝備物品第一格基地址 0DD97468(臨時)
        +5C  物品名字
    +AC  使用級別
    +F1  說明
        +23C 數量
    +26c 防禦
    +290 揹包陣列下標
    +30C 耐久度
     +408 第二格
     ...
     ...
     +?? 如果這格沒有物品 則為0

11.得到喊話CALL
喊話功能call尋找過程:
通過在喊話對話方塊中輸入不同的字串 得到2個地址 分別在CE中改寫這2個地址
發現地址A改寫後馬上更新到喊話對話方塊中了 但是傳送對話顯示的是地址B的內容
追蹤到B CE監控訪問該地址程式碼 得到一個MEMSET函式內的程式碼 CE檢視訪問時 ECX的值
OD下條件斷點 斷下後放回上一層 用IDA檢視地址 結合檢視檢視 反覆跟蹤得到喊話call
esi=[312E7E0]=0E278010
00447A9E    8B06            mov     eax, dword ptr [esi]
00447AA0    8B50 04         mov     edx, dword ptr [eax+0x4]
00447AA3    57              push    edi        //0xD
00447AA4    53              push    ebx        //0xD
00447AA5    68 ED030000     push    0x3ED
00447AAA    8BCE            mov     ecx, esi
00447AAC    FFD2            call    edx
具體訪問程式碼:

mov     esi, dword ptr [312E7E0]
mov    edi,0xd
mov    ebx,0xd
mov     eax, dword ptr [esi]      
mov     edx, dword ptr [eax+0x4]  
push    edi              
push    ebx                
push    0x3ED                     
mov     ecx, esi                  
call    edx                       
函式特徵碼 8B068B5004575368ED0300008BCEFFD2


內容基地址尋找過程:
監控地址B訪問程式碼
mov     cl, [eax]
以此往上跟蹤可以得到
mov     ebx, dword_E73D1C
lea     edi, [ebx+13Ch]
mov     eax, edi
由此可得到 喊話基地址為 [0E73D1C]+13c
        
        
12.座標相關資訊
需要注意的是3D遊戲中 座標是由X Y Z 其中z是高 如果瞬間轉移的時候不注意Z很有可能就會移動到
山體裡邊或湖水裡邊 或 地下 或天上 這個時候系統是會監測到的 所以會還原到一個正確的位置
Z座標的計算 可以一般是以上往下計算的 所以Z都是負數 負得越多海拔越低 負得少海拔高,
想象一下就是把整個3D實地模型放到一個箱子裡了 箱子的上頂角就是座標的0點

 通過CE觀察滑鼠座標得到
座標物件基地址 0312DF1C 其中還存放了滑鼠選怪ID
+0x1614 當前角色X座標
+0x1618 當前角色Z座標
+0x161C 當前角色Y座標  或者0012762C
+0x15D8 滑鼠點選座標X  或者00E9AB50
+0x15DC    滑鼠點選座標Z
+0x15E0 滑鼠點選座標Y  或者00E9AB58
這組滑鼠地址 主要是用來計算髮送資料
另外一組組要是畫面跑動使用
[[312DF1C]+2C94]+280 當前X    //修改後直接跳到相應的座標 只是本地 伺服器資料未變
[[312DF1C]+2C94]+284 當前Z
[[312DF1C]+2C94]+288 當前Y
[312DF1C]+147C 目標X
[312DF1C]+1480 目標Z
[312DF1C]+1484 目標Y
後邊還發現一組用於跑動需要
直接通過滑鼠改變來跟蹤跑步函式比較困難 所以通過動靜的狀態來判斷
CE搜尋後得到比較多 通過改寫目標地址 然後狀態來判斷角色移動沒 來最終發現
以下2個開關
[312DF1C]+1494 開關1 1
[312DF1C]+1498 開關2 1
但是發現不是每次畫面人物都能移動的 觀察得到人物擺poss時 開關2會變成1 動作完成後變為0
這個時候在修改 目標地址 及開關就可以移動 推測擺poss 不光是好看 應該有資料更新重置功能
跟蹤開關2改寫的程式碼 來到了擺poss的程式碼處 發現每次改寫時 還會改寫一個地方 且這個地方很臨近
經CE測試得到
[312DF1C]+149C 開關3 為0時更改座標開關12可以移動
現在可以自由移動 但是發現走的是直線 和平時移動不太一樣 這樣勢必會撞牆 應該有程式碼判斷是否有障礙 定位判斷障礙的函式
用CE修改目標地址 讓主角跑起來 監測X或Y寫入 當撞牆時 X或Y有一個值就不會變了 這時候檢視寫入程式碼
地址004B1693 如果遇到牆 執行不到這個地址 地址前邊應該有校正 IDA檢視瀏覽很快定位到有3個流程
但是都是 54CEC0 函式的返回值 從而推斷 54CEC0 函式是判斷障礙物的函式有,進入函式發現有4個返回值
分別是 0 1 2 3 OD斷點檢測 正常時返回的是1 快速驗證 修改函式程式碼正常返回0時就返回1 再用CE修改
目標地址進行跑動 這下就可以穿越一切了
上邊的一切都是畫面變動 伺服器資料並沒有發生變化 定位傳送座標資料的函式
由於滑鼠函式比較複雜 且遊戲本身有土靈符可以瞬移 這樣省去了 滑鼠函式呼叫 但是有傳送資料的函式
CE監測 滑鼠座標 使用土靈符 可以得到函式 495AD0 下斷函式 發現滑鼠點選時也有呼叫此函式 應該就是
資料傳送函式了 但是使用道具和滑鼠點選引數不一樣 綜合一下寫入 完整的角色移動call

mov esi, dword ptr [312DF1C]
//設定目標地址
mov dword ptr [esi+147C],44C70000
mov dword ptr [esi+1480],0xC3B621EF
mov dword ptr [esi+1484],4465C000
mov dword ptr [esi+1494],1
mov dword ptr [esi+1498],1
mov dword ptr [esi+149C],0
//傳送資料到伺服器
mov dword ptr [esi+15D8],44C70000
mov dword ptr [esi+15DC],0xC3B621EF
mov dword ptr [esi+15E0],4465C000
mov edx,dword ptr [esi+15D8]
mov ecx,dword ptr [esi+15DC]
push 2
sub esp, 0c
mov eax, esp
mov [eax], edx
mov edx,[esi+15E0]
mov [eax+4],ecx
mov ecx,esi
mov [eax+8],edx
call 495AD0

13.得到綜合記憶體資訊
通過丟物品後 走遠點選物品然後點選其他地方來取消撿物品 可以得到選擇物品ID和怪物是同一個
觀察物品記憶體塊情況 得到
0312DF20
{
    + ID*4 物品物件地址
    {
        +8    型別 33
        +C    ID/陣列下標
        +64    物品的距離
        +94    物品的名字
        +198    物品座標X
        +19C    物品座標Z
        +1A0    物品座標Y
    }
}

人物角色記憶體情況
0312DF20
{
    + ID*4 人物物件地址
    {
        +8    型別 2E
        +C    ID/陣列下標
        +18    人物名字
        +1D00    人物等級
        +147C    人物座標X
        +1480    人物座標Z
        +1484    人物座標Y
    }
}

14.得到買賣物品CALL
通過執行買賣動作 用OD監視得到買賣物品的資料包資訊
可以多次檢查不同資料來觀察
0012A48C  00 00 92 00 80 00 02 00 00 00 19 41 68 F3 68 CA  //92 80 02為常量
0012A49C  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 32 1B  //01數量 32為計數ID
0012A4AC  02 00 00 00 00 00 17 39 C2 90 23 A2 E8 0C 68 CA  //物品型別
0012A4BC  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 0C  //01數量 0C是揹包下標
0012A4CC  00 00 01 00 6C F3 00 00 00 00 00 00 00 00 00 00  
0012A4DC  00 00 00 00 00 00 00 00 00 00 00 00 00 F3 00 00  
0012A4EC  00 00 00 00 00 00 00 00 68 F3 00 00 00 00 00 00
0012A4FC  00 00 00 00 00 00 00 45 65 F3 00 00 00 00 27 44  
0012A50C  62 F3 26 42 62 F3 00 00 00 00 00 00 00 00 00 00

0012A48C  00 00 92 00 80 00 02 00 00 00 00 00 00 00 94 CA  ..?€........斒
0012A49C  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 36 1B  ?...........6
0012A4AC  02 00 00 00 00 00 F7 57 2F D0 AE A8 E8 0C 94 CA  .....鱓/挾ㄨ.斒
0012A4BC  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 00  ?............
0012A4CC  00 14 01 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............
0012A4DC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
0012A4EC  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................


6C6EB130 >00 00 92 00 80 00 02 00 00 00 00 00 00 00 94 CA  ..?€........斒
6C6EB140  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 36 1B  ?...........6
6C6EB150  02 00 00 00 00 00 F7 57 2F D0 AE A8 E8 0C 94 CA  .....鱓/挾ㄨ.斒
6C6EB160  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 00  ?............
6C6EB170  00 14 01 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............
6C6EB180  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
6C6EB190  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
6C6EB1A0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
6C6EB1B0  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................


3233FDC0  00 00 92 00 80 00 02 00 00 00 00 00 00 00 94 CA  ..?€........斒
3233FDD0  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 36 1B  ?...........6
3233FDE0  02 00 00 00 00 00 F7 57 2F D0 AE A8 E8 0C 94 CA  .....鱓/挾ㄨ.斒
3233FDF0  9A 3B 00 00 00 00 01 00 00 00 00 00 00 00 01 00  ?............
3233FE00  00 14 01 00 00 00 00 00 00 00 00 00 00 00 00 00  ..............


出售物品資料包結構
struct
{
    +0    const0            word    00        
    +2    const1            word    92        
    +4    const2            word    80        
    +6    const3            dword    2
    +A    ??            dword   可以為0
    +E    物品物件+4C        dword    物品ID
    +12    物品物件+50        dword
    +16    數量 23c        dword
    +1A    ??            dword   可以為0
    +1E    角色屬性[0x2EE5CCC]    dword
    +22    角色屬性[0x2EE5CD0]    dword
    +26    物品物件+54        dword
    +2A    物品物件+58        dword
    +2E    物品物件+4c        dword
    +32    物品物件+50        dword
    +36    數量 23c        dword    
    +3A    物品物件+240        dword
    +3E    物品物件+1F2        byte
    +3F    揹包下標 290        byte
    +40    物品物件+238        byte
    +41    物品物件+244        byte
    +42    物品物件+AC        byte
    +43    物品物件+A4        byte
        6C F3 00 00 00 00 00 00 00 00 00 00  
        00 00 00 00 00 00 00 00 00 00 00 00 00 F3 00 00  
        00 00 00 00 00 00 00 00 68 F3 00 00 00 00 00 00  
        00 00 00 00 00 00 00 45 65 F3 00 00 00 00 27 44  
        62 F3 26 42 62 F3 00 00 00 00 00 00 00 00 00 00
}
提取特徵碼 8D853CFFFFFF50B840E94700FFD0


以此類推得到 買物品CALL的資料包 開啟NPC買賣對話方塊CALL的資料包 從而完成自動買賣物品


15.關於OD除錯多執行緒的問題
OD除錯多執行緒會出現這樣的問題
"OllyICE無法再斷點(可能無效)地址 讀取暫存器及更新EIP
通常糾正後繼續試不可能的 然後 您可以在自己承擔風險的情況下
恢復及繼續"
解決方法參照 http://blog.csdn.net/whatday/article/details/9059281

16.遊戲多開實現
此遊戲多開會有提示框 OD載入去除 發現還是不行 網上搜尋發現是client資料夾衝突 想想也是第一個客戶端一個檔案嘛
複製client資料夾命名為其他名字 複製launcher.exe修改其中路徑 多開OK了

17.輔助程式設計注意事項
 1.由於牽涉到記憶體 所以每個記憶體讀之前 先嚐試是否有效 可以使用 IsBadReadPtr 函式
 2.各種物件屬性最好基於指標 因為資料都是動態變化的 只有在使用前來取得資料還是最正確的資料

 3.怪物物件ID不會變 但是物件基地址有可能變 所以應時候ID找物件基地址



相關文章