009 数据结构逆向—数组(困难版)
文章目錄
- 前言
- 數(shù)組逆向
- 通過人物血量查找人物屬性
- 調(diào)call取對(duì)象
- call內(nèi)追局部變量
- 逆向加密數(shù)組下標(biāo)
- 分析人物屬性
- 總結(jié)
前言
通過之前的分析,我們已經(jīng)對(duì)數(shù)組結(jié)構(gòu)有了一個(gè)簡(jiǎn)單的了解,這次就用幻想神域這個(gè)游戲來更加深入學(xué)習(xí)數(shù)組。
數(shù)組逆向
通過人物血量查找人物屬性
以人物血量為切入點(diǎn),我們要找到所有的人物屬性。
首先搜索當(dāng)前人物血量
接著通過換裝備的方式修改人物血量,最后剩下兩個(gè)結(jié)果,一個(gè)是當(dāng)前血量,一個(gè)是最大血量。通過修改數(shù)據(jù)可以分辨。
在OD中對(duì)這個(gè)地址下硬件訪問斷點(diǎn)。打開人物屬性欄,會(huì)對(duì)人物所有屬性進(jìn)行訪問,斷點(diǎn)斷下
這里在判斷當(dāng)前的人物血量是否為0,人物血量=eax+8。接著需要通過追蹤eax的方式找到所有的人物屬性。
eax來源于上一句call
進(jìn)到call內(nèi),eax來源[eax+C]
血量=[eax+C]+8上面有一句匯編將一個(gè)基地址賦值到eax,但這句代碼實(shí)際上是沒有執(zhí)行的,所以這個(gè)地址是無效的。
eax實(shí)際上是來源于上面的call。
這個(gè)call內(nèi)部的邏輯比較復(fù)雜,遇見這種情況可以用比較簡(jiǎn)單的方式,直接調(diào)用call來獲取數(shù)據(jù)。
調(diào)call取對(duì)象
我們只要將這個(gè)call的參數(shù)分析出來,就可以直接調(diào)用call來獲取返回值。這個(gè)call只有一個(gè)參數(shù)
參數(shù)eax是一個(gè)固定的值
往上追一下基址,就是一個(gè)基地址+0x40C
eax轉(zhuǎn)成十進(jìn)制之后像是一個(gè)ID
而調(diào)用這個(gè)call以后返回值[eax+C]+8的位置是人物的血量。這里可以大膽猜測(cè)一下,參數(shù)eax其實(shí)就是當(dāng)前的人物ID,傳入人物的ID以后會(huì)返回一個(gè)人物對(duì)象。對(duì)象加上偏移可以取到人物屬性。
call內(nèi)追局部變量
接著我們用正常的追蹤方式繼續(xù)追人物的血量基地址
血量=[eax+C]+8繼續(xù)進(jìn)到call追蹤eax的值
eax來源于[ebx+0xC],替換一下偏移表達(dá)式,繼續(xù)追ebx
血量=[[ebx+0xC]+C]+8ebx來源于[ebp-4],繼續(xù)追[ebp-4]
血量=[[[ebp-4]+0xC]+C]+8[ebp-4]作為一個(gè)局部變量只能存在于當(dāng)前的函數(shù)內(nèi),但是我們往上找發(fā)現(xiàn)并沒有[ebp-4],那就說明[ebp-4]是來源于這個(gè)函數(shù)內(nèi)的call
我們需要進(jìn)入這個(gè)被執(zhí)行的call找[ebp-4]的來源。
追這個(gè)局部變量有兩種方式,第一種是直接下斷,單步跟每一行代碼,看是哪行匯編改變了[ebp-4]。這種方式?jīng)]啥技術(shù)含量,這里我們用第二種。
局部變量想要傳入call內(nèi)被修改就必須通過指針的方式,這里我們可以查看一下這個(gè)call的參數(shù)
這個(gè)call有兩個(gè)參數(shù)[ebp+8]和[ebp-8],其中和[ebp-4]最接近的就是[ebp-8],那么就有下面的等式
edx=ebp-8用上面的等式往[ebp-4]靠近
[edx+4]=[ebp-4]edx實(shí)際上是第一個(gè)參數(shù)
[edx+4]=[arg1+4]=[[ebp+8]]+4]=[ebp-4]那么我們進(jìn)入內(nèi)層call以后要追的實(shí)際上就是[ebp+8]
進(jìn)入call內(nèi)找[ebp+8],這里將[ebp+8]賦值給了eax,然后將ecx賦值給了[eax+4],這個(gè)[eax+4]就是我們要找的[ebp-4]。所以
血量=[[ecx+0xC]+C]+8繼續(xù)往上追ecx
ecx來源于[ecx+4],ecx又來源于ebp-0x14
血量=[[[ecx+4]+0xC]+C]+8 血量=[[[ebp-0x14+4]+0xC]+C]+8 血量=[[[ebp-0x10]+0xC]+C]+8繼續(xù)追[ebp-0x10]
[ebp-0x10]來自ebx
血量=[[ebx+0xC]+C]+8ebx繼續(xù)往上追,就找到了今天的目標(biāo)數(shù)組了
血量=[[[eax+ebx*8+4]+0xC]+C]+8eax是數(shù)組首地址,繼續(xù)往上追eax。ebx是數(shù)組下標(biāo),值等于0x34。下標(biāo)暫時(shí)先不管,后面會(huì)有個(gè)彩蛋~
eax來源于[esi+0x14]
血量=[[[[esi+0x14]+ebx*8+4]+0xC]+C]+8esi來源于ecx,返回上一層找ecx
ecx來源于esi,表達(dá)式不變,繼續(xù)返回上層追esi。
[外鏈圖片轉(zhuǎn)存失敗,源站可能有防盜鏈機(jī)制,建議將圖片保存下來直接上傳(img-mkllCxu0-1587787548269)(009 數(shù)據(jù)結(jié)構(gòu)逆向—數(shù)組(困難版)].assets/1587483144194.png)
esi又來源于ecx
血量=[[[[ecx+0x14]+ebx*8+4]+0xC]+C]+8來到函數(shù)頭部,繼續(xù)返回上層追ecx
ecx來源于ecx+0x410
血量=[[[[ecx+0x410+0x14]+ebx*8+4]+0xC]+C]+8再往上,總算是追到ecx的基地址了
血量=[[[[[0xF84B74]+0x410+0x14]+ebx*8+4]+0xC]+C]+8逆向加密數(shù)組下標(biāo)
到這里我們就把人物的數(shù)組追到了,但是還有個(gè)問題就是數(shù)組的下標(biāo)0x3E是怎么來的,我們需要知道這個(gè)數(shù)組的排列規(guī)則,以及當(dāng)前的下標(biāo)為什么是0x3E。
所以這里就要考慮去追ebx的來源,看看這個(gè)0x3E是怎么得來的。
回到剛才數(shù)組的位置追ebx,ebx來源于[eax+eax]
數(shù)組下標(biāo)=eax*2eax繼續(xù)往上追
來到這個(gè)地方,這段代碼明顯是一個(gè)加密的算法。通過上面的左移右移的指令就能看出來,到這里其實(shí)就沒有必要繼續(xù)往上追了,如果需要寫代碼,直接將這段加密算法摳出來。
最后追出來的數(shù)組下標(biāo)的算法為:
數(shù)組下標(biāo)=(([0xF84B74]+0x40C*0x41]+[0xF84B74]+0x40C/4+0x9E3779B9) and [[0xF84B74]+0x410+0x20])*2到這里我們就清楚了人物數(shù)組下標(biāo)的來源是通過加密的方式計(jì)算的。
分析人物屬性
找完這個(gè)數(shù)據(jù)結(jié)構(gòu)以后,我們來進(jìn)行一個(gè)簡(jiǎn)單的分析。
血量=[[[[[0xF84B74]+0x410+0x14]+ebx*8+4]+0xC]+C]+8我們把+8的屬性偏移去掉,查看一下人物對(duì)象
dd [[[[[0xF84B74]+0x410+0x14]+ebx*8+4]+0xC]+C]記得將ebx替換為加密的下標(biāo),我這里是0x34。
其中+8的位置是人物血量,+0x10的位置是人物等級(jí),+0x18是移動(dòng)速度,+0x24是人物最大血量,+0x30是暴擊傷害。
其他的數(shù)據(jù)可以自己去分析,這里其實(shí)沒啥技術(shù)含量,就是通過不斷的對(duì)比和分析得出結(jié)論。
總結(jié)
到這里我們已經(jīng)對(duì)數(shù)組有了一個(gè)深刻的理解,數(shù)組在所有的數(shù)據(jù)結(jié)構(gòu)里屬于最簡(jiǎn)單的一種,對(duì)于這類數(shù)據(jù)結(jié)構(gòu)來說,只需要一直往上追就能找到想要的數(shù)據(jù)。如果遇到數(shù)據(jù)被加密的情況,可以逆推出加密算法,也可以直接將算法拷貝到自己的代碼里。
另外在追數(shù)據(jù)的過程中,偏移表達(dá)式每一次變化都要做一次檢驗(yàn),在數(shù)據(jù)窗口查看當(dāng)前的表達(dá)式是否正確,否則到后面很容易翻車。
最后,附上Github地址,里面有游戲下載鏈接和相關(guān)工具,需要請(qǐng)自取:
https://github.com/TonyChen56/GameReverseNote
總結(jié)
以上是生活随笔為你收集整理的009 数据结构逆向—数组(困难版)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 008 数据结构逆向—数组(简单版)
- 下一篇: 010 数据结构逆向—链表