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