如下圖:
圖中的var_s0變量對應地址ebp,[ebp+4]保存函數返回地址,[ebp+8]是第一個參數。在call sub_xxx這種情況下,返回地址等於當前地址加上5字節。如下圖:
上面這個應用例子中是想獲取ZwLoadDriver(*)更底層一些的實現,從而躲過一些麻煩。
下面是應用層的例子:
DWORD r_ebp=0;
DWORD l_entry=0;
void _stdcall GetCaller(DWORD a)
{
DWORD addr=0;
addr=*(DWORD*)(a+4);//get the return address
if(0xe8==*(unsigned char*)(addr-5))
{
printf("there is a 'call sub_xxx!\n");//call sub_xxx----->e8 00 00 00 00
printf("data at 0x%x is 0x%x,addr+*(DWORD*)(addr-4) is 0x%x\n",
addr-4,*(DWORD*)(addr-4),addr+*(DWORD*)(addr-4));
l_entry=(n_entry)(addr+*(DWORD*)(addr-4));
printf("addr of l_entry:0x%x\n",l_entry);
}
else
{
printf("bad data!");
}
}
void fake(int h)//main()調用了fake(),上面應該輸出main()的地址
{
_asm mov eax,dword ptr [ebp]
_asm mov r_ebp,eax
GetCaller(r_ebp);
}
int main()
{
printf("addr of main:0x%x\n",main);
fake(12);
getchar();
return 0;
}