- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
Windows逆向工程入门:栈指令与核心机制深度解析
一、栈的核心概念与内存布局
二、栈操作指令详解
1. PUSH 与 POP
2. PUSHA/PUSHAD 与 POPA/POPAD
3. PUSHF/PUSHFD 与 POPF/POPFD
4. CALL 与 RET
三、进阶知识点拓展
1. 调用约定(Calling Convention)
2. 栈溢出与安全防护
3. 调试实战:观察栈操作
Windows逆向工程入门:栈指令与核心机制深度解析
一、栈的核心概念与内存布局
栈(Stack) 是程序运行时内存中的一块线性区域,其操作遵循 LIFO(后进先出) 原则。在x86/x64架构中,栈向低地址方向增长,主要用于存储:
-
局部变量:函数内部定义的临时变量。
-
函数参数:调用函数时传递的参数(具体顺序由调用约定决定)。
-
返回地址:
CALL指令执行后保存的下一条指令地址。 -
保存的寄存器值:如通过
PUSH或PUSHA保存的上下文。
关键寄存器:
-
ESP(栈指针):始终指向栈顶,直接反映当前栈操作位置。
-
EBP(基址指针):固定指向当前函数的栈帧基址,用于定位参数和局部变量(尤其在未优化代码中常见)。
栈帧结构示例:
高地址 +-----------------+ | 参数n | ← EBP + 8 | ... | | 参数1 | ← EBP + 4 | 返回地址 | ← EBP | 旧的EBP | ← EBP当前指向 | 局部变量1 | ← EBP - 4 | 局部变量2 | ← EBP - 8 | ... | 低地址 ← ESP
二、栈操作指令详解
1. PUSH 与 POP
-
操作流程:
-
PUSH src:ESP -= 4(x86)或RSP -= 8(x64),然后将src写入[ESP]。 -
POP dest:从[ESP]读取数据到dest,然后ESP += 4(x86)或RSP += 8(x64)。
-
-
关键用途:
-
函数调用时的参数传递(如
cdecl调用约定由调用者清理栈)。 -
保存/恢复寄存器:例如在函数开头
PUSH EBP保存旧基址。
-
-
栈对齐问题:
-
在64位程序中,某些API(如Windows API)要求栈按16字节对齐。若未对齐,可能导致崩溃。
-
示例:调用函数前手动调整
ESP或使用SUB ESP, 8对齐。
-
2. PUSHA/PUSHAD 与 POPA/POPAD
-
PUSHA:按顺序压入
AX, CX, DX, BX, SP, BP, SI, DI(16位)。 -
PUSHAD:压入32位寄存器
EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI。 -
注意:x64架构中不再支持
PUSHAD,需手动保存寄存器。
3. PUSHF/PUSHFD 与 POPF/POPFD
-
PUSHF:保存16位标志寄存器(FLAGS)。
-
PUSHFD:保存32位EFLAGS(包括进位标志CF、零标志ZF等)。
-
应用场景:在修改标志位的指令(如
STD设置方向标志)前保存状态。
4. CALL 与 RET
-
CALL指令:
-
隐式执行
PUSH EIP(将返回地址压栈),然后跳转到目标地址。 -
示例:
CALL 0x401000→ESP -=4,[ESP] = EIP,EIP = 0x401000。
-
-
RET指令:
-
弹出栈顶值到
EIP,继续执行。若带参数(如RET 8),则额外调整ESP(清理参数)。
-
三、进阶知识点拓展
1. 调用约定(Calling Convention)
-
cdecl:参数从右向左压栈,调用者清理栈(常见于C语言)。
-
stdcall:参数从右向左压栈,被调用者清理栈(Windows API常用)。
-
fastcall:部分参数通过寄存器传递(如ECX、EDX),剩余参数压栈。
2. 栈溢出与安全防护
-
栈溢出攻击原理:通过覆盖返回地址,控制程序执行流程(如经典缓冲区溢出)。
-
防护技术:
-
栈金丝雀(Canary):在栈帧中插入随机值,函数返回前检查其完整性。
-
DEP/NX:标记栈为不可执行,阻止Shellcode运行。
-
ASLR:随机化模块基址,增加预测地址难度。
-
3. 调试实战:观察栈操作
使用调试器(如x64dbg)分析以下代码:
; 函数调用示例 PUSH 3 ; 参数3 PUSH 2 ; 参数2 PUSH 1 ; 参数1 CALL func ADD ESP, 12 ; cdecl约定下调用者清理栈 func: PUSH EBP MOV EBP, ESP SUB ESP, 8 ; 分配局部变量空间 ... LEAVE ; 等同于 MOV ESP, EBP; POP EBP RET
-
断点分析:观察
CALL执行后栈的变化,LEAVE如何恢复栈帧。

















![[JVM篇]垃圾回收器](https://i-blog.csdnimg.cn/direct/f60003d790564fd7bb5388ed6e805ec2.png)
