一.《澤諾尼亞》背包物品數(shù)據(jù)分析和遍歷
?尋找突破口
1.首先尋找突破口,圍繞一個“變”字去找
2.之前在別的課程中也給同學(xué)們說過,我們在找背包物品遍歷,無非就是要先拿到物品對象
3.然而要拿到物品對象,必須先拿到物品屬性,然后逆向分析拿到物品對象
4.那么問題來了, 怎么拿到物品屬性呢?
5.這時候就要找到我們能夠通過CE容易搜索出來的數(shù)據(jù),比如:物品的數(shù)量
6.因為數(shù)量我們很好去控制他的數(shù)量
CE尋找數(shù)據(jù)
1.我們就搜索背包里面的藥品數(shù)量

2.觀察藥品數(shù)量當(dāng)前為520,經(jīng)過我們改變和精確搜索,還剩下3個結(jié)果

3.怎么確定這3個地址那個是真正的物品數(shù)量的數(shù)據(jù)呢?
4.猶豫數(shù)量少,我們可以一個一個挨著修改,然后觀察游戲物品數(shù)量的變化,從而得知那個是真正的數(shù)據(jù)
?

?5.修改后發(fā)現(xiàn)是第三個地址

6.好,接下來拿到地址,我們用XDBG附加游戲,觀察數(shù)據(jù)

尋找對象
1.接下來我們就需要找這個數(shù)據(jù)存在那個對象下,下一個硬件寫入斷點

2.我們?nèi)ゴ蚬譁p少血量,從而斷到寫入數(shù)量的匯編代碼處

3.斷下來后,觀察到rax+18就是我們的數(shù)量地址,那么rax應(yīng)該就是結(jié)構(gòu)體首地址或者對象首地址

4.此時rax等于這個值0000021FAC59D750

5.我們觀察這個地址,發(fā)現(xiàn)0000021FAC59D750+18的地址中的值0x1FC確實是我們的物品數(shù)量

尋找對象來源
1.接下來我們繼續(xù)找rax等于0000021FAC59D750的來源,往上分析
2.結(jié)果發(fā)現(xiàn)就在本層這個rax來源一個CALL的返回值

3. 這個時候我們在這個CALL下斷,為了確認(rèn)下是否返回的是否是我們上面的對象
4.結(jié)果在這個CALL里面發(fā)現(xiàn)來源是rsi

5.繼續(xù)找rsi來源

6.發(fā)現(xiàn)rsi來源rbp,同時rbp來源[rdx],結(jié)果就在我們以為來源是rdx的時候,我們發(fā)現(xiàn)rdx是堆棧地址,也就是來源是這個CALL的rdx參數(shù),也就是第二個參數(shù)
7.好!這個時候我們來到這個CALL下斷再看看rdx參數(shù)里面存著什么

?8.觀察到,的確,在調(diào)用這個CALL的時候,rdx堆棧里面已經(jīng)存著對象了
9.接下來就繼續(xù)找堆棧里面對象的來源
10.當(dāng)我們往上找的時候,發(fā)現(xiàn)緊接著上面的CALL就有一個很熟悉的匯編語句

?11.lea rdx, ss:[rsp+0x38]有經(jīng)驗的同學(xué)就知道這句匯編結(jié)合調(diào)用下面的CALL并把rdx作為第二個參數(shù)的含義是什么
12.其實就是傳遞一個局部變量的地址,然后CALL內(nèi)部把需要的值寫入rdx指向的地址中去
13.現(xiàn)在我們驗證下,我們斷下

14..咦!我們居然發(fā)現(xiàn)我們需要的對象怎么存在這個堆棧里面呢?其實是有的,只是經(jīng)過這個CALL,才會被寫入,也就是這個CALL很可能是一個獲取對象的CALL,并把對象寫入到rdx堆棧地址中,說明我們的猜測應(yīng)該是對的,最終堆棧里面的對象來源就是這個CALL
15.分析參數(shù),發(fā)現(xiàn)此時rdx堆棧地址里面存這2個對象,同時r8我們發(fā)現(xiàn)類似一個ID

16.經(jīng)過這個CALL,rdx由原來的沒有對象被寫入了2個對象,剛好第一個對象就是我們需要找的物品對象

17.接下來繼續(xù)找這個堆棧地址啥時候?qū)懭氲倪@2個對象
18.這下就好辦了,我們就在這個CALL下斷點,然后轉(zhuǎn)到rdx堆棧地址,觀察此時是沒有我們所需要的對象,這個時候按F7進(jìn)入CALL,接著按F8,逐步分析啥時候?qū)懭肓诉@個rdx堆棧地址中得值
19.當(dāng)我們慢慢的分析,這里觀察到一個遍歷,而且還是一個結(jié)構(gòu)體數(shù)組,每個結(jié)構(gòu)體大小是0x60

20.發(fā)現(xiàn)一個結(jié)構(gòu)體數(shù)組,了解過數(shù)組概念的同學(xué)都知道,我們只需要找首地址就行了,也就是rcx的地址

21.發(fā)現(xiàn)這個r11首地址來源r15,然后在函數(shù)頭發(fā)現(xiàn)來源rcx,也就是這個CALL的第一個參數(shù)

22.我們看看rcx參數(shù)對象在內(nèi)存存的是什么,居然我們的結(jié)構(gòu)體數(shù)組在這個對象里面
?分析結(jié)構(gòu)體數(shù)組所在對象
1.我們發(fā)現(xiàn)居然確實有一個結(jié)構(gòu)體數(shù)組

2.我們觀察下這個結(jié)構(gòu)體數(shù)組, 同時我們上面分析得到這個結(jié)構(gòu)體數(shù)組中每個結(jié)構(gòu)體大小為0x60

3.同時我們發(fā)現(xiàn)在每個0x60大小的結(jié)構(gòu)體中還有一個結(jié)構(gòu)體數(shù)組

4.我們進(jìn)入分析看看,居然發(fā)現(xiàn)這個結(jié)構(gòu)體數(shù)組中,每個大小為0x18,同時每個結(jié)構(gòu)體+8 +10的2個對象就是我們寫入上面rdx堆棧地址中的2個值

5.原來如此,此時我們就找到了遍歷所在
6.但是!細(xì)心的同學(xué)發(fā)現(xiàn)我們的物品不是有32個嗎,這個結(jié)構(gòu)體數(shù)組才0xE

7.對的,的確是這樣的,其實正如上面我們所看到的,在rcx對象中有0x60結(jié)構(gòu)體,而每0x60結(jié)構(gòu)體中+8 +10有一個物品結(jié)構(gòu)體0x18數(shù)組
8.那么也就是把所有0x60結(jié)構(gòu)體的物品0x18大小結(jié)構(gòu)體數(shù)量加起來應(yīng)該就是我們物品總數(shù)了
9.我們看看剛好前3個0x60結(jié)構(gòu)體的物品0x18大小結(jié)構(gòu)體一共有32個,這就對了

10.這里再說下,為什么有3個0x60結(jié)構(gòu)體呢?
11.其實觀察過這個游戲的同學(xué)就明白了!我們看看這個背包界面他有3個類型按鈕,然后再數(shù)一數(shù)物品數(shù)量,你就明白啦?。。?/p>
12.好了,到這里我們整個遍歷就找到了,還是比較簡單,只是在這個CALL內(nèi)部需要分析一段時間,但是呢有經(jīng)驗的同學(xué)其實根本不用去分析匯編了,只需要觀察這個結(jié)構(gòu)體數(shù)組我們?nèi)シ环瓋?nèi)存就能分析出來!
13.到這里我們分析了遍歷,知道了遍歷就在rcx對象中,那么rcx對象存在哪里呢???這個時候就需要往上分析找來源啦,這個步驟相對來說就簡單了很多!
尋找rcx來源
?1.發(fā)現(xiàn)rcx來源[rcx+38]

2.這時候rcx就是一個對象了,因為我們在+0的地方看到了虛函數(shù)表首地址

3.繼續(xù)分析找來源,發(fā)現(xiàn)來源rsi,結(jié)果在上面就看到來源一個CALL的返回值

4.進(jìn)入CALL,分析

5.輕松的找到偏移表達(dá)式:[[[0x00007FF798D8E448]+30]+28] 是一個對象數(shù)組,而我們需要的rcx對象在這個對象數(shù)組索引為0x4的地方

6.這個4來源是哪里呢?其實就是這個CALL的參數(shù)傳遞進(jìn)來的0xC,然后在CALL內(nèi)部被計算成了4,其實我們寫死就行了,因為調(diào)用這個CALL的時候,匯編也是寫死的

7.好了我們整個背包物品遍歷數(shù)據(jù)分析就到此結(jié)束了
8.敲了這么多字,希望大家喜歡,感謝同學(xué)們支持迪大學(xué)院285530835
