001 从人物血量学习数据查找
文章目錄
- 前言
- 游戲選擇與環(huán)境搭建
- 查找人物血量
- 查找血量基址
- 第一條線(簡單)
- 第二條線(一般)
- 第三條線(困難)
- 總結(jié)
前言
本系列文章旨在從零開始學(xué)習(xí)游戲輔助的工作流程和開發(fā)方法,了解游戲背后的攻防對抗手段,重點(diǎn)側(cè)重?cái)?shù)據(jù)和call的追蹤查找。
側(cè)重方向在于學(xué)習(xí)整個分析過程以及思路方法,最終實(shí)現(xiàn)的效果和游戲不是關(guān)心的重點(diǎn)。
涉及到的技術(shù)有:
- windows API Hook
- dll注入
- 匯編語言
- 軟件逆向
- Windows編程
- C/C++基礎(chǔ)
沒有上述的前置知識建議勸退
游戲選擇與環(huán)境搭建
這里用來進(jìn)行分析的游戲是口袋西游,鏈接如下:
鏈接:https://pan.baidu.com/s/1nXUoK8UUEI3t3-hgAQ5pBg
提取碼:e57t
復(fù)制這段內(nèi)容后打開百度網(wǎng)盤手機(jī)App,操作更方便哦
下載以后直接解壓縮,element文件夾中的ELEMENTCLIENT.EXE就是口袋西游主程序
選擇這個游戲的好處在于,這個游戲是老版本的口袋西游,不會一直更新,難度也非常適合新手,方便進(jìn)行調(diào)試學(xué)習(xí)。
在正式開始逆向之前建議先玩一段時間,熟悉一下游戲規(guī)則,后續(xù)操作起來會比較方便
查找人物血量
首先用CE附加游戲
直接搜索當(dāng)前的人物血量值810
然后通過換裝備的方式改變一下當(dāng)前的人物血量,再次搜索,會得到兩個值,一個是當(dāng)前血量,一個是最大血量
區(qū)分的方式是通過再次換裝然后觀察數(shù)據(jù)變化進(jìn)行分辨,或者直接在CE中修改數(shù)據(jù)
查找血量基址
接下來我們要通過這個地址把血量的基址追出來。
血量為零時角色會被判斷死亡,血量不足最大值時會有一個回血的效果,而這些都會導(dǎo)致血量無時無刻被訪問。
接著在當(dāng)前地址右鍵,找出是什么訪問了這個地址,可以看到這里有四條匯編語句在訪問當(dāng)前這個血量地址
008199FA - DB 87 88020000 - fild dword ptr [edi+00000288] 0055C062 - 8B 9E 88020000 - mov ebx,[esi+00000288] 00482A36 - 8B 8E 88020000 - mov ecx,[esi+00000288] 00482AA9 - 89 96 88020000 - mov [esi+00000288],edx無論我們從哪條匯編開始追都能得到我們想要的基址,區(qū)別在于難度不一樣。在學(xué)習(xí)階段盡可能嘗試所有的難度以應(yīng)付后期的實(shí)戰(zhàn),這里先從第一條線開始追
第一條線(簡單)
008199FA - DB 87 88020000 - fild dword ptr [edi+00000288]在這個地址下斷
這里很快就能追到基址
- edi+0x288是血量
- edi來自于eax+0x28
- eax來自eax+0x1C
- eax=[0xD0DF1C]
最后得出血量基址公式為
血量=[[[0xD0DF1C+1C]+0x28]+0x288]在CE里添加這個地址
數(shù)值顯示和當(dāng)前血量一致,說明基址正確
第二條線(一般)
0055C062 - 8B 9E 88020000 - mov ebx,[esi+00000288]在這個地址下斷,讓程序斷下
用OD載入,直接在第一條匯編語句上面下斷,這個時候esi+0x288的值是0x32A(810),也就是人物的當(dāng)前血量。那么接著我們就要往上找這個esi來自于哪里。
借助OD的寄存器高亮插件一直往上翻,可以找到一條給esi賦值的語句,也就是說
血量=[eax+0x288]而eax前面有一個call,所以可能是上面這個call的返回值,進(jìn)入這個call
可以看到這個call內(nèi)部進(jìn)行了一些運(yùn)算,從下往上進(jìn)行逆推,我們很容易就能得出血量的基址為下面的值:
這里的基址和第一條線是一致的,也沒有問題。
第三條線(困難)
仔細(xì)觀察,其實(shí)第三條線和第四條線其實(shí)是一個東西
00482A36 - 8B 8E 88020000 - mov ecx,[esi+00000288] 00482AA9 - 89 96 88020000 - mov [esi+00000288],edx兩個地址很近, [esi+00000288]來自edx,而ecx來自[esi+00000288],那么我們就繼續(xù)往上追esi
在這個地址下斷,讓程序斷下
esi+288就是當(dāng)前的血量值,接下來往上追esi的來源
esi來源于ecx,繼續(xù)到上層函數(shù)追ecx的值
而這層函數(shù)里并沒有找到對ecx賦值的語句,所以繼續(xù)找到上上層函數(shù)
這里ecx來自于eax,所以我們要進(jìn)到這個call里面繼續(xù)找eax
這里有兩個對eax進(jìn)行賦值的語句,倒推出來可以得出
血量=[[[ecx+0x8]+0x28]+288]返回剛剛的位置,繼續(xù)追ecx
這里ecx已經(jīng)到了函數(shù)頭,需要再往上找一層
這里ecx來自于[ebp+eax*4+0x1C],我們在這個地方下個斷點(diǎn),這里eax=0,那么ecx就等于[ebp+0x1C],血量地址如下:
血量=[[[[ebp+0x1C]+0x8]+0x28]+288]繼續(xù)找ebp的來源
這里ebp來自eax+0x8,血量地址就等于
血量=[[[[[eax+0x8]+0x1C]+0x8]+0x28]+288]eax則來自于[ebx+0x4]
血量=[[[[[[ebx+0x4]+0x8]+0x1C]+0x8]+0x28]+288]而ebx來自ecx,所以
血量=[[[[[[ecx+0x4]+0x8]+0x1C]+0x8]+0x28]+288]這里已經(jīng)到了函數(shù)頭,繼續(xù)返回上一層追ecx
這里下斷 找到上層返回地址
ecx來自[edi+0x68],所以
血量=[[[[[[[edi+0x68]+0x4]+0x8]+0x1C]+0x8]+0x28]+288]繼續(xù)追edi
這里edi來自ecx,那么血量就等于
血量=[[[[[[[ecx+0x68]+0x4]+0x8]+0x1C]+0x8]+0x28]+288]這個地方又到了函數(shù)頭部,所以繼續(xù)找到返回地址向上跟
這里ecx來自ebp,所以
血量=[[[[[[ebp+0x68]+0x4]+0x8]+0x1C]+0x8]+0x28]+288繼續(xù)找ebp
往上翻的時候這里會看到ebp來自[ebp+0x28],實(shí)際上我們在這下個斷點(diǎn),會發(fā)現(xiàn)這個地方根本斷不下來,說明這條語句不被訪問。
那么這個[ebp+0x28]就是無效的,繼續(xù)往上找ebp來源
這里ebp來自于ecx,那么
血量=[[[[[[ecx+0x68]+0x4]+0x8]+0x1C]+0x8]+0x28]+288這里也到也函數(shù)頭,繼續(xù)往上找ecx
返回上層我們發(fā)現(xiàn)ecx=[ebp+0x1C],下個斷點(diǎn),發(fā)現(xiàn)ebp的值是個基址,那么ecx就等于[00D11A50+0x1C]
血量=[[[[[[[00D11A50+0x1C]+0x68]+0x4]+0x8]+0x1C]+0x8]+0x28]+288到這里整個第三條線的基址數(shù)據(jù)就追完了
在CE里添加這個基址,結(jié)果為810,正好是我們的人物血量
總結(jié)
在逆向分析數(shù)據(jù)的過程中會有很多條線路,無論是哪條都能追到我們想要的結(jié)果。區(qū)別在于有的是康莊大道,有的是荊棘叢生。
最后我們得出了一條經(jīng)驗(yàn):在實(shí)際分析過程中如果感覺數(shù)據(jù)查找比較困難,趕緊勸退,換另外一種方式,曲線救國。
https://github.com/TonyChen56/GameReverseNote
《新程序員》:云原生和全面數(shù)字化實(shí)踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀總結(jié)
以上是生活随笔為你收集整理的001 从人物血量学习数据查找的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 编译器扩展SEH
- 下一篇: 002 通过send断点分析功能call