010 数据结构逆向—链表
文章目錄
- 逆向周圍對象鏈表
- 總結
之前我們已經通過人物的血量找到了人物的屬性數組,接下來學習一下鏈表。
逆向周圍對象鏈表
這一次要找的目標是人物周圍的對象鏈表,包括人物周圍的NPC和怪物等等。找這個數據結構的突破口有很多,可以通過人物本身,也可以通過NPC和怪物。
這里還是以人物血量為突破口,之前我們已經用人物血量去找到了屬性的數組,但是同一個突破口通過不同的訪問代碼可以逆向分析出不同的數據。
和之前的方式一樣,用CE找到當前的人物血量,然后在這個位置下硬件訪問斷點
點擊當前的人物血量
斷點斷下,[eax+8]是人物的血量,追eax的數據來源,eax來自[esi+0xC],繼續往上追esi
血量=[esi+0xC]+8esi來自于ecx,返回上層找ecx
ecx又來源于ebx
血量=[ebx+0xC]+8ebx來源ecx
ecx來自[esi+C]
血量=[[esi+C]+0xC]+8在這里查看一下血量的值,每一次斷點斷下,存儲血量的地址和esi的值都會不斷發生變化。
這個地方的地址一直發生變化說明是已經來到了一個數據結構,如果這個地方單純的存放的是人物血量的話,就是基址+偏移的方式,不會發生改變。
繼續往上追esi
esi來自[eax]
血量=[[[eax]+C]+0xC]+8eax這個時候只有兩個值在發生變化,而且偏移表達式的地址,不管斷下多少次都沒有發生改變。
從這個地方的變化說明esi的值不來源于eax,也就是說當前的代碼不是順序執行的,有可能是進到了循環里面。
那么就有必要分析一下當前的這段代碼
這里有一個向上的跳轉是當前的循環尾部,jmp跳轉的目標地址是循環頭部,中間的代碼相當于是循環體了。
esi不來自循環體外的eax,也就說明是來自循環體內的[esi],esi再往上找還是沒有發現來源,說明當前的這一句代碼一直在循環取值。
如果和數據結構聯想到一起的話,很明顯這個地方是一個單向鏈表,C++代碼如下
class Node { public:Node<T> *next;T data;上面這段代碼就是通過對Node節點的循環遍歷,來找到想要的目標節點。跳出循環體外
esi來源于[eax],eax就是當前的鏈表頭,這里可以對當前的鏈表進行取值
第一個對象血量:[[[[eax]]+C]+0xC]+8 第二個對象血量:[[[[[eax]]]+C]+0xC]+8 第三個對象血量:[[[[[[eax]]]]+C]+0xC]+8我們已經找到了鏈表的數據結構,這個時候就沒有必要繼續往上追了,意義不大。剩余的對象屬性各位可以自己去分析
總結
對于鏈表的逆向來說,需要時刻關注追數據過程中每一步的數據結構變化,特別是變化比較明顯的那一種。識別鏈表的標識在于是否有匯編代碼在遍歷當前的鏈表不斷進行取值,例如:
mov eax,[eax];最后,附上Github地址,里面有游戲下載鏈接和相關工具,需要請自取:
https://github.com/TonyChen56/GameReverseNote
總結
以上是生活随笔為你收集整理的010 数据结构逆向—链表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 009 数据结构逆向—数组(困难版)
- 下一篇: 011 数据结构逆向—二叉树