vc6 中实现gcc 的__builtin_return_address 扩展

本文介绍如何使用GCC提供的__builtin_return_address函数获取当前函数及其调用者的返回地址,并通过VC6的具体实现进行了说明。同时,文章还提供了一个示例程序帮助理解这一机制。

获取函数返回值:

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.



 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值