32位匯編第六講,OllyDbg逆向植物大戰僵屍,快速定位陽光基址
一丶基址,隨機基址的理解
首先,全局變量的地址,我們都知道是固定的,是在PE文件中有保存的
但是高版本有了隨機基址,那么要怎么解決這個問題,不解決這個問題,那么如果以后逆向分析的時候,找不到基址,那么就不能進行下一層的操作
首先看下固定基址,和隨機基址
①丶新建工程
(這里使用VS2013 ,VC++6.0不支持隨機基址)


自己新建一個程序,添加個CPP文件
編寫如下代碼
#include <stdio.h> #include <stdlib.h> int g_szText = 2;int main() { printf("g_szText address = %p\r\n", &g_szText); system("pause"); }
我們看下設置,是否隨機基址已經啟動
1.找到項目屬性

看下 連接器 -> 高級 -> 隨機基址

現在我們的程序是隨機基址,每次打開都是隨機的


備份一下,然后修改為不隨機基址
不隨機基址,就是地址沒次運行都是一樣的,現在我們比較兩個文件,隨機基址在文件中是存的一個標記
我們在PE文件中更改這個標記,則可以達到基址是一樣的了

Text1是隨機基址的,TEst是不隨機的
使用Winhex對比

比對

首先我們排除一下,標志不會在下面,因為程序一啟動則要加載
隨意在上面PE 后面我們一個自己一個字節的嘗試
這里我就不嘗試了,標志是PE 后面數6個字節,然后下方就是
也就是02 和 03
02是隨機基址,03是不隨機
現在改一下試一下

因為程序權限問題,這里不讓我更改,不過我們可以寫文件更改
第二種方法
如果對於修改文件,我們不愛做,我們也可以通過程序算偏移去做
具體
有公式可以計算
全局變量的地址 - 模塊首地址 = 偏移
每次程序啟動加載模塊
模塊 + 偏移 = 全局變量的地址,也是可以一樣的訪問
這里是把全局變量當做DLL使用
二丶OllyDbg分析植物大戰僵屍,快速定位陽光基址
1.對於植物大戰僵屍,我們需要一款內存搜索工具 (Cheat Engine 簡稱CE)
為什么使用這款工具,因為這款游戲不同於上次講的掃雷,上次的掃雷,我們可以通過Bitblt
去尋找,繪圖,而這次如果在通過繪圖去找,那么很麻煩,所以我們使用這款工具
2.首先CE加載植物大戰僵屍的進程

進程名稱: PlantsVsZombies.exe
3.搜索陽光的數量
我猜測他是4個字節存放陽光的數值,那么我們可以是4個byte搜索,先搜索精確的數值

4.然后增加或者減少陽光,在已有的基礎上,搜索現有的陽光數量

5.找到一個,我們看下修改值是否會把陽光修改了

發現成功修改

那么我們看下這個地址有沒有別的變量保存
例如 int *p = 0x 106F6EB0
Int *p1 = p ;有可能是這樣存儲的
復制出來搜索一下
以16進制掃描,來一個新的掃描

我們發現沒有保存,那么我們可以認為他是存儲陽光的(但是又怎么簡單嗎)
我們重新打開游戲,看下這個地方是否變化了,如果沒變,那么這個基址就是保存了陽光的數值
什么是基址?
上面說了很多基址的概念,什么是基址
比如看下列代碼
全局區
Int *G_RunCount = NULL //全局 Int main() { Int *p1 = 0x11122233當前存儲了陽光的個數) P = p1 //保存地址 System(“pause”); }
那么像我們上面所說,如果重新打開游戲,那么這個地址不存在了,也就是說地址里面存的不是陽光的數量,那么我們可以認為他不是最頂層的地址
最頂層的地址就是 全局變量,只要找到全局變量那么以后都不用修改了,因為全局變量中存儲了這個地址
那么我們試一下

我們發現這塊地址不是,很有可能是局部變量存儲了
那么我們重新進行上面的幾個步驟,找出當前的局部變量存儲的地址
10711A38
打開OD,附加當前植物大戰僵屍的進程,在數據區域Ctrl + G 跳轉到重新找到的局部變量地址

我們修改一下

正式我們要找的存放陽光數量的地址
那么現在我們下一個內存訪問斷點,看看誰訪問了這個地方


我們看到,他是加了一個偏移尋到了5560
也就是 [base + 5560] 取內容 = 陽光的個數
那么現在主要是base(地址)是什么,在上面可以看出,base是edx,那么現在主要是edx的值

(注意,尋找的時候你們可能看的不一樣,因為地址是不固定的,固定的是全局變量,也就是說為什么我們要全局變量地址+偏移的方式來訪問數值的)
我們去CE搜索一下這個變量有沒有存儲

我們發現這塊局部變量地址,也有人來保存,那么我們OD查一下這塊局部變量的地址,看下內容(為什么要再次搜索,因為如果有保存這個值的局部變量,那么就不是最終的地址,所以一定找到頂層)
(別忘了OD的內存斷點取消)
我們發現有很多,但是,我們需要用排除法了,首先,根據上面我們的經驗,全局變量的地址不是 0018開頭的,這個很像局部變量,如果是局部變量,那么往上查找很困難
那么我們往下拉,看看還有沒有了
我們依次下內存斷點,我們會發現,有的時候下了內存斷點,你的植物大戰僵屍暫停界面會停止不動,那么可能是我們找錯了,刪除內存斷點,重新繼續
我們排除0018開頭的,因為不光是局部變量,如果是你寫代碼,你有可能會寫很多地址相似的位置一起保存Base基址嗎
例如
Int *p1 = p
Int *p2 = p
Int *p3 = p
Int *p4 = p
....
所以找不同的

我們發現再次搜索,發現就這兩個不通,我們把第一個弄下來,然后數據窗口中搜索,下內存斷點,(內存訪問)

,內存斷下了來了

現在我們知道base的地址是怎么得到了
以前是 [base + 5560] = 陽光的個數
但是現在因為求base所以base變為了
[[base + 768]+5560] = 陽光的個數
看看Base是多少

我們重新看下這個地址有沒有保存,如果有,那么繼續往上尋找
CE搜這個地址

搜索完成之后發現有幾個綠色的,以后看到綠色的優先嘗試,因為這個可能就是全局基址了
先看第一個

雙擊地址,發現了這個,那么這個是什么意思,這個的意思就是 (游戲首地址 + 偏移的意思)
游戲首地址怎么看
我們打開PChunter工具(注意,64位系統,請用64位的,32的用32的,我的是64的所以用64的)

找到植物大戰僵屍的進程

看下模塊路徑,以及植物大戰僵屍的基地址入口點

所以我們的公式可以得到補充了
[[006A9EC0 + 768]+5560] = 取出的內容等於陽光的個數
為什么我們確定是006A9EC0,而不是下面的3個綠色的
我們可以數據窗口中搜索這個地址,接着內存下訪問的斷點

我們可能會得出很多個加偏移的,不過沒關系,一個一個的場浩司,總會找到
最終會找到,如下圖

那么現在我們用CE的添加地址功能 把我們的地址+偏移添加上,看看是否陽光一樣

對了,那么以后寫代碼就是基址 + 偏移 + 偏移訪問
對於找基址的不太熟悉的話,可以看下面的圖片

,看下指針結構圖后面的內容

也就是 006A9EC0 里面的值 02209CA8
Struct A { Struct B { Int a //存放陽光的個數 } }
Int a存儲了陽光的個數
我們要尋找a
B(地址) + 偏移(5560) = a的地址,然后取內 = 陽光個數
B的地址又要尋找,那么
A的地址 + 偏移(768) = B的地址
A的地址尋找
找到了一個實例
相當於 A p1 = new A(); 我們尋找的P1的地址
P1的地址取內容 = new A的地址(也就是A的地址)
A + 768(得出B的地址) + 5560 = int a成員變量的地址,對其取內容 = 陽光個數
課堂資料:
鏈接:http://pan.baidu.com/s/1cbGf18 密碼:gk7s
