靜態基址
靜態基址是指程序中實現定義好的數據(全局數據或局部數據),這種地址在程序每一次加載時都是唯一的不會變化(不考慮ALSR,如果存在ALSR則靜態地址相對於程序基地址的偏移不會變)。
動態基址
動態基址是指程序中通過new或者malloc從堆中申請返回的地址,這種地址在程序每一次加載時都可能會變化。
通過動態基址尋找靜態基址
靜態基址一般通過多級指針指向動態基址,我們先找到動態基址后回溯得到多級指針,最后得到靜態基址。
通過CE搜索功能回溯
以植物大戰僵屍為例,我們先找到陽光的動態基址。
接着我們找到哪個地方訪問的這個地址,發現add eax,[edx+00005560]這條指令訪問了這個地址,而edx的值為0x1A761CD8
接着搜0x1a761cd8的值,並查看誰訪問的他。發現cmp dword ptr [eax+00000768],00指令訪問了這個地址,eax值為0x02859C70
接着搜0x02859C70的值,並查看誰訪問的他。發現靜態地址0x006A9EC0的值為0x02859c70。
最后總結得出:0x1A767238 = [0x006A9EC0 + 0x768] + 0x5560,即陽光靜態基址為0x006A9EC0,一級偏移為0x768,二級偏移為0x5560。
通過匯編代碼回溯
我們尋找第一個卡槽植物的CD時間的動態基址。
我們搜索誰訪問的這個地址,發現指令add dword ptr [edi+24],01訪問了這個地址,edi等於0x1778CA98。
接着搜0x1778CA98的值發現搜索不到,我們查看add dword ptr [edi+24],01地址處對應的反匯編代碼, 發現edi值來源於eax,而eax的值來源上層函數。
我們返回上層函數發現,eax值等於 edi + eax + 28。我們發現此處為一個循環,edi每次增加50,而當eax等於0x1778ca98時,edi等於0。因為eax = edi + eax + 0x28,所以原來的eax = 0x1778ca98 - 0x28 = 0x1778ca70。
那么為什么我們在CE中沒有搜索到0x1778CA98的值呢,因為我們在CE中搜索時鼠標的焦點在CE中游戲被暫停了,而當游戲被暫停后下圖中更新植物CD時間的函數代碼就不會執行了,導致無法搜索到誰訪問的地址。
接着搜0x1778ca70的值,並查看誰訪問的他。發現指令mov eax,[ebx+00000144]指令訪問了這個地址,ebx = 0x1A761CD8.
接着搜0x1A761CD8的值,並查看誰訪問的他。發現指令cmp dword ptr [eax+00000768],00指令訪問了這個地址,eax = 0x02859c70.
接着搜0x02859c70的值,並查看誰訪問的他。發現靜態地址0x006A9EC0的值為0x02859c70。
最后總結得出:0x1778CA98 = [[0x006A9EC0 + 0x768] + 0x144] + 0x28,而0x1778CA98 + 0x24處為第一個卡槽植物的CD時間。
並且由上述分析循環處代碼可得,卡槽植物對象數組基地址為 [[0x006A9EC0 + 0x768] + 0x144] + 0x28 + 50 * i;