hacktricks/reversing/reversing-tools-basic-methods
2023-08-03 19:12:22 +00:00
..
angr Translated to Chinese 2023-08-03 19:12:22 +00:00
blobrunner.md Translated to Chinese 2023-08-03 19:12:22 +00:00
cheat-engine.md Translated to Chinese 2023-08-03 19:12:22 +00:00
README.md Translated to Chinese 2023-08-03 19:12:22 +00:00
satisfiability-modulo-theories-smt-z3.md Translated to Chinese 2023-08-03 19:12:22 +00:00

反向工程工具和基本方法

☁️ HackTricks 云 ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

基于ImGui的反向工程工具

软件:

Wasm反编译器 / Wat编译器

在线工具:

软件:

.Net反编译器

dotPeek

dotPeek是一个反编译器可以反编译和检查多种格式包括库.dll、Windows元数据文件.winmd和可执行文件.exe。一旦反编译可以将程序集保存为Visual Studio项目.csproj

这里的优点是如果丢失的源代码需要从旧版程序集中恢复这个操作可以节省时间。此外dotPeek提供了方便的导航功能使其成为Xamarin算法分析的完美工具之一。

.Net Reflector

.NET Reflector具有全面的插件模型和API可以根据您的实际需求扩展工具节省时间并简化开发。让我们来看看这个工具提供的众多逆向工程服务

  • 提供对数据在库或组件中的流动方式的洞察
  • 提供对.NET语言和框架的实现和使用的洞察
  • 发现未记录和未公开的功能以更充分地利用所使用的API和技术。
  • 查找依赖项和不同的程序集
  • 追踪代码中错误、第三方组件和库的确切位置。

ILSpy & dnSpy

ILSpy Visual Studio Code插件你可以在任何操作系统中使用它你可以直接从VSCode安装它无需下载git。点击Extensions然后搜索ILSpy)。
如果你需要反编译修改重新编译,你可以使用:https://github.com/0xd4d/dnSpy/releases右键单击 -> 修改方法来更改函数内部的内容)。
你也可以尝试https://www.jetbrains.com/es-es/decompiler/

DNSpy日志记录

为了使DNSpy记录一些信息到文件中,你可以使用以下.NET代码行

using System.IO;
path = "C:\\inetpub\\temp\\MyTest2.txt";
File.AppendAllText(path, "Password: " + password + "\n");

DNSpy调试

为了使用DNSpy调试代码您需要

首先,更改与调试相关的程序集属性

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]

/hive/hacktricks/reversing/reversing-tools-basic-methods/README.md

Reversing Tools Basic Methods

This section provides an overview of the basic methods used in reversing tools. These methods are essential for reverse engineering and analyzing software.

Static Analysis

Static analysis involves examining the binary code of a program without executing it. This can be done using tools such as disassemblers and decompilers. Static analysis helps in understanding the structure and behavior of the program.

Disassemblers

Disassemblers are tools that convert machine code into assembly code. They allow you to view the low-level instructions of a program. Some popular disassemblers include IDA Pro, Ghidra, and Radare2.

Decompilers

Decompilers are tools that convert compiled code into a higher-level programming language. They help in understanding the logic and functionality of a program. Some popular decompilers include IDA Pro, Ghidra, and RetDec.

Dynamic Analysis

Dynamic analysis involves running the program and observing its behavior in real-time. This can be done using tools such as debuggers and dynamic analysis frameworks. Dynamic analysis helps in understanding the runtime behavior and identifying vulnerabilities.

Debuggers

Debuggers are tools that allow you to monitor and control the execution of a program. They provide features such as breakpoints, stepping through code, and inspecting variables. Some popular debuggers include GDB, WinDbg, and OllyDbg.

Dynamic Analysis Frameworks

Dynamic analysis frameworks are tools that automate the process of analyzing software behavior. They provide features such as code instrumentation, memory monitoring, and network traffic analysis. Some popular dynamic analysis frameworks include Frida, Pin, and DynamoRIO.

Other Tools

Apart from disassemblers, decompilers, debuggers, and dynamic analysis frameworks, there are several other tools that can be used in reverse engineering. These include:

  • Hex Editors: Tools that allow you to view and edit binary files.
  • Packers/Unpackers: Tools that compress or encrypt executable files to make reverse engineering more difficult.
  • Patchers: Tools that modify the binary code of a program to change its behavior.
  • Fuzzers: Tools that generate random inputs to test the robustness of a program.
  • Profilers: Tools that analyze the performance of a program and identify bottlenecks.

Conclusion

Understanding the basic methods used in reversing tools is essential for reverse engineering and analyzing software. By using a combination of static and dynamic analysis, along with other tools, you can gain insights into the inner workings of a program and identify vulnerabilities.

[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default |
DebuggableAttribute.DebuggingModes.DisableOptimizations |
DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints |
DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]

然后点击编译

然后将新文件保存在_文件 >> 保存模块..._

这是必要的,因为如果不这样做,在运行时会对代码应用多个优化,可能会导致在调试时断点永远不会触发或某些变量不存在

然后,如果你的.NET应用程序正在由IIS运行,你可以使用以下命令重新启动它:

iisreset /noforce

然后,为了开始调试,您应该关闭所有打开的文件,并在调试选项卡中选择附加到进程...

然后选择w3wp.exe以附加到IIS服务器,然后点击附加

现在我们正在调试进程是时候停止它并加载所有模块了。首先点击_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

  • 加载rundll3264位在C:\Windows\System32\rundll32.exe32位在C:\Windows\SysWOW64\rundll32.exe
  • 选择Windbg调试器
  • 选择“在库加载/卸载时暂停

  • 配置执行的参数,将DLL的路径和要调用的函数放入其中:

然后,当您开始调试时,每次加载DLL时都会停止执行然后当rundll32加载您的DLL时执行将停止。

但是您如何获取已加载的DLL的代码使用这种方法我不知道如何。

使用x64dbg/x32dbg

  • 加载rundll3264位在C:\Windows\System32\rundll32.exe32位在C:\Windows\SysWOW64\rundll32.exe
  • 更改命令行文件 --> 更改命令行设置dll的路径和要调用的函数例如"C:\Windows\SysWOW64\rundll32.exe" "Z:\shared\Cybercamp\rev2\\14.ridii_2.dll",DLLMain
  • 更改_Options --> Settings_选择“DLL Entry”。
  • 然后开始执行调试器将在每个dll主函数处停止最终您将停在您的dll的dll Entry处。从那里,只需搜索您想要设置断点的位置。

请注意当执行由于任何原因停止时在win64dbg中您可以在win64dbg窗口顶部看到您所在的代码:

然后查看此处您可以看到执行停止在您要调试的dll中的位置。

GUI应用程序/视频游戏

Cheat Engine是一个有用的程序,可以找到正在运行的游戏内存中保存的重要值并进行更改。更多信息请参见:

{% content-ref url="cheat-engine.md" %} cheat-engine.md {% endcontent-ref %}

ARM和MIPS

{% embed url="https://github.com/nongiach/arm_now" %}

Shellcode

使用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++项目,复制并粘贴代码,然后构建

{% content-ref url="blobrunner.md" %} blobrunner.md {% endcontent-ref %}

使用jmp2it调试shellcode

jmp2it 与blobrunner非常相似。它将在内存空间中分配shellcode,并启动一个无限循环。然后,您需要将调试器附加到进程,播放开始等待2-5秒然后按停止,您将发现自己处于无限循环中。跳转到无限循环的下一条指令因为它将是对shellcode的调用最后您将发现自己正在执行shellcode。

您可以在发布页面下载编译版本的jmp2it

使用Cutter调试shellcode

Cutter是radare的图形界面。使用cutter您可以动态地模拟和检查shellcode。

请注意Cutter允许您“打开文件”和“打开shellcode”。在我的情况下当我将shellcode作为文件打开时它正确反编译了但当我将其作为shellcode打开时它没有

为了从您想要的位置开始模拟设置一个断点然后cutter将自动从那里开始模拟

您可以在十六进制转储中查看堆栈,例如:

反混淆 shellcode 并获取执行的函数

你可以尝试使用 scdbg
它会告诉你 shellcode 使用了哪些函数,并且如果 shellcode 在内存中进行了解码

scdbg.exe -f shellcode # Get info
scdbg.exe -f shellcode -r #show analysis report at end of run
scdbg.exe -f shellcode -i -r #enable interactive hooks (file and network) and show analysis report at end of run
scdbg.exe -f shellcode -d #Dump decoded shellcode
scdbg.exe -f shellcode /findsc #Find offset where starts
scdbg.exe -f shellcode /foff 0x0000004D #Start the executing in that offset

scDbg也提供了一个图形化启动器您可以在其中选择所需的选项并执行shellcode。

如果对shellcode在内存中进行了任何动态更改用于下载解码后的shellcodeCreate Dump选项将转储最终的shellcode。start offset可以用于在特定偏移处启动shellcode。Debug 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)

Movfuscator

这个混淆器修改了所有的mov指令(是的,非常酷)。它还使用中断来改变执行流程。有关其工作原理的更多信息:

如果您很幸运,demovfuscator将对二进制文件进行反混淆。它有几个依赖项。

apt-get install libcapstone-dev
apt-get install libz3-dev

并且安装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代码:

{% content-ref url="../../forensics/basic-forensic-methodology/specific-software-file-type-tricks/.pyc.md" %} .pyc.md {% endcontent-ref %}

GBA - Game Body Advance

如果你得到了一个GBA游戏的二进制文件,你可以使用不同的工具来模拟调试它:

no$gba在_Options --> Emulation Setup --> Controls_** **中可以看到如何按下Game Boy Advance的按钮

按下时,每个键都有一个值来识别它:

A = 1
B = 2
SELECT = 4
START = 8
RIGHT = 16
LEFT = 32
UP = 64
DOWN = 128
R = 256
L = 256

所以,在这种程序中,一个有趣的部分将是程序如何处理用户输入。在地址0x4000130中,你会找到常见的函数:KEYINPUT

在上面的图像中,你可以发现该函数是从FUN_080015a8(地址:0x080015fa_和_0x080017ac)调用的。

在该函数中,在一些初始化操作之后(没有任何重要性):

void FUN_080015a8(void)

{
ushort uVar1;
undefined4 uVar2;
undefined4 uVar3;
ushort uVar4;
int iVar5;
ushort *puVar6;
undefined *local_2c;

DISPCNT = 0x1140;
FUN_08000a74();
FUN_08000ce4(1);
DISPCNT = 0x404;
FUN_08000dd0(&DAT_02009584,0x6000000,&DAT_030000dc);
FUN_08000354(&DAT_030000dc,0x3c);
uVar4 = DAT_030004d8;

发现了这段代码:

do {
DAT_030004da = uVar4; //This is the last key pressed
DAT_030004d8 = KEYINPUT | 0xfc00;
puVar6 = &DAT_0200b03c;
uVar4 = DAT_030004d8;
do {
uVar2 = DAT_030004dc;
uVar1 = *puVar6;
if ((uVar1 & DAT_030004da & ~uVar4) != 0) {

最后的if语句检查**uVar4是否在最后的Keys中,而不是当前的按键,也就是放开一个按钮(当前按键存储在uVar1**中)。

if (uVar1 == 4) {
DAT_030000d4 = 0;
uVar3 = FUN_08001c24(DAT_030004dc);
FUN_08001868(uVar2,0,uVar3);
DAT_05000000 = 0x1483;
FUN_08001844(&DAT_0200ba18);
FUN_08001844(&DAT_0200ba20,&DAT_0200ba40);
DAT_030000d8 = 0;
uVar4 = DAT_030004d8;
}
else {
if (uVar1 == 8) {
if (DAT_030000d8 == 0xf3) {
DISPCNT = 0x404;
FUN_08000dd0(&DAT_02008aac,0x6000000,&DAT_030000dc);
FUN_08000354(&DAT_030000dc,0x3c);
uVar4 = DAT_030004d8;
}
}
else {
if (DAT_030000d4 < 8) {
DAT_030000d4 = DAT_030000d4 + 1;
FUN_08000864();
if (uVar1 == 0x10) {
DAT_030000d8 = DAT_030000d8 + 0x3a;

在上面的代码中,我们可以看到我们正在将uVar1(按下按钮的值的位置)与一些值进行比较:

  • 首先,它与值4SELECT按钮)进行比较:在挑战中,该按钮清除屏幕
  • 然后,它与值8START按钮)进行比较:在挑战中,这将检查代码是否有效以获取标志。
  • 在这种情况下,将变量**DAT_030000d8**与0xf3进行比较如果值相同则执行一些代码。
  • 在其他任何情况下将检查一些contDAT_030000d4。它是一个cont因为在进入代码后立即加1。
  • 如果小于8则执行涉及将值添加到**DAT_030000d8**的操作基本上是将按下的键的值添加到此变量中只要cont小于8

因此,在这个挑战中,知道按钮的值,你需要按下一个长度小于8的组合使得结果的加法等于0xf3

本教程的参考资料:https://exp.codes/Nostalgia/

Game Boy

{% embed url="https://www.youtube.com/watch?v=VVbRe7wr3G4" %}

课程

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥