[逆向工程]Windows 下逆向分析“Hello, World!”程序(一)

[逆向工程]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为无壳程序。查壳去壳可浏览博主以下文章,此处只是简单展示。

在这里插入图片描述

​ 相关链接:查壳脱壳

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 中。40hMB_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 中,rdxMessageBoxA 函数的第三个参数,表示对话框中显示的文本。
.text:0000000140001484                 mov     ecx, 0          ; hWnd
  • 0 移动到寄存器 ecx 中,ecxMessageBoxA 函数的第一个参数,表示父窗口的句柄。0 表示没有父窗口。
.text:0000000140001489                 mov     rax, cs:__imp_MessageBoxA
  • MessageBoxA 函数的地址加载到寄存器 rax 中。__imp_MessageBoxAMessageBoxA 函数的导入地址。
.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 函数的结束。
  1. 字符串存储

    • 字符串 “Hello, World!” 通常存储在程序的 .data 段或 .rodata 段中。

五,使用 IDA十六进制窗口进行修改

1.在线将mandao字符串转为16进制,转换后为6D616E64616F

在这里插入图片描述

2.找到十六进制窗口选择修改字符串,按F2进行修改,输入mandao字符串的16进制
在这里插入图片描述
在这里插入图片描述

3.修改后进行保存

在这里插入图片描述

在这里插入图片描述

六、总结

通过本文的介绍,我们了解了如何在 Windows 环境下使用 IDA Pro 对一个简单的“Hello, World!”程序进行逆向分析。逆向工程不仅可以帮助我们学习程序的内部结构,还可以用于调试软件和分析恶意软件。希望本文对你有所帮助,如果你对逆向工程感兴趣,可以进一步学习更复杂的程序分析和调试技术。

如果本教程对您有帮助,请点赞❤️收藏⭐关注支持!欢迎在评论区留言交流技术细节!欲了解更深密码学知识,请订阅《密码学实战》专栏 → 密码学实战

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曼岛_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值