免杀专题
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:字符串混淆(必做)
- 实现字符串加密宏
- 应用到敏感API名称
6.2、作业2:控制流平坦化(进阶)
- 手动实现简单的控制流平坦化
- 用IDA分析效果
7. 下一课预告
下一课我们将学习函数调用序列欺骗技术。