关于逆向工程
逆向工程 Reverse Engineering RE
通过分析物体、机械设备或系统,了解结构、功能、行为,掌握原理改善不足,添加新的*一些过程
附件:
逆向工程核心原理(源代码)(解压密码是reversecore).zip
逆向工程核心原理(crackme)(解压密码是reversecore).zip
代码逆向工程 Reverse Code Engineering RCE
逆向工程在软件领域的应用
软件的逆向工程实质是对软件进行深入细致的分析
逆向分析法
1- 静态分析法
不执行代码的情况下,对代码进行静态分析
静态分析时不执行代码,观察代码外部特征,获取文件类型(EXE、DCL、DOC、ZIP)大小,PE 头信息,Import/Export API、内部字符串,是否运行时解压缩,注册信息、调试信息、数字证书等多种信息,使用反汇编工具(Disassembler) 查看内部代码,分析代码结构也属于静态分析。
2-动态分析法
在程序文件执行过程中对代码进行动态分析的一种方法,通过调试来分析代码流,获得内存的状态等,通过动态分析法,我们可以在观察文件、注册表、网络等同时分析软件程序的行为,动态分析中常使用调试器(Debugger)分析程序内部结构与动作原理
通常先采用静态分析收集代码相关信息,通过手机的信息推测程序的结构与行为机制,这些对动态分析具有高参考价值,为动态分析提供创意,对程序代码进行逆向分析过程中灵活使用,增加分析准确性,缩短代码分析时间
源代码、十六进制代码、汇编代码
代码逆向分析主要对象:可执行文件
没有源代码都情况下分析可执行文件都二进制代码
构建一段 C++代码学习源代码,十六进制代码,汇编代码如何转换
源代码
在 C++集成开发环境便携 helloworld.cpp 源码后,执行菜单中生成命令,将程序代码编译成 helloworld.exe 可执行文件

十六进制代码
把二进制代码文件转换为十六进制代码文件后,数字位减少,使用 HexEditor 轻松把二进制文件转换为十六进制文件

汇编代码
与十六进制代码相比,汇编代码更易理解

补丁与破解
对应用程序文件或进程内存内容的更改叫打补丁,破解与其相似,但意图违法,补丁主要目的在于修复程序漏洞,破解是对著作权的侵害
调试工具 OllyDbg

调试 HelloWorld.exe 程序
目标:在转换得到的汇编预压代码中查找 main()函数,这一过程中,我们要了解基本都调试方法和汇编指令
OllyDbg 是一种强大都 Win32 调试工具,用户界面直观、简介、支持插件扩展功能,当逆向水平到一定高度,可以使用 IDA-Pro
| 代码窗口 | 默认显示反汇编代码,还用于显示各种注释、标签、分析代码时显示循环、跳转位置等信息 |
|---|---|
| 寄存器窗口 | 实时显示 CPU 寄存器的值,修改特定的寄存器 |
| 数据窗口 | 以 Hex/ASCII/Unicode 值形式显示进程的内存地址,也可在此修改内存地址 |
| 栈窗口 | 实时显示 ESP 寄存器指向都进程栈内存,并允许修改 |
入口点
调试器停止都地点即为 HelloWorld.exe 执行的起始地址 4011A0,它是一段 EntryPoint(EP,入口点)代码,引人注意的是 CALL 与 JMP 两个命令

| 地址 | 进程的虚拟内存地址(Vitual Address,VA) |
|---|---|
| 指令 | IA32 或 x86CPU 指令 |
| 反汇编代码 | 将 OP code 转换为便于查看都汇编指令 |
| 注释 | 调试器添加都注释(根据选项不同,显示注释不同) |
上图 两行汇编代码含义:
**先 CALL(调用) 0040270C 地址处函数,再 JMP(跳转) 至 0040104F 处**
目标是在 main 函数中找出调用 MessageBox 函数的代码
入口点 EP,是 Windows 可执行文件的代码入口点,是执行应用程序时最先执行的代码起始位置,它依赖于 CPU
跟踪 40270C 函数
OllyDbg 代码窗口基本指令
| 指令 | 快捷键 | 含义 |
|---|---|---|
| Restart | Ctrl+F2 | 重新开始调试(终止正在调试都进程后再次运行) |
| Setp Into | F7 | 执行一句 OP code(操作码),若遇到调用命令 CALL,将进入函数代码内部 |
| Setp Over | F8 | 执行一 OPcode,若遇到调用命令,仅执行函数自身,不跟随进入 |
| Execute till Return | Ctrl+F9 | 一直在函数代码内部运行,直到遇到 RETN 命令,跳出函数 |
在 EP 代码的 4011A0 地址使用 Step Into (F7),进入 40270C 函数


4027A1 地址处有一条 RETN 指令,它用于返回到函数调用者的下一条指令,一般是被调用函数的最后一句,即返回 4011A5 地址处,在 4027A1 地址处的 RETN 指令上执行 Step Over 或 Rxecutr till Return 命令,继续操作,按 F7/F8 执行 RETN 指令,程序会跳转到 4011A5 地址处
跟踪 40104F 跳转语句
执行 4011A5 地址处的跳转命令 JMP 0040104F,跳转至 40104F 地址处

查找 main()函数
从 40104F 地址处开始逐条分析各函数调用指令,就能查找到我们要查找到 main()函数,这是初学调试都必经阶段。
:::info
初学者在调试代码过程中使用 F7/F8 可能会感到困惑,特别是过分深入到函数调用中,此时可以使用 Ctrl+F2 (Restart)重新打开待调试文件,重头调试,每种编译器产生的启动函数是不同的,熟悉这些启动函数后,实际调试过程中可以快速跳过类似启动函数的部分。
:::
从 40104F 地址开始,每执行一次 Step Into 就下移一行代码,移动到 401056 地址处的 CALL 402524 函数调用指令时,执行 F7,进入 402524 函数


在它的代码中并未发现调用 MessageBox()APi 的代码,执行 Execute till Return 指令,调试转到 402568 地址处的 RETN 指令,然后使用 Step Into 或者 Step Over 执行 RETN 指令 跳出 402524 函数返回到 40105B 地址
同样,在 40104F 地址执行 Step Into 遇到函数调用就进入函数查看代码,使用 Step Into 确认是否为 main 函数,若不是 main 函数 则使用 Execute till Return 命令跳出相关函数,继续以相同方式调试
4010E4 地址处的 CALL Kernel32.GetCommandLineW 指令是调用 Win32API 的代码,现在我们还不需要进入被调用的函数,直接使用 Step Over 命令跳过

401144 地址有一条 CALL 401000 指令,用来调用 401000 函数,使用 Step Into 命令进入 401000 函数

401000 函数内部出现了调用 MessageBoxW()API 代码,API 参数为 www.reversecore.com 与 Helloworld 字符串,这和 HelloWorld.cpp 源码一致,由此判定 401000 函数就是 main()函数
进一步熟悉调试器
适用于代码窗口的调试器操作命令
| 指令 | 快捷键 | 含义 |
|---|---|---|
| Go to | Ctrl+G | 移动到指定位置,用来查看代码或 |
| Execute till Cursor | F4 | 执行到光标位置,直接转到要调试的地址 |
| Comment | ; | 添加注释 |
| User-defined comment | 鼠标右键菜单 Search for User-defined comment | |
| Lable | : | 添加标签 |
| User-defined label | 鼠标右键菜单 Search for User-defined label | |
| Set/Reset BreakPoint | F2 | 设置或取消断点(BP) |
| Run | F9 | 运行(若设置断点,则执行到断点处) |
| Show the current EIP | * | 显示当前 EIP(命令指针)位置 |
| Show the previous Cursor | – | 显示上一个光标位置 |
| Previer CALL/JMP address | Enter | 若光标处有 CALL/JMP 等指令,则跟踪并显示相关地址(运行时不可用,简单查看函数内容时非常有用) |
:::info
每次重新运行调试器时,调试都会返回到 EP 处,并从此开始新的调试,使用起来想当不方便,经验丰富的专家会需要在调试代码时设置某个重要的点(地址)使调试能快速转到设置点上,在代码中设置好这样的点后,再次调试时,调试流能够经过这些指定的点,快速达到目标
这些代码中设置的点就像行进中据点一样,例如行军,需要设置多个据点。同样,调试代码量非常巨大时,整个调试过程可能需要好几天时间,那么在相应位置上设置这些据点将非常方便调试
:::
设置据点的四种方法
1-Goto 命令 要设置一个地址为据点 执行 Goto(Ctrl+G)打开一个 Enter expression to follow(输入跟踪表达式)对话框,在文本框输入 地址 然后点击 OK 按钮

2-设置断点 调试代码时,还可以设置 BP(BreakPoint ,F2)让调试流转到据点,设置断点后,调试运行到断点处将会暂停,在 OllyDbg 菜单依次选择 View-Breakpoints 选项(ALT+B)打开 BreakPoints 对话框,列出代码中设置的断点,在断点列表中双击某个断点会跳转相应位置

3-注释 按键盘上的;可以在指定地址添加注释,还可以通过查找命令找到它

调试过程中添加的注释和编程中注释一样重要,在重要代码添加注释会让整个调试变得轻松,移动光标到一个位置,在鼠标右键菜单依次选择 Search for-User defined comment,这样就能看到用户输入的所有注释

红字部分是光标所处位置,注释位置与光标位置重合时,仅以红字方式显示(所以刚开始的时候需要把光标暂时移动到其他位置)双击相应注释,将自动定位到相应位置
4-标签 也可以通过标签提供的功能在指定地址添加特定敏成,移动光标到地址处按:键输入标签

同样在 Search for-User defined label 中也能找到添加到标签,并且双击标签跳转到相应位置

快速查找指定代码的四种方法
调试代码时,main 函数并不直接位于可执行文件 EP 位置上,出现在此的上开发工具生成的启动函数,我们需要查看的 main 函数举例 EP 代码很远,如果有一种方法可以帮助我们快速查找到 main 函数呢?
1-代码执行法 需要查找的是 main 函数中调用 MessageBox()函数的代码,在调试器中调试 HelloWorld
.exe(Step Over(F8))时,main 函数的 messageBox 函数在某个时刻就会被调用执行,弹出消息对话框,显示 Hello World!这条信息。
37
更新: 2025-06-11 12:07:42
原文: https://www.yuque.com/yuhui.net/network/zud0xzmyqywn4fl5

评论(0)
暂无评论