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