012 分析技能冷却二叉树
文章目錄
- 前言
- 技能冷卻二叉樹
- 獲取技能名稱
- 總結
前言
學習完了最常用的數據結構,我們再來分析游戲中其他的功能,盡量將游戲中的所有數據分析完全,為后面的實際應用積累經驗。
對于RPG游戲來說,技能數據是必不可少的。這次我們就來找技能相關的數據。
技能冷卻二叉樹
想要找到技能相關的數據結構,可以有很多突破口,比如技能名稱,技能ID,技能冷卻時間等等。以技能冷卻時間為例,找一下當前的技能數據。
首先找到一個技能冷卻時間長的技能,以技能的當前冷卻時間為突破口來找技能數據。
以這個技能為例,釋放技能,此時處于冷卻狀態,冷卻時間開始倒計時。 在CE中選擇浮點型,未知初始值
然后一直掃描減少的數值
最后從多個結果中很容易就能找到唯一一個和當前冷卻時間相同的數值。然后對這個地址下硬件訪問斷點
斷點斷下,ecx+0x10是技能的冷卻時間。在這個地方下斷點,一直F9運行,發現ecx的值是不變的。
接著再次釋放技能,ecx的值會在兩個數值間變化。
就是說這個位置是所有處于冷卻狀態下的技能才會訪問的代碼。那么最后我們會追到數據結構,里面存放的是所有處于冷卻狀態中的技能。
繼續往上追ecx的值
ecx來源于[edi+0x10],觀察edi的值,此時edi依然是兩個值變化的
冷卻時間=[edi+0x10]+0x10edi來源于[eax]。此時eax不再發生變化,盡管這個時候有兩個技能處于冷卻狀態。根據之前的經驗,說明這段代碼中有循環改變了寄存器的值。
找到向上的跳轉,確定循環頭部和尾部。
下面有第二個循環,頭部和第一個循環頭部一樣。
第三個循環,頭部也和第一個循環頭部一樣
第四個循環,頭部和第一個循環頭部一致。
繼續追edi,無論是第幾個循環,edi都來自[ebp-0x8],[ebp-0x8]作為局部變量,肯定中間有一個call會改變它的值
單步步過這個call,發現[ebp-8]被改變了,這個call傳入一個對象指針,然后返回一個新的對象。
跟之前分析過的二叉樹幾乎完全一樣,要么拿到根節點調用call取下一個對象,要么下訪問斷點找到遍歷的代碼。
還是在這個地方對數據下訪問斷點,斷點斷下。這個地方的代碼和之前一模一樣,是一個標準的二叉樹遍歷。
冷卻時間=[eax+0x10]+0x10[eax]是二叉樹的左子樹,[eax+8]是右子樹。[eax+0x15]是結束標志位,[eax+C]是技能ID。繼續往上可以把整個偏移表達式追出來,這里省略過程。
獲取技能名稱
找到了技能的冷卻時間二叉樹,接著來找技能名稱的數據結構。由于幻想神域這個游戲是用的繁體字,所以這里需要用到一個轉換工具,將Big5編碼的繁體字轉換為GBK編碼的十六進制。
隨意選取一個技能名稱,用工具轉換為字節集
然后在CE中搜索字節數組,字節尾部加上00
掃描出了五個結果,分別對五個值就行修改,即可篩選出唯一一個技能名稱。
接著在這個位置下硬件訪問斷點
打開技能欄讓斷點斷下,[esi+ecx*4-8]就是當前的技能名稱。這里由于所有的字符串經過這里都會斷下,并不僅限于技能名稱,所以就不太好追。
可以用到一個技巧
復制esi的值,在棧窗口點擊查找,一直按Ctrl+l找到堆棧中第一次出現的位置
這里esi是上面的返回地址中的第三個參數,反匯編窗口跟隨第三個地址繼續追第三個參數
第三個參數是edx
edx來源于ebx+edx,但是ebx的值為0,所以不用管繼續往上追
edx來源于[eax+4]
eax來源于[ebp+8],也就是第一個參數。這里返回上一層不能直接下軟件斷點,否則會得到錯誤的調用關系,必須在之前的數據下訪問斷點。
第一個參數是ecx,這個地方是技能名稱的訪問代碼,其他字符串不會斷下。ecx來源于ecx+0x100,又來源于[ebp+0x10],上一層的第三個參數,繼續下斷返回
第三個參數是esi,繼續往上找esi
esi來源于eax,eax是上一個函數的返回值。這個call的內部邏輯比較復雜,里面還調用了之前分析過的數組下標加密的代碼,就沒必要繼續往上追了
直接分析參數,eax是技能ID,返回的eax是技能對象,我們可以通過調用這個call來獲取技能名稱。
實際效果如圖:
總結
分析完了技能冷卻二叉樹,相當于是復習了一下之前學過的內容,這種類似的數據結構,后面會碰到很多。
對于數據結構的逆向,需要在追蹤寄存器的過程中每一步都觀察寄存器的變化,然后通過當前的變化分析附近的代碼,從而分析出數據結構。
最后,附上Github地址,里面有游戲下載鏈接和相關工具,需要請自取:
https://github.com/TonyChen56/GameReverseNote
總結
以上是生活随笔為你收集整理的012 分析技能冷却二叉树的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 011 数据结构逆向—二叉树
- 下一篇: PC微信逆向:分析通用设置数组