免杀专题

30、代码混淆

1. 课程目标

学习代码混淆技术,增加逆向分析难度。


2. 混淆技术分类

技术 说明
控制流混淆 打乱代码执行顺序
数据混淆 隐藏真实数据
字符串混淆 加密敏感字符串
符号混淆 混淆函数/变量名

3. 控制流混淆

3.1 控制流平坦化

// 原始代码
void original() {
    step1();
    step2();
    step3();
}

// 平坦化后
void flattened() {
    int state = 0;
    while (1) {
        switch (state) {
            case 0: step1(); state = 1; break;
            case 1: step2(); state = 2; break;
            case 2: step3(); state = 3; break;
            case 3: return;
        }
    }
}

3.2 虚假控制流

void ObfuscatedFunc() {
    int x = GetTickCount();
    
    if ((x * x) % 2 == 2) {  // 永远为假
        ExitProcess(0);
    }
    
    // 真正代码
    DoRealWork();
    
    if (x < 0 && x > 0) {  // 永远为假
        format("C:");
    }
}

4. 字符串混淆

4.1 编译时加密

// 编译时加密的字符串
#define ENCRYPT_CHAR(c) ((c) ^ 0x55)

char encrypted_str[] = {
    ENCRYPT_CHAR('H'),
    ENCRYPT_CHAR('e'),
    ENCRYPT_CHAR('l'),
    ENCRYPT_CHAR('l'),
    ENCRYPT_CHAR('o'),
    0
};

void DecryptString(char* str) {
    while (*str) {
        *str ^= 0x55;
        str++;
    }
}

4.2 运行时构造

void GetKernel32() {
    char name[20];
    name[0] = 'K';
    name[1] = 'e';
    name[2] = 'r';
    // ...动态构造字符串
    
    HMODULE h = GetModuleHandleA(name);
}

5. 数据混淆

// 隐藏常量
#define OBFUSCATE(x) ((x) ^ 0x12345678)
#define DEOBFUSCATE(x) ((x) ^ 0x12345678)

int GetHiddenValue() {
    int encrypted = OBFUSCATE(12345);  // 编译时加密
    return DEOBFUSCATE(encrypted);     // 运行时解密
}

6. 课后作业

6.1、作业1:字符串混淆(必做)

  1. 实现字符串加密宏
  2. 应用到敏感API名称

6.2、作业2:控制流平坦化(进阶)

  1. 手动实现简单的控制流平坦化
  2. 用IDA分析效果

7. 下一课预告

下一课我们将学习函数调用序列欺骗技术。