x86逆转挑战中的打包和加密部分,没有绊倒熵启发式

Pol*_*ial 5 windows encryption x86 assembly reverse-engineering

任务:

我正在构建一组x86汇编逆向工程挑战,其中我已经完成了大约20个左右.他们只是为了娱乐/教育.

当前的挑战是更先进的挑战之一,并且涉及一些技巧,使得它看起来像EP实际上在正常程序中,但它实际上被包装在另一个PE部分中.

继承人的基本流程:

  • 开始就好像它是一个普通的MSVC++应用程序.
  • 向一堆反调试器技巧注入一个偷偷摸摸的电话.
  • 如果它们通过,则内存中的DWORD设置为1.
  • 稍后在程序流程中,它检查该值是否为1,如果它有效,则解密一个小的调用表.如果它失败了,它就会通过疯狂的反调试技巧将它们发送出去,最终只会崩溃.
  • 调用表指向解密实际程序代码段的真实解密例程.
  • 调用解密例程,并使用基本循环xor解密(C ^ k ^ n,其中C是密文,k是32位密钥,n是当前数据偏移)
  • VirtualProtect用于将部分的保护标志从RW切换到RX.
  • 控制流被重定向到OEP,程序运行.

这个想法是因为他们认为他们处于正常的程序流程中,这使得他们错过了反调试和后来的检查.无论如何,一切正常.

问题:

目前的问题是,OllyDbg和其他一些工具会查看打包部分并发现它具有较高的熵,并发出一个警告,说它已经打包了.PE头中的代码段指针是正确设置的,所以它不会从EP外部代码中得到它 - 它纯粹是一个熵分析的东西.

题:

有没有我可以使用的加密方法保留低熵,但仍然很容易在x86 asm中实现?我不想使用普通的xor,因为它太容易了,但我也不希望它像包装一样抓住它并让游戏消失.

我想到了一个类似洗牌器的东西(以某种方式生成一个密钥流并使用它来交换4字节的代码块),但我不确定这是否会起作用,甚至是简单的.

有人有任何想法吗?

Baf*_*ois 2

实际上,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
Run Code Online (Sandbox Code Playgroud)

因此,避免该警告的方法是在压缩部分使用足够的字节,其值为 0xFF 0xE8 0x8B 0x89 0x83。