x86指令自动混淆

问题描述 投票:7回答:2

[我正在使用x86 asm混淆器,该混淆器将Intel语法代码作为字符串,并输出被混淆的等效操作码集。

这里是一个例子:

mov eax, 0x5523
or eax, [ebx]
push eax
call someAPI

成为类似:

mov eax, 0xFFFFFFFF ; mov eax, 0x5523
and eax, 0x5523     ;
push [ebx]          ; xor eax, [ebx]
or [esp], eax       ;
pop eax             ;
push 12345h         ; push eax
mov [esp], eax      ;
call getEIP         ; call someAPI
getEIP:             ;
add [esp], 9        ;
jmp someAPI         ;

这只是一个例子,我没有检查过这不会弄乱标志(它可能会弄错)。

现在,我有一个XML文档,其中列出了指令模板(例如push e*x)和可以使用的替换指令列表。

我正在寻找一种自动生成与输入结果相同的操作码序列的方法。我不介意进行有教育的暴力,但不确定如何处理此问题。

assembly automation x86 obfuscation
2个回答
15
投票

您需要的是操作码的代数描述以及一组代数定律,使您可以确定等效的运算。

然后,对于每条指令,您都要查询其代数描述(为便于举例,一个

 XOR  eax,mem[ecx]

其代数等价于

 eax exclusive_or mem[ecx]

使用那些代数等效项来枚举代数等价项,例如:

 a exclusive_or b ==> (a and not b) or (b and not a)

为您的XOR指令生成等效的代数语句

 eax exclusive_or mem[ecx] ==> (eax and not mem[ecx]) or (mem[ecx] and not eax)

您可以对此应用更多的代数定律,例如德摩根定理:

 a or b ==> not (not a and not b)

获取

(not (not (eax and not mem[ecx])) and (not (mem[ecx] and not eax)))

至此,您已经有了代数计算的说明,和原来的一样。有你的蛮力。

现在,您必须通过匹配哪些指令来将其“编译”为机器指令会用这个说的做。像任何编译器一样,您可能希望优化生成的代码(两次获取mem [ecx]毫无意义)。 (所有这些都很困难……它是一个代码生成器!)产生的代码序列类似于:

mov ebx, mem[ecx]
mov edx, ebx
not edx
and edx, eax
not eax
and eax, ebx
not eax
or eax, edx

这是很多手动构建的机械。

另一种方法是利用程序转换系统,该系统允许您将源到源的转换应用于代码。然后,您可以将“等效性”编码为直接在代码上重写。

这些工具之一是我们的DMS Software Reengineering Toolkit

DMS采用语言定义(本质上是EBNF),自动实现解析器,AST构建器和prettyprinter(反解析器,将AST转换为有效的源文本)。[DMS目前没有针对ASM86的EBNF,但是针对各种已经为DMS构建了复杂的语言,其中包括一些用于其他非x86汇编程序的语言因此,您必须将ASM86 EBNF定义为DMS。这非常简单; DMS有一个非常强大的解析器生成器]。

使用DMS,您可以直接在代码上编写源代码转换。您可以编写以下转换来直接实现XOR等价法和DeMorgan定律:

  domain ASM86;

  rule obfuscate_XOR(r: register, m: memory_access):instruction:instruction
  =  " XOR \r, \m " 
      rewrites to
     " MOV \free_register\(\),\m
       NOT \free_register\(\)
       AND \free_register\(\),\r 
       NOT \r
       AND \r,\m
       OR \r,\free_register\(\)";

 rule obfuscate_OR(r1: register, r2: register):instruction:instruction
 = " OR \r1, \r2"
     rewrites to
    " MOV \free_register\(\),\r1
      NOT \free_register\(\)
      AND \free_register\(\),\r2
      NOT \r2
      AND \r1,\r2
      NOT \r1";

在称为“ free_register”的元过程中具有一些附加的魔术,它确定了哪些寄存器在代码中(AST匹配)的那一刻是免费的。 (如果您不想这样做,请使用堆栈顶部就像您在示例中一样在任何地方都是临时的)。

您需要使用大量的重写程序来覆盖所有想要混淆的情况,并使用带有寄存器和内存操作数的组合器。

然后,可以要求转换引擎在代码的每个点上随机地一次或多次应用这些转换,以便对其进行加扰。

您可以看到fully worked example of some algebraic transforms being applied with DMS.


0
投票

看看Obfusion项目。它可以很好地混淆Obfusion x86。但是,它似乎不支持shellcode。不过,该项目中的大多数代码,算法和想法都可以满足您的需求。

另外一个值得研究的很好的项目是shellcode,但它适用于通过宏对64-bit源代码进行模糊处理。

© www.soinside.com 2019 - 2024. All rights reserved.