0

我的一个朋友挑战我破解他编写的一个小程序。基本上,它是一个显示图像的 exe 文件,但为了做到这一点,您需要一个带有密码的密钥文件。

我开始用 ollydgb 对其进行逆向工程,我发现需要存在一个名为 key.txt 的文件并包含密码。我意识到的另一件事是我的朋友使用密码来计算内存地址并调用它。因此,如果您的密码错误,应用程序将崩溃,因为它会跳转到一个随机地址,可能会导致违规。

他基本上将密码存储在EBX中。他放了一个固定值 EAX。然后他做了ADD EAX、EBX,最后是CALL EAX。

所以,知道了这一切,如果我知道接下来要执行哪个地址,我可以从存储在 EAX 中的固定值中减去该地址,我将得到与密码对应的 HEX 值。

我的问题是,我到底怎么知道下一个要执行的地址是哪个?我对破解还很陌生...

我尝试在 CALL 之后指向下一个地址,但它不起作用。我还检查了它正在使用的库,我当然看到了 opengl32,但我不确定我是否必须以某种方式跳转到那个库。

我的问题是,我怎样才能确定下一个要执行的地址?

4

2 回答 2

2

X86 指令集的属性之一是,尽管长度可变(指令使用可变字节数编码),但指令序列会很快收敛。这意味着,如果您随机选择一个位置作为函数的开始并从该点开始拆卸,您将不会搞砸。你反汇编的一些指令是错误的,但最终(而且很快)你会得到真正的指令。

这意味着你可以做一些事情,比如在可执行文件中选择随机地址,并开始寻找常见的模式,比如函数的序言和结尾。这些可以给你提示代码在哪里。

但是,这假设您的朋友不是手写程序集或以其他方式混淆代码。

但是,无论他做什么,都会有一些对导入地址表中的方法的调用,或者系统调用指令。这些将运行代码来绘制图像,或者将修改进程的页表,以便可以对混淆的代码进行反混淆。这些模式会更可靠。因此,一个好的开始是转储 iat(导入地址表),并寻找对有趣函数的调用。如果这不起作用,请尝试寻找系统调用模式。究竟要寻找什么取决于您所使用的特定操作系统。

要记住几件事:

  1. 如果您的朋友没有关闭 ASLR(地址空间布局随机化),那么即使您有正确的密码,代码也可能不会总是有效。

  2. 我对 olydbg 不太熟悉,但我假设它使用递归下降反汇编。如果是这样,它可能不会在反汇编中包含您的目标函数,因为它不会有任何静态可解析的调用。

要解决 2,您可能需要编写代码自己进行反汇编,解码指令。最好的起点是扫描 exe 以寻找间接调用指令。之后尝试系统调用。

更新

还有一件事:如果 exe 配置为使 exe 部分可写或数据部分可执行(或关闭 nxbit),则映像中可能没有系统调用。在开始之前查看图像中的部分表并查看是否有任何异常作为健全性检查是个好主意。

于 2012-10-17T05:12:36.400 回答
0

除非程序很小(我的意思是只有几 KB 的代码),否则您无法轻易弄清楚,需要执行一些代码分析、做出假设并通过试验来确认或反驳它们,并且不可避免地会出错。

我首先想到的是找到代码中存在但没有调用/跳转指令将控制权转移给它们的函数。您可以通过首先确定为绘制图片而必须调用的那些函数(调用相关 OpenGL/DirectX/GDI 函数的函数)来缩小搜索范围。然后你可以从那里向后工作。

查看可执行文件的数据部分中是否有任何函数指针/地址也可能很有用,原因是编译器可能会删除未被任何其他函数或指针引用的函数,因此对于感兴趣的函数要仍然存在于已编译的可执行文件中,必须在某处对其进行一些引用(当然,除非代码是在所有优化关闭的情况下编译的)。

无论哪种方式,恐怕您都将不得不编写大量代码。

要查看的另一件事是可执行文件本身及其部分(例如,它们的名称、大小、位置或内容)。这可能会给你一些线索。

于 2012-10-17T00:55:15.330 回答