函数的开始和结束标志

.text:00401010 ; void *__thiscall CtmpApp___vector deleting destructor_(CtmpApp *this, unsigned int)
.text:00401010 ??_ECtmpApp@@UAEPAXI@Z proc near        ; DATA XREF: .rdata:004034D8o
.text:00401010
.text:00401010 arg_0           = byte ptr  8
.text:00401010
.text:00401010 this = ecx
.text:00401010                 push    ebp
.text:00401011                 mov     ebp, esp
.text:00401013                 push    esi
.text:00401014                 mov     esi, this
.text:00401016                 call    ds:__imp_??1CWinApp@@UAE@XZ ; CWinApp::~CWinApp(void)
.text:0040101C                 test    [ebp+arg_0], 1
.text:00401020                 jz      short loc_40102C
.text:00401022                 push    esi
.text:00401023                 call    ds:__imp_??3@YAXPAX@Z ; operator delete(void *)
.text:00401029                 add     esp, 4
.text:0040102C
.text:0040102C loc_40102C:                             ; CODE XREF: CtmpApp::`vector deleting destructor'(uint)+10j
.text:0040102C                 mov     eax, esi
.text:0040102E                 pop     esi
.text:0040102F                 pop     ebp
.text:00401030                 retn    4
.text:00401030 ??_ECtmpApp@@UAEPAXI@Z endp

先不说别的,随便贴一段反汇编代码,然后进行分析:

可以看到,一般而言函数都是以

push ebp;

mov  ebp,esp;

开始的因为在函数内部要使用局部变量,而所有的变量都是要有地址记录的,所以要使用ebp,而在新的函数使用ebp之前要压入堆栈,否则会导致父函数崩溃,使用之前先将

其保存到堆栈当中,同时因为esp是指向栈顶的,其次mov ebp,esp是要将之前的栈顶变栈底,因为之后根据函数内部的局部变量的分配,esp不断减小,所以要将函数调用之

前的内容保存起来,也就是,当前函数的起始地址,之后的函数局部变量要在esp之后,随着函数内部变量的不断分配,同时esp的值也会不断减小,我们会看到,在该函数内

部,push和pop并不是成对出现的,但是在

.text:00401022 push esi;

.text:00401023 call ds:operator delete(void*);

这是一步函数调用,push  esi为函数 delete提供参数,在该函数完成后,会自行弹出esi的值,

.text:00401013 push esi;压入堆栈,使用完毕后,在

.text:0040102E pop esi;  弹出堆栈,恢复之前的现场

该函数执行完毕后,.text 将 在函数使用之前压入堆栈的栈顶地址弹出到ebp当中,然后 retn 4说明函数执行完毕,4表示在该函数中弹出4个字节,可能该函数中有占据4个字节

的参数。

所以 函数执行完毕有两种:

pop ebp;                                                                                                      mov esp,ebp;

add esp,64h;//将之前的压入堆栈的空间收回                                         pop ebp;

retn                                                                                                                    retn

函数在执行完毕后通过将堆栈的指针向下移动,恢复ebp,而关闭堆栈,对应之前的mov ebp,esp;打开堆栈,或者通过esp的增加实现关闭堆栈的同样效果。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世纪殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值