call $5
pop eax
and eax,0xffff0000
and eax,base
jmp eaxhtml
delphi能夠這樣web
mov ecx,$12345678 //這裏寫入原來OEP入口shell
//動態基址獲取
//call $+5
CALL @@1
@@1:
pop eax
and eax,$ffff0000
and ecx,$0000ffff
or eax,ecx
//jmp eax
push eax
函數
上面再實際狀況中並不起做用,而應該用如下方式編碼
mov ecx,$12345678 //這裏寫入原來OEP入口
mov edx,$12345678 //這裏寫入原ImageNtHeaders.OptionalHeader.ImageBase基址
mov edi,$12345678 //這裏寫入新ep入口
//動態基址獲取
//call $+5
CALL @@1
@@1:
pop eax
sub eax,35 //獲得如今的ep+基址
sub eax,edi //減去ep 得到新的基址
add ecx,eax //獲得動態的原oep
//or eax,ecx
//jmp eax
//push eax
push ecx
spa
在進行病毒分析時,或者調試漏洞的shellcode時,常常看到標題中的指令流(E800000000 58,第二條確定是pop指令,可是目的寄存器不必定是eax),這是幹什麼的呢?調試
看起來貌似很神祕,其實結合先後代碼的意圖能夠知道(進行實時調試),最終eax中存放的數據是0x00413935(就上面的代碼),而這個0x00413935,剛好就是pop eax指令的地址,所以實際上這條指令流的做用就是獲取執行call $+5時,eip的值,也能夠簡單認爲是獲取當前指令地址,獲取當前指令地址有什麼用呢?我所見過最可能是使用場景是經過獲得當前指令地址來獲取硬編碼到shellcode中的字符串的地址,經過簡單計算當前指令地址+偏移(這個已知,由於shellcode就是本身寫的),就能夠獲取到字符串的地址。code
這條指令流的原理也很簡單,E8是call指令中的相對跳轉指令(能夠參考:http://www.mouseos.com/assembly/example/calling.html),它能夠帶一個dword參數,指明相對跳轉的距離(E8 dword offset),計算方式很簡單:下一條指令地址+ offset 便是call指令的目的地。下一條指令地址就是pop eax的地址啦。所以這個地方場景是這樣滴:orm
一、CPU執行到E800000000時,eip中此時存放的是下一條指令的地址,也就是0x00413935(計算機組成原理);htm
二、CPU執行call指令,將call指令的下一條指令地址push到棧中(也就是0x00413935被push到棧中,這是用於函數調用後返回的);
三、對E8指令進行解析,offset == 0,計算call指令目的跳轉地址:下一條指令地址+ offset ,eip被存入0x00413935;
四、跳轉到0x00413935執行(實際就是call的下一條指令),執行pop eax,從上面的分析可知,此時棧頂的值是0x00413935,所以eax就被賦值0x00413935。
有人可能想,獲取當前指令地址,直接mov eax, eip不就好了麼?還真不行,由於木有直接操做eip的指令的。