學習逆向知識之用於游戲外掛的實現.第二講,快速尋找植物大戰僵屍陽光基址.以及動態基址跟靜態基址的區別


              通過游戲外掛,學習逆向技術之快速尋找植物大戰僵屍陽光基址.以及動態基址跟靜態基址的區別

一丶靜態基址. 動態基址. 基址的區別

 通過上一講超級馬里奧的游戲外掛技術制作.我們學習到了靜態基址.以及觀看內存區域得出相關偏移出的靜態基址.

那么什么是靜態基址.什么是動態基址. 什么是基址.

1.靜態基址

  靜態基址指的是.程序在啟動后地址是不變的.游戲關閉后重新啟動.那么地址也是不會變的.我們通過逆向技術直接對其修改那么則可以進行我們的外掛制作.

2.動態地址.

  動態地址是指當前地址保存了我們想要的屬性信息. 但是當游戲重新打開.的時候.其當前地址的信息已經不是我們的信息了.所以我們要尋找基址.

3.基址

  基址指的就是最頂層的地址. 這個地址是不會改變的.除非游戲重新編譯.或者增加減少成員.

二丶以植物大戰僵屍為例.尋找當前動態地址.

植物大戰僵屍這款游戲.相信我們大家都應該玩過.那么我們通過這款游戲.來學習 動態地址. + 基址的尋找方法. 

文字簡介:  CE附加植物大戰僵屍進程 -> 搜索陽光數量(精確數值 4字節搜索) -> 改變陽光數值 -> CE再次搜索改變之后的數值.

改變陽光數值.點擊再次掃描.進行新的搜索.

通過在次掃描之后.我們得出一個地址.這個地址是一個動態地址. 怎么判斷是否是動態地址.

1.我們首先修改這個地址里面的值. 看看是否能把陽光修改 (已經測試.可以修改.不截圖說明了)

2.我們重新打開游戲.看看當前地址里面的值是否是我們陽光的值. (不是,已經測試)

經過上面兩個步驟.我們可以得出.這個地址是一個動態地址.所以我們還要繼續向上尋找.

三丶尋找基址.

  通過上面的地址我們知道這一個是一個動態的地址.那么我們需要找到基址應該怎么尋找?

思路: 如果找到一個動態地址.那么修改陽光肯定會修改這個地址這個地址里面的值. 所以我們可以下一個寫入斷點

1.我們可以用CE 下寫入斷電. 找出什么修改了這個地址

2.我們可以用OD / x32Dbg 下寫入斷點

上面兩種方式都是可以完成的.

我們雙擊打開反匯編

可以看到里面的值是 add[eax + 0x5560],ecx

那么我們尋找到了一級偏移. 5560

那么這里涉及到偏移. 我們講下原理吧.

其實很簡單.植物大戰僵屍編寫的時候都是對象或者結構體成員.

例如:

  

struct Plant
{
   
    ......
    int sunNumber;  
}

而在匯編指令中則是 結構體到地址 + 偏移 得出 陽光的個數.

所以我們要繼續尋找結構體首地址. 也就是誰保存了結構體首地址.所以根據上圖匯編得出.我們需要繼續尋找eax

繼續尋找eax

CE 以16進制搜索eax的值

根據上圖可以得出. 一個地址里面保存了結構體的值. 那么猜想這個可能就是結構體的首地址了.我們使用CE的手動添加地址添加我們的偏移看一下.

我們也不知道上面的地址那個是保存了結構體的地址. 不過CE一般都是前五個.當前也不一定.可以嘗試一下.

根據上圖我們可以得出 0299a4a0地址的內容是結構體首地址. 根據CE的手動添加指針.我們加上我們的偏移.可以得出陽光的地址.(對地址取內容則是陽光的值)

現在我們找的這個地址還是一個動態地址. 所以我們要找一下什么訪問了這個地址為什么是訪問? 因為要操作陽光.肯定會訪問這個地址. 如果修改陽光則會修改這個陽光的值.

因為這個地址保存了結構體首地址.那么他肯定不會改寫了.所以肯定會訪問.所以我們找一下訪問的地址.

 

 根據上圖的值, 看匯編代碼得出 mov esi[edi + 0x768] 訪問了這個地址.

那么同理 [edi + 0x768]保存了結構體的地址. 那么edi 是一個新的結構體的地址. 而我們進行搜索的時候會發現其實這是一個結構體的嵌套.

例如:

  

struct aaa
{
    .......
    struct plant plant    //0x768
    {
        int SunNumber;  //0x5560
    }
}

所以我們要繼續尋找edi是誰保存了.

繼續尋找edi的值我們發現有幾個綠色的值.一般遇到這個很有可能是基址了.

那么我們嘗試一下.使用CE自帶的手動添加地址.

確實是我們的地址.那么我們繼續看誰訪問.

發現我們地址都是這樣了.匯編指令 mov reg,[常量地址]   那么則確定我們找到了我們的基址了.

原理:

  如果對基址不太熟悉.那么熟悉C++語法的大概能明白.

struct aaa
{
    struct plant
   {
          int SunNumber;
   }
}


aaa *p= new aaa;

new aaa 是我們的結構體首地址

new aaa + 768 = plant結構體的首地址

new aaa + 768 + 5560 = 陽光個數的地址

那么我們知道 new aaa是一個無名對象.所以肯定有一個變量保存着.
所以 *p 這個變量就是我們尋找的基址.

p + 768 + 5560 = 陽光個數地址
*(p + 768 + 5560 ) = 陽光個數.
所以我們找的基址就是p的地址. 而p保存的就是 new aaa的地址 new aaa中保存了 plant結構體的地址.

如果不理解也可以濾過. 熟悉我們的尋找方法即可.

通過上面我們的匯編指令.

add [reg + 0x5560],ecx       注意reg代表是任何寄存器.   add指令在匯編中是增加的意思. []的意思是對這個地址的內容進行操作

上面的匯編指令的意思是: 對 reg + 5560 的這個地址進行操作.因為帶有中括號.[] 所以意思是對reg + 5560這個地址里面的值進行操作.

 

mov reg,[reg + 0x768]. 內容同上.  mov 指令是傳送指令.  也就是將這個地址里面的值輔賦值給左操作數.

 

[[[6A9EC0] + 0x768] + 0x5560] = 陽光的地址.

所以我們可以寫程序來實現增加陽光跟減少陽光了

 

C++ :  學習OpenProcess  WriteProcessMemory  //注意: 在調用OpenProcess獲得進程句柄前.需要獲得進程PID.  可以通過FindWindow 查找窗口句柄.然后通過GetWindowsThreadProcessID() 通過窗口句柄獲取進程pID. 當前也可以通過 進程快照.遍歷進程.得出進程PID.都是可以的.具體不在累贅. 

易語言: 因為使用了超級模塊所以 熟悉 取進程ID  十六到十 寫內存整數型即可.

因為易語言實現簡單.所以直接使用易語言寫一個了.

 

 

 總結:

  通過這一講.我們學習了 add 匯編指令. mov 匯編指令. 以及結構體在匯編中表現的形式. 例如 [reg + 5560] 這樣的其實是結構體偏移.

學會了如果通過動態地址尋找基址.

課堂資料下載:  鏈接:https://pan.baidu.com/s/1DDWfx68wi37Dc2OV2aTpqQ 密碼:3w2x


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM