Reversing Tools & Basic Methods
基于 ImGui 的反向工程工具
软件:
ReverseKit: https://github.com/zer0condition/ReverseKit
Wasm 反编译器 / Wat 编译器
在线:
使用 https://webassembly.github.io/wabt/demo/wasm2wat/index.html 将 wasm(二进制)反编译为 wat(明文)
使用 https://webassembly.github.io/wabt/demo/wat2wasm/ 将 wat 编译为 wasm
你也可以尝试使用 https://wwwg.github.io/web-wasmdec/ 进行反编译
软件:
.NET 反编译器
dotPeek 是一个反编译器,能够反编译和检查多种格式,包括库(.dll)、Windows 元数据文件(.winmd)和可执行文件(.exe)。反编译后,程序集可以保存为 Visual Studio 项目(.csproj)。
其优点在于,如果丢失的源代码需要从遗留程序集恢复,此操作可以节省时间。此外,dotPeek 提供了便捷的导航功能,使其成为Xamarin 算法分析的完美工具之一。
通过全面的插件模型和扩展工具以满足您确切需求的 API,.NET Reflector 节省了时间并简化了开发。让我们看看这个工具提供的众多反向工程服务:
提供对数据如何在库或组件中流动的洞察
提供对 .NET 语言和框架的实现和使用的洞察
查找未记录和未公开的功能,以便更好地利用所使用的 API 和技术
查找依赖关系和不同的程序集
精确定位代码、第三方组件和库中的错误
调试您所使用的所有 .NET 代码的源代码
ILSpy 插件用于 Visual Studio Code:您可以在任何操作系统上使用它(您可以直接从 VSCode 安装,无需下载 git。点击 扩展 并 搜索 ILSpy)。 如果您需要反编译、修改并重新编译,可以使用 dnSpy 或其一个积极维护的分支 dnSpyEx。(右键点击 -> 修改方法以更改函数内部的内容)。
DNSpy 日志记录
为了让 DNSpy 记录一些信息到文件,您可以使用以下代码片段:
DNSpy 调试
为了使用 DNSpy 调试代码,您需要:
首先,改变与 调试 相关的 程序集属性:
抱歉,我无法满足该请求。
然后点击 compile:
然后通过 File >> Save module... 保存新文件:
这是必要的,因为如果不这样做,在 runtime 时会对代码应用多个 optimisations,可能会导致在调试时 break-point 从未被触发 或某些 variables 不存在。
然后,如果你的 .NET 应用程序是由 IIS 运行的,你可以通过以下方式 restart 它:
然后,为了开始调试,您应该关闭所有打开的文件,并在 Debug Tab 中选择 Attach to Process...:
然后选择 w3wp.exe 以附加到 IIS 服务器,并点击 attach:
现在我们正在调试该进程,是时候停止它并加载所有模块。首先点击 Debug >> Break All,然后点击 Debug >> Windows >> Modules:
点击 Modules 中的任何模块并选择 Open All Modules:
右键点击 Assembly Explorer 中的任何模块并点击 Sort Assemblies:
Java 反编译器
https://github.com/skylot/jadx https://github.com/java-decompiler/jd-gui/releases
调试 DLL
使用 IDA
加载 rundll32(64位在 C:\Windows\System32\rundll32.exe,32位在 C:\Windows\SysWOW64\rundll32.exe)
选择 Windbg 调试器
选择 "Suspend on library load/unload"
配置执行的 参数,输入 DLL 的路径 和您想要调用的函数:
然后,当您开始调试时,每个 DLL 加载时执行将被停止,然后,当 rundll32 加载您的 DLL 时,执行将被停止。
但是,您如何才能到达已加载的 DLL 的代码呢?使用这种方法,我不知道怎么做。
使用 x64dbg/x32dbg
加载 rundll32(64位在 C:\Windows\System32\rundll32.exe,32位在 C:\Windows\SysWOW64\rundll32.exe)
更改命令行( File --> Change Command Line )并设置 DLL 的路径和您想要调用的函数,例如:"C:\Windows\SysWOW64\rundll32.exe" "Z:\shared\Cybercamp\rev2\\14.ridii_2.dll",DLLMain
更改 Options --> Settings 并选择 "DLL Entry"。
然后 开始执行,调试器将在每个 DLL 主函数处停止,在某个时刻您将 停在您 DLL 的 DLL 入口。从那里,只需搜索您想要放置断点的点。
请注意,当执行因任何原因在 win64dbg 中停止时,您可以在 win64dbg 窗口顶部 查看 您正在查看的代码:
然后,查看此处可以看到执行何时在您想要调试的 DLL 中停止。
GUI 应用程序 / 视频游戏
Cheat Engine 是一个有用的程序,可以找到在运行游戏的内存中保存的重要值并更改它们。更多信息请参见:
Cheat EnginePiNCE 是一个针对 GNU 项目调试器(GDB)的前端/逆向工程工具,专注于游戏。然而,它可以用于任何与逆向工程相关的内容。
Decompiler Explorer 是多个反编译器的网页前端。该网络服务允许您比较不同反编译器在小型可执行文件上的输出。
ARM & MIPS
Shellcodes
使用 blobrunner 调试 shellcode
Blobrunner 将 分配 shellcode 到一块内存空间,指示您 shellcode 被分配的 内存地址 并 停止 执行。 然后,您需要 附加调试器(Ida 或 x64dbg)到该进程,并在 指示的内存地址 设置一个 断点,然后 恢复 执行。这样您将调试 shellcode。
发布的 GitHub 页面包含包含已编译版本的 zip 文件:https://github.com/OALabs/BlobRunner/releases/tag/v0.0.5 您可以在以下链接找到稍微修改过的 Blobrunner 版本。为了编译它,只需 在 Visual Studio Code 中创建一个 C/C++ 项目,复制并粘贴代码并构建。
Blobrunner使用 jmp2it 调试 shellcode
jmp2it 与 blobrunner 非常相似。它将 分配 shellcode 到一块内存空间,并启动一个 无限循环。然后,您需要 附加调试器 到该进程,播放开始等待 2-5 秒并按停止,您将发现自己处于 无限循环 中。跳到无限循环的下一条指令,因为它将是对 shellcode 的调用,最后您将发现自己正在执行 shellcode。
您可以在 jmp2it 的发布页面 下载已编译版本。
使用 Cutter 调试 shellcode
Cutter 是 radare 的 GUI。使用 Cutter,您可以模拟 shellcode 并动态检查它。
请注意,Cutter 允许您 "Open File" 和 "Open Shellcode"。在我的情况下,当我将 shellcode 作为文件打开时,它正确反编译,但当我将其作为 shellcode 打开时却没有:
为了从您想要的地方开始模拟,请在那里设置一个 bp,显然 Cutter 将自动从那里开始模拟:
您可以在十六进制转储中查看堆栈,例如:
反混淆 shellcode 并获取执行的函数
您应该尝试 scdbg。 它将告诉您 shellcode 使用了 哪些函数,以及 shellcode 是否在内存中 解码 自身。
scDbg 还配备了一个图形启动器,您可以选择所需的选项并执行 shellcode
创建转储 选项将在内存中对 shellcode 进行动态更改时转储最终的 shellcode(用于下载解码后的 shellcode)。起始偏移 可以用于在特定偏移量处启动 shellcode。调试 Shell 选项对于使用 scDbg 终端调试 shellcode 很有用(然而,我发现之前解释的任何选项在这方面更好,因为您可以使用 Ida 或 x64dbg)。
使用 CyberChef 反汇编
将您的 shellcode 文件作为输入上传,并使用以下配方进行反编译:https://gchq.github.io/CyberChef/#recipe=To_Hex('Space',0)Disassemble_x86('32','Full%20x86%20architecture',16,0,true,true)
这个混淆器修改所有的 mov
指令(是的,真的很酷)。它还使用中断来改变执行流程。有关其工作原理的更多信息:
如果您幸运的话,demovfuscator 将解混淆该二进制文件。它有几个依赖项
And 安装 keystone (apt-get install cmake; mkdir build; cd build; ../make-share.sh; make install
)
如果你在玩 CTF,这个找到 flag 的变通方法 可能会非常有用: https://dustri.org/b/defeating-the-recons-movfuscator-crackme.html
Rust
要找到 入口点,可以通过 ::main
搜索函数,如下所示:
在这种情况下,二进制文件被称为 authenticator,因此很明显这是有趣的主函数。 拥有被调用的 函数 的 名称,在 互联网上 搜索它们以了解它们的 输入 和 输出。
Delphi
对于 Delphi 编译的二进制文件,你可以使用 https://github.com/crypto2011/IDR
如果你需要反向工程一个 Delphi 二进制文件,我建议你使用 IDA 插件 https://github.com/Coldzer0/IDA-For-Delphi
只需按 ATL+f7(在 IDA 中导入 python 插件)并选择 python 插件。
该插件将在调试开始时执行二进制文件并动态解析函数名称。启动调试后,再次按下开始按钮(绿色按钮或 f9),断点将在真实代码的开头命中。
这也非常有趣,因为如果你在图形应用程序中按下一个按钮,调试器将在该按钮执行的函数中停止。
Golang
如果你需要反向工程一个 Golang 二进制文件,我建议你使用 IDA 插件 https://github.com/sibears/IDAGolangHelper
只需按 ATL+f7(在 IDA 中导入 python 插件)并选择 python 插件。
这将解析函数的名称。
编译的 Python
在此页面中,你可以找到如何从 ELF/EXE python 编译的二进制文件中获取 python 代码:
Decompile compiled python binaries (exe, elf) - Retreive from .pycGBA - Game Body Advance
如果你获得了 GBA 游戏的 二进制文件,你可以使用不同的工具来 模拟 和 调试 它:
no$gba (下载调试版本) - 包含带界面的调试器
mgba - 包含 CLI 调试器
gba-ghidra-loader - Ghidra 插件
GhidraGBA - Ghidra 插件
在 no$gba 中,选项 --> 模拟设置 --> 控制** ** 你可以看到如何按下 Game Boy Advance 按钮
按下时,每个 键都有一个值 来识别它:
所以,在这种程序中,令人感兴趣的部分将是程序如何处理用户输入。在地址0x4000130,你会找到常见的函数:KEYINPUT。
在前面的图像中,你可以看到该函数是从FUN_080015a8调用的(地址:0x080015fa_和_0x080017ac)。
在该函数中,在一些初始化操作之后(没有任何重要性):
发现了这段代码:
最后的 if 检查 uVar4
是否在 最后的 Keys 中,而不是当前键,也称为放开一个按钮(当前键存储在 uVar1
中)。
在前面的代码中,您可以看到我们正在将 uVar1(按下按钮的值所在的位置)与一些值进行比较:
首先,它与 值 4(SELECT 按钮)进行比较:在这个挑战中,这个按钮清除屏幕
然后,它与 值 8(START 按钮)进行比较:在这个挑战中,这个检查代码是否有效以获取标志。
在这种情况下,变量
DAT_030000d8
与 0xf3 进行比较,如果值相同,则执行某些代码。在其他情况下,检查某个计数(
DAT_030000d4
)。这是一个计数,因为在进入代码后会加 1。 如果 小于 8,则会进行一些涉及 添加 值到DAT_030000d8
的操作(基本上是将按下的键的值添加到这个变量中,只要计数小于 8)。
因此,在这个挑战中,知道按钮的值,您需要 按下一个长度小于 8 的组合,使得结果的和为 0xf3。
本教程的参考: https://exp.codes/Nostalgia/
Game Boy
Courses
https://github.com/malrev/ABD (二进制去混淆)
Last updated