好友
阅读权限 10
听众
最后登录 1970-1-1
本帖最后由 mandaono1 于 2025-4-28 09:35 编辑
小白帖,仅供个人研究!!!
Windows 下逆向分析修改“Hello, World!”程序
在软件开发和安全领域,逆向工程是一个极具挑战性和趣味性的技术。通过逆向分析,我们可以深入了解程序的内部结构和运行机制,这对于学习编程、调试软件以及分析恶意软件等方面都有着重要的意义。本文将以一个简单的“Hello, World!”程序为例,介绍如何在 Windows 环境下进行逆向分析。
一、实验环境准备
1.1 开发工具
- Visual Studio Code:一款轻量级且功能强大的代码编辑器,支持多种编程语言。
- MinGW :提供 GCC 编译器,用于编译 C 程序。
- IDA Pro:专业的逆向工程工具,用于分析可执行文件。
- DIE : 查壳工具。
1.2 实验步骤
1. 使用 Visual Studio Code 编写一个简单的“Hello, World!”程序。
2. 使用 MinGW 编译程序,生成可执行文件。
3. 使用DIE查壳。
4. 使用 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为无壳程序。查壳去壳可浏览博主以下文章,此处只是简单展示。
​相关链接:[查壳脱壳 ](https://blog.csdn.net/qq_29709589/article/details/147473015 )
4.2 使用 IDA Pro 分析
1. 打开 IDA Pro,选择 `File` > open ,加载 `hello.exe` 文件。
2. IDA Pro 会自动对程序进行分析,并生成反汇编代码。
3. 在反汇编窗口中,可以看到程序的入口点(通常是 `main` 函数)。
4. 双击入口点地址,查看 `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 关键点分析
1. 代码解释:
.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` 函数的结束。
2. 字符串存储:
- 字符串 "Hello, World!" 通常存储在程序的 `.data` 段或 `.rodata` 段中。
五,使用 IDA十六进制窗口京进行修改
1.在线将mandao字符串转为16进制,转换后为6D616E64616F
2.找到十六进制窗口选择修改字符串,按F2进行修改,输入mandao字符串的16进制
3.修改后进行保存
4.修改后运行
六、总结
通过本文的介绍,我们了解了如何在 Windows 环境下使用 IDA Pro 对一个简单的“Hello, World!”程序进行逆向分析。逆向工程不仅可以帮助我们学习程序的内部结构,还可以用于调试软件和分析恶意软件。希望本文对你有所帮助,如果你对逆向工程感兴趣,可以进一步学习更复杂的程序分析和调试技术。
免费评分
查看全部评分
发帖前要善用【论坛搜索 】 功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。