1.shellcode代碼重定向
當我們獲得一個溢出緩沖區,要向其中注入代碼時,為保證shellcode代碼在任意機器上正常運轉,我們必須獲得shellcode
注入的位址,在此我們要用到的一個關鍵的技術:代碼重定向
- call指令本質包含兩個步驟:壓棧和跳轉
- call指令後接跳轉位址,在二進制表示時使用的是相對位址
//彙編指令
call 40400
//等同于
push current //call指令目前所處位置
jmp 40400
//利用執行個體
begin:
call entry //E8 00000000
entry:pop ebx //ebx中所存為注入點位址
// do something ...
2.在記憶體中尋找kernel32.dll位置
當我們重定向了代碼,開始進行系統調用是,問題來了,函數位址在哪呢?
因為dll的加載都是任意的,你無法在事先确定函數位址,是以我們隻能通過GetProcAddress()函數來動态獲得函數位址
但是GetProAddress()的位址也不知道啊,可能有人會問了大笑
這不是死循環嗎?
我們強大的帽子總是有辦法的,先給出執行個體代碼,稍後解釋。
mov eax, fs:[30] //PEB
mov eax,[eax+0ch] //PEB_LDR_DATA
mov esi,[eax+1ch] //InInittializationOrderModuleList
lodsd
mov ebx,[eax+08h] //base address
if base.name=="kernel32.dll" //xp and more
jmp ok
then //win7
mov esi,eax
lodsd
mov ebx,[eax,08h]
ok: //到此ebx所存即為kernel32.dll的記憶體位址
//do something....
通過以上代碼可以從任意平台動态擷取kernel32.dll的加載位址。
了解PE結構的人就了解,知道了kernel32.dll的人就會知道如何通過這位址獲得GetProAddress()位址,進而獲得Windows平台下任意API函數位址。
PE結構不再此博文讨論之列,若讀者不清楚可自行學習,不難但繁瑣。
先對以上代碼解釋:
PEB結構----枚舉使用者子產品清單
它所處位置為 fs:[30],其結構如下圖:

一般來說,在xp平台上kernel32.dll是挂在連結清單的第一位,win7平台以後第一位則是kernelbase.dll,kernel32.dll位于連結清單的第二位。