Windows逆向工程入门之汇编开发框架解析
- 公开视频 -> 链接点击跳转公开课程
- 博客首页 -> 链接点击跳转博客主页
目录
环境搭建与配置
Visual Studio配置
X86汇编基础框架
基本程序框架
数据定义与内存访问
过程(函数)定义
汇编框架解析
代码主体解析
完整代码执行
代码逻辑流程
汇编代码段组织
环境搭建与配置
Visual Studio配置
1. 创建新项目:
File -> New -> Project -> Empty Project
2. 配置MASM支持:
Project -> Build Customizations -> 勾选masm(.targets)
3. 添加汇编文件:
Solution Explorer -> Add -> New Item -> .asm file
X86汇编基础框架
基本程序框架
.386
.model flat, stdcall
option casemap :none
ExitProcess PROTO STDCALL :DWORD
MessageBoxA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
.const
MB_OK EQU 0
NULL EQU 0
.data
msgText db "Hello Assembly!", 0
msgTitle db "Message", 0
.data?
buffer db 100 dup(?)
.code
main PROC
invoke MessageBoxA, NULL, offset msgText, offset msgTitle, MB_OK
invoke ExitProcess, 0
main ENDP
end main
end
数据定义与内存访问
.data
; 基本数据类型
byte_var db 10 ; 8位
word_var dw 1000h ; 16位
dword_var dd 12345678h ; 32位
qword_var dq 1234567812345678h ; 64位
; 数组定义
byte_array db 10 dup(0) ; 10字节数组
word_array dw 5 dup(?) ; 5个字未初始化
; 字符串
str1 db "Hello", 0 ; C风格字符串
str2 db 'World', 13, 10, 0 ; 带换行符
过程(函数)定义
.code
; 标准过程定义
StandardProc PROC
push ebp ; 保存调用者的栈基址
mov ebp, esp ; 设置新的栈基址
; 函数体
mov esp, ebp ; 恢复栈指针
pop ebp ; 恢复调用者的栈基址
ret ; 返回
StandardProc ENDP
; 带参数的过程
ParamProc PROC param1:DWORD, param2:DWORD
; 访问参数
mov eax, param1
mov ebx, param2
ret
ParamProc ENDP
汇编框架解析
代码主体解析
.386
.model flat, stdcall
option casemap :none
-
.386
:- 指定代码适用于 80386 指令集(支持32位操作)。
- x86结构指令集一般从 80386 开始全面支持32位操作。
-
.model flat, stdcall
:- flat: 使用平坦内存模型,所有地址空间共享一个线性内存块(通常用于现代操作系统)。
- stdcall: 调用约定,参数从右到左压栈,由被调用函数负责清理栈。
-
option casemap :none
:- 禁用大小写不敏感的行为(汇编语言默认不区分大小写)。
- 在
casemap
被禁用后,变量、函数名需大小写完全一致。
ExitProcess PROTO STDCALL :DWORD
MessageBoxA PROTO STDCALL :DWORD,:DWORD,:DWORD,:DWORD
-
函数声明(PROTO):
- 定义和声明外部函数的接口,告诉编译器如何调用这些函数及其参数类型。
- ExitProcess: 用于退出当前进程。
- 参数:
DWORD
:退出代码。
- 参数:
- MessageBoxA: 显示一个带标题、内容和按钮的消息框。
- 参数:
DWORD hWnd
(父窗口句柄),DWORD lpText
(消息内容的地址),DWORD lpCaption
(标题内容地址),DWORD uType
(按钮类型)。
- 参数:
-
调用约定:
STDCALL
调用约定,遵循特定的调用与栈清理规则:- 参数从右到左入栈。
- 被调用函数负责栈的清理。
.const
MB_OK EQU 0
NULL EQU 0
const
段:- 定义常量,编译时会将常量替换为其对应值。
- MB_OK:
MessageBox
按钮类型,0
指定显示一个确认按钮 “确定”。 - NULL:空指针,表示0值。
.data
msgText db "Hello Assembly!", 0
msgTitle db "Message", 0
.data
段:- 定义已初始化的全局或静态变量,比如字符串。
msgText
和msgTitle
:- 定义了两个以 NULL 结尾的C风格字符串。
db
(Define Byte) 表示 1 字节定义,0
表示字符串结束标记。
.data?
buffer db 100 dup(?)
.data?
段:- 定义未初始化的全局或静态变量。
buffer
:- 分配固定空间,大小为100字节。
dup(?)
表示分配未初始化的空间。
.code
main PROC
.code
段:- 定义程序的代码段,所有指令从这里开始。
main PROC
:- 定义
main
过程(过程类似函数),它是程序的入口点。
- 定义
invoke MessageBoxA, NULL, offset msgText, offset msgTitle, MB_OK
invoke ExitProcess, 0
-
invoke
指令:- 汇编语言的高级指令,用于简化函数调用。
invoke
程序会自动处理参数压栈与调用,并根据声明推断函数签名。
-
调用 MessageBoxA:
- 参数:
NULL
:无父窗口(显示独立消息框)。offset msgText
:msgText
的地址指针,作为消息内容。offset msgTitle
:msgTitle
的地址指针,作为标题。MB_OK
:设定按钮样式为 “确定”。
- 参数:
-
调用 ExitProcess:
- 参数:
0
:进程退出码,表示正常退出。
- 参数:
main ENDP
end main
ENDP
:- 结束
main
过程,标志主程序结束。
- 结束
完整代码执行
代码逻辑流程
- 程序从
.code
段的main
函数开始执行。 - 通过
invoke MessageBoxA
显示一个消息框:- 内容为
Hello Assembly!
。 - 标题为
Message
。
- 内容为
- 消息框关闭后,调用
ExitProcess
退出程序。
汇编代码段组织
段名 | 描述 |
---|---|
.386 | 指定指令集架构(支持x86 32位指令)。 |
.model flat, stdcall | 指定内存模型为“平坦”、调用约定为“stdcall”。 |
段名 | 作用 | 示例 |
---|---|---|
.const | 定义只读常量 | MB_OK EQU 0 |
.data | 定义已初始化的全局变量或数据 | msgText db "Hello",0 (ASCII字符串必须以0结尾) |
.data? | 定义未初始化数据(运行时填充零值) | buffer db 100 dup(?) (保留100字节空间) |
.code | 程序代码段 | main PROC 和 main ENDP 定义主过程 |