008 数据结构逆向—数组(简单版)
文章目錄
- 前言
- 逆向背包數組
- 一維背包數組
- 二維背包數組
- 數組結構分析
- 總結
前言
對于游戲逆向來說,核心需求其實就只有兩個
對于追蹤游戲數據來說,單純從一個寄存器或者內存往上追蹤到這個數據的基址是較為簡單的,難點在于如何通過這一個數據,找到整個數據結構。
這里先拋出三個問題
想要解決上述的問題,就必須學會如何逆向分析程序中的數據結構,上述三個問題,對應了三種數據結構,分別是數組 鏈表和二叉樹。這三個數據結構也是游戲里最常用的。
我們先用口袋西游,來學習一個簡單版本的數組。
逆向背包數組
一維背包數組
這一次我們要逆向的目標是整個背包的物品,通過數據追蹤的方式找到所有的背包物品及屬性。切入點可以是背包中任意一個物品的屬性,比如數量。
首先搜索背包中血藥的數量
第二次搜索即可得到唯一一個結果,然后在OD中對這個地址下硬件寫入斷點,斷點斷下
斷下的位置上一句就是寫入的代碼,[ecx+0x14]是當前物品的數量。那么我們就要往上追ecx,由于這個位置已經是函數頭的位置了,我們需要返回上一層繼續找ecx
ecx來源于esi,而esi來源于[eax+ebx*4]。這是一個典型的數組下標訪問的代碼。C++代碼如下:
int arr[10]; DWORD iNum=a[i];eax相當于是arr數組的首地址,ebx相當于是數組的下標,通過對下標取不同的值可以訪問到不同的數組成員。
接著我們在這個位置下斷點,觀察eax和ebx的值
ebx的值正好和當前藥品所在的第幾個格子數,然后再吃另外一個藥。ebx的值和當前物品的背包格子數也是一樣的。
也就是說整個背包的物品是用一個數組來存放的,數組的下標代表的是物品所在的格子數。
問題在于,當前的背包有三個,分別是普通 任務和時裝,理論上來說應該有三個數組,那么另外兩個在哪呢?繼續往上追就能得到答案。
先來回顧一下當前物品的偏移表達式
血藥數量=[[eax+i*4]+0x14]然后我們繼續往上追eax
eax來源于[edi+C],edi來源于ecx,所以
血藥數量=[[[ecx+0xC]+i*4]+0x14]返回上一層,繼續追ecx
ecx,來源于esi
血藥數量=[[[esi+0xC]+i*4]+0x14]esi來源于[esp+0x1C]
[esp+0x1C]來源于eax,那么
血藥數量=[[[eax+0xC]+i*4]+0x14]繼續追eax,eax作為返回值來源于上一個call,進入call內部
這個call的內部代碼的分支比較多,這里可以先單步F7走一遍,然后用減號鍵回退的方式整理代碼執行流程
eax來源于[ecx+0xAD8]
血藥數量=[[[[ecx+0xAD8]+0xC]+i*4]+0x14]返回上層ecx來源ebp,ebp來源ecx,表達式不變,繼續返回上一層函數追ecx
ecx來源于上上層函數的eax,eax作為返回值,繼續進上面的call,追eax
血藥數量=[[[[[ecx+8]+0x28]+0xAD8]+0xC]+i*4]+0x14二維背包數組
返回上層繼續找ecx
這里我們又看到了一個數組的訪問代碼,在這個地方下個斷點,發現eax的值為0
血藥數量=[[[[[[ebp+0*4+1C]+8]+0x28]+0xAD8]+0xC]+i*4]+0x14這個地方大概是一個二維數組,eax是數組下標,0代表第一個普通背包,1代表第二個任務背包,2代表第三個時裝背包。
繼續往上追ebp
ebp來源[eax+0x8],eax來源于[ebx+4],ebx來源ecx
血藥數量=[[[[[[[[ecx+4]+0x8]+0*4+1C]+8]+0x28]+0xAD8]+0xC]+i*4]+0x14繼續找ecx
來源[edi+0x68]
血藥數量=[[[[[[[[[edi+0x68]+4]+0x8]+0*4+1C]+8]+0x28]+0xAD8]+0xC]+i*4]+0x14[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-cLGVTuAQ-1587393010884)(008 數據結構逆向—數組(簡單版)].assets/1587390974080.png)
edi來源ecx
血藥數量=[[[[[[[[[ecx+0x68]+4]+0x8]+0*4+1C]+8]+0x28]+0xAD8]+0xC]+i*4]+0x14繼續返回上層追ecx
ecx來源ebp
血藥數量=[[[[[[[[[ebp+0x68]+4]+0x8]+0*4+1C]+8]+0x28]+0xAD8]+0xC]+i*4]+0x14ebp來源ecx
血藥數量=[[[[[[[[[ecx+0x68]+4]+0x8]+0*4+1C]+8]+0x28]+0xAD8]+0xC]+i*4]+0x14ecx來源于[ebp+0x1C],而ebp是一個基地址,那么這個偏移表達式就已經追完了
血藥數量=[[[[[[[[[[0xD11A50+0x1C]+0x68]+4]+0x8]+0*4+1C]+8]+0x28]+0xAD8]+0xC]+i*4]+0x14數組結構分析
這里可以把整個偏移表達式分為三部分
背包物品數組首地址=[[[[[[[[[0xD11A50+0x1C]+0x68]+4]+0x8]+0*4+1C]+8]+0x28]+0xAD8]+0xC] 背包背包物品數組下標=i*4 背包物品屬性偏移=0x14接著我們在內存中查看一下數組首地址的內存
這里是一個DWORD類型的對象數組,每一個成員都是一個物品對象,找到第六個我們的血藥的對象地址,數據窗口跟隨
其中+14的位置是當前的血藥數量,借用這個數據可以猜測一下+018的位置是3E7,十進制的999,應該是物品的最大數量。其他的每一個成員都是物品的屬性
總結
到這里我們就完成了從物品數量到整個背包的數據結構分析的過程,識別數組結構的關鍵在于是否有匯編通過下標的方式訪問內存
mov esi,dword ptr [eax+ebx+4];這個數組結構僅僅是一個簡單版本的,下次我們再來分析一個困難版本的數組。
最后,附上Github地址,里面有游戲下載鏈接和相關工具,需要請自取:
https://github.com/TonyChen56/GameReverseNote
總結
以上是生活随笔為你收集整理的008 数据结构逆向—数组(简单版)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 005 定位控件输入call
- 下一篇: 009 数据结构逆向—数组(困难版)