Alcatraz 是一个 x64 二进制混淆器,能够混淆多种不同的 PE 文件,包括:
安装:https://vcpkg.io/en/getting-started.html
asmjit:vcpkg.exe install asmjit:x64-windows
Zydis:vcpkg.exe install zydis:x64-windows
1.) 点击左上角的 file 加载一个二进制文件。
2.) 展开 Functions 树,添加函数。(你可以通过在顶部的搜索栏中输入名称来搜索)
3.) 点击 compile(注意:混淆大量函数可能需要几秒钟)
在接下来的展示中,所有其他功能(除了当前展示的)均被禁用。
如果一个立即数被移入寄存器,我们通过应用多个位运算来混淆它。让我们看看流行的函数 _security_init_cookie。
混淆前:
混淆后:

通过移除编译器生成的整洁程序结构,并将我们的代码放入新生成的块中,我们增加了程序的复杂性。以这个简单的 main 函数为例(该程序的优化已禁用):

如果我们将其丢入 IDA 7.6,反编译器会对其进行优化:

现在让我们平坦化其控制流,并让 IDA 再次分析:

如你所见,尽管我只展示了生成代码的一小部分,但复杂性大大增加。如果你想看看其 CFG 是什么样子:

如果一个寄存器(例如 RAX)被加到另一个寄存器(例如 RCX),我们将对该指令进行变异。这意味着语法改变但语义不变。
指令 ADD RCX, RAX 可以被变异为:
push rax
not rax
sub rcx, rax
pop rax
sub rcx, 1
如果你想了解更多关于变异的细节,请查看 perses。
如果 PE 文件是 .exe(.dll 支持将稍后添加),我们将创建一个自定义入口点,在启动时解密真实的入口点(!!!当被手动映射时不起作用)。

Lea 混淆非常简单但有效。我们将一个不同的地址移入寄存器,然后在之后解密它。这样,逆向工程师无法交叉引用某些数据/函数。
假设我们找到以下指令:lea rcx, [0xDEAD]
我们将将其变异为:
pushf
lea rcx, [1CE54]
sub rcx, EFA7
popf
rcx -> 0xDEAD
如果我们找到一条以字节 0xFF 开头的指令,我们会在其前面放置一个 0xEB。
我们这样做是因为 0xEB 0xFF 编码为 jmp rip + 1,最终会跳转到我们实际的第一个 0xFF。这会让以线性方式解码指令的工具出错。
反反汇编前:

反反汇编后:

有时我们可以插入:
jz 3
jne 1
0xE8
IDA 会尝试解码 0xE8(call),但不会成功:

目前没有“适当的” IAT 混淆。0xFF 反反汇编技巧暂时处理了这一点。计划在此处实现正确的方法:
iat.cpp
这是我们的 main 函数的一个片段,除了反反汇编外所有功能都启用(这样 IDA 可以创建一个函数):
