反汇编心得

看汇编代码时一定要牢牢把握栈的变化情况,脑里浮现栈帧图,并时刻跟踪ESP,这样会更容易读懂汇编。

下面是函数调用时callee要做的事情(被调用者负责平衡堆栈: 分配和释放栈空间),所有的函数本质上都是callee,由别的函数调用指行,包括main函数:

1. 保存旧的帧指针(把新的栈帧链接到栈帧链表中)
其实栈被分成一个个连续的栈帧(由于函数调用的原因),这些栈帧就像链表一样被EBP链接了起来,每次被调用函数callee要做的第一件事情就是把新的栈帧链接到原来的栈帧链表上,即汇编代码:
 push ebp
把EBP的值压栈,而EBP恰是caller函数的帧指针,这就相当于挂接到栈帧链表上。

2. 建立新的帧指针
 mov  ebp , esp

3. 分配新的栈空间
sub esp , 0xC0h

4. 把寄存器压栈
push ebx
push esi
push edi

5. 初始化栈空间
初始化栈空间为0xCCh,0xCCh是汇编指令int 3的二进制码,便于中断纠错。
lea edi , [ebp - 0xC0h]
mov ecx , 30h  ;长度,30h * 4 = 0xC0h
mov eax , 0xCCCCCCCCh
rep stosd

6. 执行函数的算法代码

7. 平衡堆栈:弹出保存的寄存器,恢复栈空间,恢复被保存的EBP,即从栈帧链表中删除callee的栈帧。
pop edi
pop esi
pop ebx
mov esp , ebp ;恢复栈空间,重置栈顶esp, 此时esp = ebp = 旧的ebp
pop ebp ;恢复旧的EBP,即把新的栈帧从栈帧链表中删除了,此时esp指向被保存的函数返回地址,即call之后的地址
retn  ; 函数返回,此指令相当于pop eip,把esp指向的函数返回地址赋值给EIP

栈帧结构图:


posted on 2013-03-16 15:09 挑灯看剑 阅读(425) 评论(0)  编辑 收藏 引用 所属分类: 工作随笔汇编艺术

只有注册用户登录后才能发表评论。
<2018年9月>
2627282930311
2345678
9101112131415
16171819202122
23242526272829
30123456

导航

公告

【自我介绍】 08年南开大学硕士毕业 最近关注:算法、Linux、c++、高并发 爱好:滑旱冰、打乒乓球、台球、保龄球

常用链接

随笔分类(139)

文章分类

我常去的网站

技术博客(都是大牛)

技术站点

搜索

积分与排名