C++运行原理的汇编代码分析 二

SEH: Structured Exception Handler 结构化异常处理。 是windows的一个__try{}__except(){}异常处理机制。可以捕获系统异常,也可以用RaiseException()函数来抛出自定义异常
TEB:Thread Environment Block 线程环境块。 是一个用来记录线程运行状态的结构体,前4字节是SEH链表的起始地址,是一个栈地址,后4字节是第一个处理函数
例子:
栈add   :[-1(0xFFFFFFFF)] #是SEH的结尾标志
栈add-4h:[except_handle_function1_address(0xXXXXXXXX)]
栈add-8h:[except_handle_function2_address(0xXXXXXXXX)]
栈add-Ch:#这个地址就是TEB首4字节存放的内容
security cookie:一个数,在函数开始时和ebp的值异或,结果被保存,函数退出前检查是否栈溢出,可以防止恶意修改ebp
ES:段寄存器
FS:标志段寄存器(windows指向TEB)
GS:全局段寄存器
1、返回值是一个类
father get_father()
{
    father fa;
    fa.set_val3(0x10);
    return fa;
}
    father myfa = get_father();
00EC181E  lea         eax,[myfa] 
00EC1821  push        eax      #局部类对象地址入栈
00EC1822  call        get_father (0EC1181h) 
00EC1827  add         esp,4 
father get_father()
{
00D814A0  push        ebp 
00D814A1  mov         ebp,esp      #保存esp
00D814A3  push        0FFFFFFFFh   #构建SEH链表,-1是结尾 位置:ebp-4
                      #异常处理程序入栈,函数名是系统随机生成的 位置:ebp-8
00D814A5  push        offset __ehhandler$?get_father@@YA?AVfather@@XZ (0D84D97h)
00D814AA  mov         eax,dword ptr fs:[00000000h]  #把TEB里老的SEH放入eax
00D814B0  push        eax          #入栈 位置:ebp-0Ch
00D814B1  sub         esp,0E4h     #申请栈空间 执行后esp等于 ebp-F0h
00D814B7  push        ebx 
00D814B8  push        esi 
00D814B9  push        edi 
00D814BA  lea         edi,[ebp-0F0h]  #把上面的地址给edi,和下3句一起初始化申请的栈
00D814C0  mov         ecx,39h 
00D814C5  mov         eax,0CCCCCCCCh 
00D814CA  rep stos    dword ptr es:[edi] 
00D814CC  mov         eax,dword ptr [___security_cookie (0D8801Ch)]  #获取安全cookie
00D814D1  xor         eax,ebp 
00D814D3  push        eax              #跟ebp异或后的值保存在栈里 ebp-100h
00D814D4  lea         eax,[ebp-0Ch]    #eax=ebp-0Ch
00D814D7  mov         dword ptr fs:[00000000h],eax  #把栈地址设置到TEB首4字节里
00D814DD  mov         dword ptr [ebp-0ECh],0      #用于判断的参数
    father fa;
00D814E7  lea         ecx,[ebp-20h]  #类对象首地址
00D814EA  call        father::father (0D81078h)  #调用构造函数
00D814EF  mov         dword ptr [ebp-4],1        #开启异常捕获
    fa.set_val3(0x10);
00D814F6  push        10h            #调用成员函数
00D814F8  lea         ecx,[ebp-20h] 
00D814FB  call        father::set_val3 (0D81037h) 
    return fa;
00D81500  lea         eax,[ebp-20h] 
00D81503  push        eax                        #函数内类对象地址作为参数入栈
00D81504  mov         ecx,dword ptr [ebp+8]     
                      #调用myfa的构造 注意这个构造不是默认构造函数,而是复制构造函数 
00D81507  call        father::father (0D8101Eh) 
00D8150C  mov         ecx,dword ptr [ebp-0ECh]  
00D81512  or          ecx,1                     
00D81515  mov         dword ptr [ebp-0ECh],ecx   #把[ebp-0ECh]的值置为一 00D8151B  mov         byte ptr [ebp-4],0         #关闭异常捕获
00D8151F  lea         ecx,[ebp-20h]              #函数内部对象析构
00D81522  call        father::~father (0D810CDh) 
00D81527  mov         eax,dword ptr [ebp+8]      #返回值是myfa的地址
}
00EC1842  push        edx      #检查栈参数
00EC1843  mov         ecx,ebp 
00EC1845  push        eax 
00EC1846  lea         edx,[ (0EC1868h)] 
00EC184C  call        @ILT+155(@_RTC_CheckStackVars@8) (0EC10A0h) 
00EC1851  pop         eax 
00EC1852  pop         edx 
00EC1853  pop         edi 
00EC1854  pop         esi 
00EC1855  pop         ebx 
00EC1856  add         esp,0E4h 
00EC185C  cmp         ebp,esp  #检查栈esp
00EC185E  call        @ILT+350(__RTC_CheckEsp) (0EC1163h) 
00EC1863  mov         esp,ebp 
00EC1865  pop         ebp 
00EC1866  ret 
拷贝构造函数:
father::father:
00EC17AC  mov         eax,dword ptr [this]    #this指针依旧是放在ecx里
00EC17AF  mov         ecx,dword ptr [__that]  #__that指针是参数ebp+8
00EC17B2  mov         edx,dword ptr [ecx+4] 
00EC17B5  mov         dword ptr [eax+4],edx
#总结:其实是把类地址当参数传进去,然后在函数里先构造一个,最后调用复制构造函数把成员值全部拷贝过来
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值