- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
一、MASM宏编程解析
示例代码1:寄存器保存与运算宏
SAVEREG MACRO
push eax
push ecx
... ; 保存所有通用寄存器
ENDM
ADDREG MACRO num1, num2
mov eax, num1
add eax, num2
ENDM
main proc
SAVEREG
ADDREG 1, 2
ret
main endp
关键知识点
-
宏的作用
SAVEREG
:保存所有通用寄存器(eax
,ecx
,edx
等),常用于函数入口保存上下文。ADDREG
:将两个操作数相加,结果存入eax
。
-
堆栈平衡问题
- 错误分析:示例中
SAVEREG
压入8个寄存器(32字节),但未通过pop
恢复,导致ret
执行时堆栈指针(ESP)错误,程序崩溃。 - 修正方法:
RESTOREREG MACRO pop edi pop esi ... ; 逆序恢复寄存器 ENDM main proc SAVEREG ADDREG 1, 2 RESTOREREG ret main endp
- 优化方案:使用
pushad
/popad
指令一键保存/恢复所有寄存器。
- 错误分析:示例中
-
宏的局限性
- 参数类型需明确:
ADDREG
假设num1
和num2
为立即数,若传递内存地址需用[]
解引用。
- 参数类型需明确:
二、Windows API调用深度剖析
示例代码2:MessageBoxA调用
#include <Windows.h>
int main() {
MessageBoxA(0, "Hello", "0xCC", MB_ABORTRETRYIGNORE);
return 0;
}
关键知识点
-
API函数原型
- 参数约定:
MessageBoxA
使用stdcall
调用约定,参数从右向左入栈,由被调用方清理堆栈。 - 参数详解:
hWnd
: 父窗口句柄,0
表示无父窗口。lpText
: 消息内容(LPCSTR类型,ANSI字符串)。lpCaption
: 标题(同上)。uType
: 按钮类型,如MB_ABORTRETRYIGNORE
(0x00000002)。
- 参数约定:
-
MASM中调用API
- 声明与链接:
; 声明API函数 MessageBoxA PROTO STDCALL :DWORD, :DWORD, :DWORD, :DWORD includelib user32.lib ; 链接库文件
- 参数传递:
main proc push MB_ABORTRETRYIGNORE ; uType push offset Caption ; lpCaption push offset Text ; lpText push 0 ; hWnd call MessageBoxA ret main endp
- 简化指令:使用
invoke
自动处理参数顺序和堆栈平衡:invoke MessageBoxA, 0, offset Text, offset Caption, MB_ABORTRETRYIGNORE
- 声明与链接:
-
逆向工程中的识别
- 参数布局:通过
push
指令顺序可判断参数传递顺序。 - 调用约定:若返回地址后堆栈由被调用方清理,则为
stdcall
。
- 参数布局:通过
三、拓展知识点
-
x86调用约定对比
约定 参数传递 堆栈清理 典型应用 cdecl 右到左,栈 调用方 C语言函数 stdcall 右到左,栈 被调用方 Windows API fastcall 寄存器和栈 被调用方 性能敏感场景 -
逆向工程技巧
- 寄存器跟踪:观察
eax
存储返回值,esp
变化判断堆栈平衡。 - 字符串定位:在.data段查找硬编码字符串(如"Hello"),快速定位关键代码。
- API断点:通过
bp MessageBoxA
设置断点,分析调用上下文。
- 寄存器跟踪:观察
-
异常处理
- 调用API后检查返回值(如
eax
是否为0),结合GetLastError
诊断错误。
- 调用API后检查返回值(如