一个简单的C++程序反汇编解析1Word格式文档下载.docx
- 文档编号:3599173
- 上传时间:2023-05-02
- 格式:DOCX
- 页数:10
- 大小:17.80KB
一个简单的C++程序反汇编解析1Word格式文档下载.docx
《一个简单的C++程序反汇编解析1Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《一个简单的C++程序反汇编解析1Word格式文档下载.docx(10页珍藏版)》请在冰点文库上搜索。
a_class.method(10);
return0;
可以直接debug的时候看到assembly代码,不过这样获得的代码注释比较少。
比较理想的方法是利用vc编译器的一个选项/fas来生成对应的汇编代码。
/fas还会在汇编代码中加入注释注明和c++代码的对应关系,十分有助于分析。
build代码便可以在输出目录下发现对应的.asm文件。
本文将逐句分析汇编代码和c++的对应关系。
首先是winmain:
_textsegment
_wmain
proc
push
ebp
;
保存旧的ebp
mov
ebp,esp
ebp保存当前栈的位置
-1
建立seh(structuredexceptionhandler)链
-1表示表头,没有prev
__ehhandler$_wmain
seh异常处理程序的地址
eax,dwordptrfs:
0
fs:
0指向teb的内容,头4个字节是当前seh链的地址
eax
保存起来
sub
esp,d8h
分配d8h字节的空间
ebx
esi
edi
lea
edi,dwordptr[ebp-e4h]
e4h=d8h+4*3,跳过中间ebx,esi,edi
ecx,36h
36h*4h=d8h,也就是用36h个cccccccch填满刚才分配的d8h字节空间
eax,cccccccch
repstosd
eax,dwordptr___security_cookie
xor
eax,ebp
ebp^__security_cookie压栈保存
eax,dwordptr[ebp-0ch]
ebp-0ch是新的seh链的结构地址(刚压入栈中的栈地址)
dwordptrfs:
0,eax
设置到teb中作为当前active的seh链表末尾
到此为止栈的内容是这样的:
低地址
securitycookieafterxor
localstack:
d8h
oldfs:
__ehhandler$_wmain
ffffffffh
oldebp
高地址
main接着后面调用my_class的构造函数
ecx,dwordptr[ebp-14h]
call
?
0my_class@@qae@xz
调用my_class:
:
my_class,?
my_class@@qae@xz是经过namemangling后的名字
mov
dwordptr[ebp-4],0
进入__try块,在main中有一个隐式的__try/__except块
接着调用my_class:
method
10
参数入栈
ecx,dwordptr[ebp-14h]
遵循thiscall调用协定,ecx存放的是this指针
call
method@my_class@@qaexh@z
调用子程序my_class:
method(10)
之后是析构:
dwordptr[ebp-e0h],0
用来放置返回值
dwordptr[ebp-4],-1
标记try的正常结束
a_class的地址作为this存入ecx
1my_class@@qae@xz
my_class:
~my_class
eax,dwordptr[ebp-e0h]
返回值按照约定放入eax中
main函数退出代码如下:
edx
ecx,ebp
eax
edx,dwordptr$ln7@wmain
@_rtc_checkstackvars@8
检查栈
pop
eax
edx
ecx,dwordptr[ebp-0ch]
取出之前保存的旧的fs:
0,并恢复
0,ecx
ecx
edi
esi
ebx
add
esp,e4h
退掉分配的d8h+建立seh链所需的0ch字节
cmp
ebp,esp
__rtc_checkesp
检查esp值,这个时候esp应该和ebp匹配,否则说明出现了栈不平衡的情况,这种情况下调用子程序报错
esp,ebp
恢复ebp到esp
ebp
恢复原来的ebp值
ret
0
endp
专门用于seh的子程序。
__unwindfunclet$_wmain$0当异常发生的时候被调,负责进行栈展开,主要是调用析构函数。
__ehhandler$_wmain则是在exception被抛出的时候调用。
text$x
segment
__unwindfunclet$_wmain$0:
当seh发生的时候会调用该函数,析购a_class
ecx=[ebp–14h],也就是a_class的地址
jmp
?
__ehhandler$_wmain:
edx,dwordptr[esp+8]
esp=当前的fs:
0,[esp+8]=之前的seh结构,也就是main中建立的
eax,dwordptr[edx+0ch]
edx+0ch=当前的ebp,也就是main的ebp,此时不能直接使用ebp因为可能会从任意函数调过来,此时ebp是该函数的ebp,而不是main的ebp
ecx,dwordptr[edx-e0h]
之前存下去的__security_cookie^ebp
ecx,eax
再次和ebp相异或
@__security_check_cookie@4
此时ecx应该等于__security_cookie,否则说明栈的内容被恶意改动(或者编程错误)
eax,offset__ehfuncinfo$_wmain
___cxxframehandler3
ends
my_class:
my_class构造函数如下。
构造函数本质上就是一个全局函数,名字是经过打乱的(namemangling),这样可以和同一class和其他class的同名方法区别开来。
不同编译器有不同规则,因此不必过于深究。
0my_class@@qae@xzproc
esp,cch
给栈分配cch个字节
ebx
保存常用寄存器
ecx
edi,dwordptr[ebp-cch]
从分配的位置开始
ecx,33h
写33h个cccccccch
eax,cccccccch
也就是33h*4h=cch,正好是分配的大小
repstosd
从而把整个栈上当前分配的空间用cch填满
dwordptr[ebp-8],ecx
按照约定,一般用ecx保存this指针
把this存入到ebp-8,并不是很必要,因为这是debug版本
;
10
:
11
eax,dwordptr[ebp-8]
eax中存放this
dwordptr[eax],1
this的头四个byte是m_member的内容
12
多余的一句话,可以优化掉
恢复esp,因此就算是中间栈运算出错,最后也不会导致灾难性的结果,只要ebp还是正确的
ebp
0my_class@@qae@xzendp
method的实现如下:
method@my_class@@qaexh@zproc
15
ebp
esp,cch
edi,dwordptr[ebp-cch]
ecx,33h
dwordptr[ebp-8],ecx
16
ecx,dwordptr[ebp+8]
ebp->
ebp+4->
ip
ebp+8->
n
把n存入ecx中
dwordptr[eax],ecx
this头四个字节是m_member,因此这句话就是m_member=n
17
esp,ebp
4
等价于
ret恢复eip,返回调用地址
addesp,4->
把n从栈上pop掉
method@my_class@@qaexh@zendp
最后的析构函数,和前面的代码并无区别。
1my_class@@qae@xzproc
20
esp,204
edi,dwordptr[ebp-204]
dwordptr_this$[ebp],ecx
21
eax,dwordptr[ebp-8]
dwordptr[eax],0
22
1my_class@@qae@xzendp
_textends
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 一个 简单 C+ 程序 汇编 解析
![提示](https://static.bingdoc.com/images/bang_tan.gif)