Windows逆向工程入门之MASM过程调用机制深度解析
- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
一、过程入口控制与栈帧管理:从ENTRY到LEAVE
1.1 栈帧构建的机器级实现
二、高级过程调用机制:INVOKE与PROTO的逆向对抗
2.1 调用约定的二进制指纹
2.2 PROTO的类型安全验证
三、过程环境控制:USES与LOCAL的深层安全考量
3.1 寄存器保护机制(USES)
3.2 局部变量布局优化
四、地址操作符:ADDR与OFFSET的二进制差异
4.1 操作符语义解析
一、过程入口控制与栈帧管理:从ENTRY到LEAVE
1.1 栈帧构建的机器级实现
main proc
enter 8, 0 ; 等价于:
; push ebp (55)
; mov ebp, esp (8B EC)
; sub esp, 8 (83 EC 08)
leave ; mov esp, ebp (8B E5)
; pop ebp (5D)
ret
逆向工程特征识别:
- 黄金三指令序列:55 8B EC 83 EC XX(PUSH EBP/MOV EBP,ESP/SUB ESP,X)
- 栈指纹分析:OllyDbg的栈窗口显示EBP链式结构
- 异常处理关联:
_EXCEPTION_REGISTRATION_RECORD
结构中的栈范围验证
二、高级过程调用机制:INVOKE与PROTO的逆向对抗
2.1 调用约定的二进制指纹
; stdcall调用示例
INVOKE MessageBoxA, 0, OFFSET Text, OFFSET Caption, MB_OK
机器码特征:
6A 00 push 0 ; MB_OK
68 00 40 40 00 push offset Caption
68 00 40 40 00 push offset Text
6A 00 push 0
FF 15 00 40 40 00 call [MessageBoxA]
调用约定识别矩阵:
特征 | stdcall | cdecl | fastcall |
---|---|---|---|
参数清理方 | 被调用方 | 调用方 | 被调用方 |
寄存器参数 | 无 | 无 | ECX/EDX |
典型返回指令 | RET N | RET | RET |
2.2 PROTO的类型安全验证
Swap PROTO :DWORD, :DWORD ; 参数类型声明
链接期验证机制:
- 参数数量匹配检查(通过符号修饰差异实现)
- 参数大小验证(DWORD(4) vs WORD(2))
- 调用约定一致性(stdcall vs __cdecl修饰差异)
三、过程环境控制:USES与LOCAL的深层安全考量
3.1 寄存器保护机制(USES)
ArraySum PROC USES ESI ECX ; 生成代码:
push esi ; 56
push ecx ; 51
...
pop ecx ; 59
pop esi ; 5E
安全开发实践:
- 易失性寄存器标记:明确区分调用者保存和被调用者保存寄存器
- 中断上下文保护:在ISR中必须保存所有使用寄存器
逆向反制技术:
- 寄存器差异分析:对比函数入口/出口的寄存器值变化
3.2 局部变量布局优化
LOCAL var1:BYTE, arr[10]:DWORD ; 栈布局:
; EBP-1 : BYTE var1
; EBP-4 : (3字节填充)
; EBP-8 : DWORD arr[0]
; EBP-48 : DWORD arr[9]
漏洞模式检测:
- 负偏移访问:
mov eax, [ebp-0x100]
(可能越界) - 数组越界:
arr[11]
访问破坏返回地址 - 初始化使用:
mov eax, [ebp-4]
未赋初值
四、地址操作符:ADDR与OFFSET的二进制差异
4.1 操作符语义解析
操作符 | 作用域 | 生成指令 | 适用场景 |
---|---|---|---|
OFFSET | 全局变量 | MOV EAX, 00400000 | 数据段静态地址 |
ADDR | 局部变量 | LEA EAX, [EBP-4] | 栈/堆动态地址 |
PTR | 类型转换 | WORD PTR [EAX] | 内存解释方式修改 |