vc6 中实现gcc 的__builtin_return_address 扩展

获取函数返回值:

gcc提供了获取当前函数的返回地址的一个关键字:

void * __builtin_return_address(int nLevel);

nlevel 参数指获取哪个函数的返回值,0表示当前函数,1表示当前函数的调用者的函数,为2依次类推;

下面是vc6的实现:

__declspec (naked) void* __builtin_return_address (int iLevel)
{
    __asm
    {
        push ebx;
		
        mov eax, ebp;
        mov ebx, DWORD PTR [esp + 8]; // iLevel
		
__Next:
        test ebx, ebx;
        je  __break;
        dec ebx;
        mov eax, DWORD PTR [eax];
        jmp __Next;
__break:
		
        mov eax, DWORD PTR [eax + 4];
        pop ebx;
        ret;
    }
} 

用一个测试例子来试一下:

int sum(int a,int b)
{
	void *add=__builtin_return_address(0);
	return a+b;
}
int main(int argc, char* argv[])
{


	int c=sum(1,4);
	
	return 0;
}

这里取得是当前函数的返回地址;调试过程中用汇编展开:

32:   int main(int argc, char* argv[])
33:   {
004010A0   push        ebp
004010A1   mov         ebp,esp
004010A3   sub         esp,44h
004010A6   push        ebx
004010A7   push        esi
004010A8   push        edi
004010A9   lea         edi,[ebp-44h]
004010AC   mov         ecx,11h
004010B1   mov         eax,0CCCCCCCCh
004010B6   rep stos    dword ptr [edi]
34:
35:
36:       int c=sum(1,4);
004010B8   push        4
004010BA   push        1
004010BC   call        @ILT+0(sum) (00401005)
004010C1   add         esp,8
004010C4   mov         dword ptr [ebp-4],eax
37:
38:       return 0;
004010C7   xor         eax,eax
39:   }


我们看到,sum函数的返回地址应该是004010C1, 然后跟进sum函数,查看执行后add的地址发现恰恰是004010C1,说明模仿成功。

 

__declspec (naked)关键字说明:

naked

Microsoft Specific —>

__declspec( naked ) declarator

For functions declared with the naked attribute, the compiler generates code without prolog and epilog code. You can use this feature to write your own prolog/epilog code using inline assembler code. Naked functions are particularly useful in writing virtual device drivers.



 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值