任务:
我正在构建一组 x86 汇编逆向工程挑战,其中我已经完成了大约 20 个。它们只是为了娱乐/教育。
当前的挑战是更高级的挑战之一,涉及一些技巧,使 EP 看起来像是在正常程序中,但实际上被打包在另一个 PE 部分中。
基本流程如下:
- 开始时就像一个普通的 MSVC++ 应用程序。
- 向一堆反调试器技巧中注入(inject)偷偷摸摸的调用。
- 如果通过,内存中的 DWORD 值将设置为 1。
- 稍后在程序流程中,它会检查该值是否为 1,如果有效,它会解密一个小的调用表。如果它失败了,它会让他们疯狂地追逐虚假的反调试技巧,最终只会崩溃。
- 调用表指向解密实际程序代码段的真实解密例程。
- 调用解密例程,它们使用基本的循环异或(C^k^n,其中 C 是密文,k 是 32 位 key ,n 是当前数据偏移量)进行解密
- VirtualProtect 用于将部分的保护标志从 RW 切换到 RX。
- 控制流被重定向到 OEP,程序运行。
这个想法是因为他们认为他们处于正常的程序流程中,这让他们错过了反调试调用和以后的检查。无论如何,一切正常。
问题:
当前的问题是 OllyDbg 和其他一些工具查看打包部分并发现它具有高熵,并发出警告它已打包。 PE header 中的代码段指针已正确设置,因此它不会从 EP 外部代码中获取此指针 - 这纯粹是一种熵分析。
问题:
是否有一种我可以使用的加密方法可以保留低熵,但在 x86 asm 中仍然很容易实现?我不想使用普通的 xor,因为它太简单了,但我也不希望它把它打包并泄露游戏。
我想到了类似洗牌器的东西(以某种方式产生一个 key 流并用它来交换 4 字节的代码块),但我不确定这是否会起作用,或者是否简单。
有人有什么想法吗?
最佳答案
实际上,OllyDbg 的工作原理是这样的伪代码:
useful_bytes = number_of_bytes_in_section - count_bytes_with_values(0x00, 0x90, 0xCC)
warn about compression if useful_bytes > 0x2000 and count_bytes_with_values(0xFF, 0xE8, 0x8B, 0x89, 0x83) / useful_bytes < 0.075
因此,避免该警告的方法是在压缩部分中使用值为 0xFF 0xE8 0x8B 0x89 0x83 的足够字节。
关于windows - x86 逆向挑战中的打包和加密部分,没有触发熵启发式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7937942/