如下图:
图中的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;
}