[逆向工程]Windows 下逆向分析修改“Hello, World!”程序
在软件开发和安全领域,逆向工程是一个极具挑战性和趣味性的技术。通过逆向分析,我们可以深入了解程序的内部结构和运行机制,这对于学习编程、调试软件以及分析恶意软件等方面都有着重要的意义。本文将以一个简单的“Hello, World!”程序为例,介绍如何在 Windows 环境下进行逆向分析。
一、实验环境准备
1.1 开发工具
- Visual Studio Code:一款轻量级且功能强大的代码编辑器,支持多种编程语言。
- MinGW :提供 GCC 编译器,用于编译 C 程序。
- IDA Pro:专业的逆向工程工具,用于分析可执行文件。
- DIE : 查壳工具。
1.2 实验步骤
- 使用 Visual Studio Code 编写一个简单的“Hello, World!”程序。
- 使用 MinGW 编译程序,生成可执行文件。
- 使用DIE查壳。
- 使用 IDA Pro 对生成的可执行文件进行逆向分析。
二、编写“Hello, World!”程序
2.1 代码实现
在 Visual Studio Code 中创建一个名为 hello.c
的文件,并输入以下代码:
// hello.c
#include <windows.h> // 包含 Windows API 的头文件
int main() {
// 使用 MessageBox 函数弹出对话框
MessageBox(NULL, "Hello, World!", "My First MessageBox", MB_OK | MB_ICONINFORMATION);
return 0;
}
编写程序:
2.2 编译程序
在 VSCode 的终端中,运行以下命令编译程序或点击工具编译按钮编译:
gcc hello.c -o hello.exe
如果编译成功,当前目录下会生成一个名为 hello.exe
的可执行文件。
编译成功运行弹出运行,弹出框内容为“Hello, World!”:
三、逆向分析工具介绍
3.1 IDA Pro
IDA Pro 是一款功能强大的逆向工程工具,广泛应用于软件开发和安全领域。它提供了丰富的分析功能,包括代码反汇编、伪代码生成、函数调用图等。
3.2 DIE
Detect It Easy(简称 DIE)是一款功能强大的文件分析工具,专为开发者、逆向工程师和安全专家设计,旨在快速识别可执行文件和库的类型及其详细信息。它能够分析多种文件格式,包括可执行文件(EXE)、动态链接库(DLL)、脚本文件和图像文件,提供有关文件版本、依赖关系、资源和签名的信息。
四、逆向分析修改弹出框内容过程
修改目标:将弹出框内容“Hello, World!”修改为“mandao World!”
4.1 查壳
使用DIE查壳,hello.exe为无壳程序。查壳去壳可浏览博主以下文章,此处只是简单展示。
相关链接:查壳脱壳
4.2 使用 IDA Pro 分析
- 打开 IDA Pro,选择
File
> open ,加载hello.exe
文件。 - IDA Pro 会自动对程序进行分析,并生成反汇编代码。
- 在反汇编窗口中,可以看到程序的入口点(通常是
main
函数)。 - 双击入口点地址,查看
main
函数的反汇编代码。
4.3 分析反汇编代码
以下是 main
函数的反汇编代码示例:
反汇编代码如下所示:
.text:0000000140001460 public main
.text:0000000140001460 main proc near ; CODE XREF: __tmainCRTStartup+164↑p
.text:0000000140001460 ; DATA XREF: .pdata:000000014000506C↓o
.text:0000000140001460 push rbp
.text:0000000140001461 mov rbp, rsp
.text:0000000140001464 sub rsp, 20h
.text:0000000140001468 call __main
.text:000000014000146D mov r9d, 40h ; '@' ; uType
.text:0000000140001473 lea r8, Caption ; "My First MessageBox"
.text:000000014000147A lea rax, Text ; "Hello, World!"
.text:0000000140001481 mov rdx, rax ; lpText
.text:0000000140001484 mov ecx, 0 ; hWnd
.text:0000000140001489 mov rax, cs:__imp_MessageBoxA
.text:0000000140001490 call rax ; __imp_MessageBoxA
.text:0000000140001492 mov eax, 0
.text:0000000140001497 add rsp, 20h
.text:000000014000149B pop rbp
.text:000000014000149C retn
.text:000000014000149C main endp
4.4 关键点分析
- 代码解释:
.text:0000000140001460 public main
- 这一行声明了
main
函数是一个公共符号,意味着它可以在其他地方被引用。
.text:0000000140001460 main proc near ; CODE XREF: __tmainCRTStartup+164↑p
- 这是
main
函数的开始,proc near
表示这是一个近过程(near procedure),即函数调用不会跨越太远的地址空间。
.text:0000000140001460 ; DATA XREF: .pdata:000000014000506C↓o
- 这是一个注释,说明在
.pdata
段中有对这个地址的引用,这通常用于异常处理。
.text:0000000140001460 push rbp
- 将基指针寄存器
rbp
的值压入栈中。这是函数序言(prologue)的一部分,用于保存调用者的基指针。
.text:0000000140001461 mov rbp, rsp
- 将栈指针
rsp
的值移动到基指针rbp
中,用于设置当前函数的栈帧。
.text:0000000140001464 sub rsp, 20h
- 从栈指针
rsp
中减去20h
(32 字节),为局部变量分配空间。
.text:0000000140001468 call __main
- 调用
__main
函数,这是一个运行时初始化函数,通常由 C 运行时库提供,用于初始化程序。
.text:000000014000146D mov r9d, 40h ; '@' ; uType
- 将
40h
(十六进制,等于十进制的 64)移动到寄存器r9d
中。40h
是MB_OK | MB_ICONINFORMATION
的值,表示对话框有一个“确定”按钮并显示一个信息图标。
.text:0000000140001473 lea r8, Caption ; "My First MessageBox"
- 使用
lea
(Load Effective Address)指令将Caption
的地址加载到寄存器r8
中。Caption
是对话框的标题。
.text:000000014000147A lea rax, Text ; "Hello, World!"
- 将
Text
的地址加载到寄存器rax
中。Text
是对话框中显示的文本。
.text:0000000140001481 mov rdx, rax ; lpText
- 将
rax
的值(Text
的地址)移动到寄存器rdx
中,rdx
是MessageBoxA
函数的第三个参数,表示对话框中显示的文本。
.text:0000000140001484 mov ecx, 0 ; hWnd
- 将
0
移动到寄存器ecx
中,ecx
是MessageBoxA
函数的第一个参数,表示父窗口的句柄。0
表示没有父窗口。
.text:0000000140001489 mov rax, cs:__imp_MessageBoxA
- 将
MessageBoxA
函数的地址加载到寄存器rax
中。__imp_MessageBoxA
是MessageBoxA
函数的导入地址。
.text:0000000140001490 call rax ; __imp_MessageBoxA
- 调用
MessageBoxA
函数,弹出对话框。
.text:0000000140001492 mov eax, 0
- 将
0
移动到寄存器eax
中,表示函数的返回值。
.text:0000000140001497 add rsp, 20h
- 将栈指针
rsp
加上20h
,释放之前分配的局部变量空间。
.text:000000014000149B pop rbp
- 从栈中弹出基指针
rbp
的值,恢复调用者的栈帧。
.text:000000014000149C retn
- 返回到调用者。
.text:000000014000149C main endp
- 这是
main
函数的结束。
-
字符串存储:
- 字符串 “Hello, World!” 通常存储在程序的
.data
段或.rodata
段中。
- 字符串 “Hello, World!” 通常存储在程序的
五,使用 IDA十六进制窗口进行修改
1.在线将mandao字符串转为16进制,转换后为6D616E64616F
2.找到十六进制窗口选择修改字符串,按F2进行修改,输入mandao字符串的16进制
3.修改后进行保存
六、总结
通过本文的介绍,我们了解了如何在 Windows 环境下使用 IDA Pro 对一个简单的“Hello, World!”程序进行逆向分析。逆向工程不仅可以帮助我们学习程序的内部结构,还可以用于调试软件和分析恶意软件。希望本文对你有所帮助,如果你对逆向工程感兴趣,可以进一步学习更复杂的程序分析和调试技术。
如果本教程对您有帮助,请点赞❤️收藏⭐关注支持!欢迎在评论区留言交流技术细节!欲了解更深密码学知识,请订阅《密码学实战》专栏 → 密码学实战