我的一个朋友挑战我破解他编写的一个小程序。基本上,它是一个显示图像的exe文件,但为了做到这一点,你需要一个带密码的密钥文件。
我开始使用ollydgb对其进行逆向工程,我能够发现名为key.txt的文件需要存在并包含密码。我意识到的另一件事是我的朋友使用密码来计算内存地址并调用它。因此,如果您的密码错误,应用程序将崩溃,因为它会跳转到随机地址,可能会导致违规。
他基本上将密码存储在EBX中。他给出了固定值EAX。然后他做了ADD EAX,EBX,最后是CALL EAX。
所以,知道这一切,如果我知道接下来要执行哪个地址,我可以从存储在EAX中的固定值中减去地址,我将获得与密码相对应的HEX值。
我的问题是,我怎么知道哪个应该是下一个要执行的地址?我很擅长破解...
我试着指向CALL之后的下一个地址,但它不起作用。我还检查了它正在使用的库,我当然看到了opengl32,但我不确定是否必须以某种方式跳转到该库。
我的问题是,如何确定下一个要执行的地址?
答案 0 :(得分:2)
X86指令集的一个属性是尽管长度可变(指令使用可变数量的字节进行编码),但指令序列会相当快速地收敛。这意味着如果你随机选择一个位置作为一个功能的开始并开始从那一点开始拆卸你就不会太搞砸了。你反汇编的一些说明是错误的,但最终(而且很快)你会得到真正的指示。
这意味着您可以执行诸如在可执行文件中选择随机地址之类的操作,并开始寻找常见模式,例如函数的序言和结尾。这些可以为您提供代码所在位置的提示。
但是,假设您的朋友不是手写大会或以其他方式混淆代码。
但是,无论他做什么,他都会对导入地址表中的方法或系统调用指令进行一些调用。这些将运行代码以绘制图像,或者将修改进程的页表,以便可以对模糊处理的代码进行反混淆处理。这些模式会更可靠。因此,一个好的起点是转储iat(导入地址表),并寻找对有趣函数的调用。如果这不起作用,请尝试查找系统调用模式。究竟要查找的内容取决于您所使用的特定操作系统。
要记住的一些事项:
如果您的朋友没有关闭ASLR(地址空间布局随机化),那么即使您拥有正确的密码,代码也可能无法正常运行。
我对olydbg不太熟悉,但我会假设它使用递归下降反汇编。如果是,它可能不会在反汇编中包含您的目标函数,因为它不会有任何静态可解析的调用。
要解决2,您可能需要编写代码来进行反汇编,解码指令。最好的起点是扫描exe寻找间接调用指令。之后尝试系统调用。
<强>更新强>
还有一件事:如果exe配置为使exe部分可写或数据部分可执行(或关闭nxbit),则图像中可能没有系统调用。最好先看看图像中的部分表,然后在开始之前查看是否有任何异常情况作为完整性检查。
答案 1 :(得分:0)
除非程序很小(并且我的意思只是几KB的代码),否则你无法轻易搞清楚,需要进行一些代码分析,做出假设并通过试验确认或反驳它们,并且不可避免地,错误。
我想到的第一件事就是找到代码中存在的函数,但是没有调用/跳转指令将控制转移给它们。您可以通过首先识别必须调用的函数来缩小搜索范围,以便绘制图片(调用相关OpenGL / DirectX / GDI函数的函数)。然后你可以从那里向后工作。
查看可执行文件的数据部分中是否存在任何函数指针/地址也是有用的,原因是编译器可能删除未被任何其他函数或指针引用的函数,因此对于感兴趣的函数仍然存在于已编译的可执行文件中,必须在某处对它进行一些引用(当然,除非代码是在关闭所有优化的情况下编译的)。
无论哪种方式,我担心,你将不得不翻阅大量的代码。
要看的另一件事是可执行文件本身及其部分(例如它们的名称,大小,位置或内容)。这可能会给你一些线索。