在哪里以及如何使用可变纠缠混淆?

逆向工程 混淆 白盒加密
2021-06-30 07:02:38

我不知道这种混淆的确切名称,所以我现在称之为变量纠缠

我已经在一些二进制文件中看到了这个原则,但我从来没有找到关于什么是可能的,什么是不可能的完整描述。

这个想法是通过将两个值混合在一起并对混合值执行操作来混淆反向器。完成所有操作后,可以通过一些简单的操作重新组合结果。例如,一个简单的例子可能是:

int foo (int a, int b) {
  long long x = 0;
  // Initial entanglement
  x = (a << 32) | b;

  // Performing operations on both variables
  x += (12 << 32) & 72;
  ...

  // Final desentanglement
  a = (int) (x >> 32);
  b = (int) (((int) -1) & x);
} 

当然,在这里,我们将所有内容混合在一个变量中(我没有处理溢出细节)。但是,您可以想象更复杂的初始纠缠方式,其中您将所有内容重新拆分为两个(或更多)变量,例如通过将它们异在一起。

必须为这种新格式重新定义诸如加法、乘法之类的操作,因此它可能会误导逆向者。

我现在的问题是,有没有人知道不同的可变纠缠模式(我给出的模式非常基本)?而且,也许,可以提供有关它的指示或出版物吗?

1个回答

我不确定这是否符合您正在寻找的路线(很可能您已经弄清楚了所有这些以及更多),但这里有一个粗略的形式化,然后是一些实现想法。从概念上讲,这种尝试分开是什么意思,从如何纠缠值套住几个值来表示

形式化

从概念上讲,纠缠值可以被认为是不同组件保留其值、互不干扰并且可以独立提取的集合考虑这种聚合的一种方便方法是将值视为n元组;为简单起见,我在这里假设n = 2。此外,我假设我们有一些操作可以从一组值构造元组,并从元组中提取组件值。

我们现在需要能够对元组进行操作。为此,对于原始程序中的每个操作op,我们现在有 2 个版本:op1,它对 2 元组的第一个组件进行操作,以及op2,它对第二个组件进行操作:

<a1,b1> op1 <a2,b2> = if (b1 == b2) then <(a1 op a2), b1> else undefined
<a1,b1> op2 <a2,b2> = if (a1 == a2)然后 <a1, (b1 op b2)> else undefined

最后(这就是混淆的地方),我们需要一种将元组编码为值并将值解码为元组的方法。如果值的集合是 S,那么我们需要两个函数encdec它们必须是彼此的逆函数

enc : S x S --> S(将值对编码为单个纠缠值)
dec : S --> S x S(将纠缠值解码为其分量)

enc ( dec (x)) = x 对于所有 x
dec ( enc (x)) = x 对于所有 x

例子:

  • enc取一对 16 位值并将它们嵌入到一个 32 位值 w 中,使得 x 占据 w 的低 16 位,y 占据 w 的高 16 位;dec取一个 32 位值并将它们解码成一对,其中 x 是低 16 位,y 是高 16 位。

  • enc采用一对 <x,y> 的 16 位值并将它们嵌入到一个 32 位字 w 中,使得 x 占据 w 的偶数位位置,而 y 占据 w 的奇数位位置(即,它们的位是交错的);dec采用 32 位值 w 并将它们解码为一对 <x,y> 使得 x 由 w 的偶数位组成,y 由 w 的奇数位组成。

实施注意事项

从实现的角度来看,我们希望能够直接对值的编码表示执行操作。为此,对应于上面的每个操作op1op2,我们需要定义必须满足以下健全性标准的“编码”版本op1*op2*

对于所有 x1、x2 和 y: x1 op1* x2 = y IFF enc ( dec (x1) op1 dec (x2) ) = y

op2*类似

省略了很多细节(大多数很容易解决),并且可以通过各种方式美化这种基本方法,但我不知道这是否符合您的要求,也不知道这是否非常简单你已经为自己解决了所有问题。无论如何,我希望这是有用的。


从@perror 的评论(如下)看来,上面的形式化显然不够强大,无法捕捉到他想到的混淆(尽管可能会从概括编码/解码函数encdec 中获得一些好处)。

我忘记了这篇论文,它讨论了一个似乎相关的转换(参见第 6.1 节,“拆分变量”):

克里斯蒂安·科尔伯格、克拉克·汤姆森和道格拉斯·洛。打破抽象和解构数据结构。IEEE 计算机语言国际会议(ICCL'98),1998 年 5 月。(链接