代码混淆与保护

发布时间:2026/5/20 7:22:40

代码混淆与保护 Day 27: 代码混淆与保护代码保护技术用于防止软件被逆向工程和破解。本章介绍常见的代码混淆、虚拟化保护和加壳技术以及对应的分析方法。1. 控制流混淆1.1 控制流平坦化 (Control Flow Flattening)将正常的控制流结构打散用一个大的 switch 语句分发原始代码voidoriginal(){step1();if(condition){step2();}else{step3();}step4();}平坦化后voidflattened(){intstate1;while(state!0){switch(state){case1:step1();state2;break;case2:statecondition?3:4;break;case3:step2();state5;break;case4:step3();state5;break;case5:step4();state0;break;}}}在 IDA 中表现为一个巨大的 switch 块难以理解逻辑。对抗方法使用符号执行恢复控制流IDA 插件D-810手动分析状态转移1.2 虚假控制流 (Bogus Control Flow)插入永远不会执行的分支voidbogus_cf(){if((x*x)0){// 永远为真real_code();}else{// 永远不执行但增加分析难度fake_code();}}使用不透明谓词Opaque Predicate编译时难以确定运行时恒为真/假。1.3 指令替换 (Instruction Substitution)用等价但更复杂的指令序列替换简单指令原始替换add eax, 1sub eax, -1xor eax, eaxsub eax, eax或and eax, 0mov eax, 0xor eax, eax然后add eax, 0a ba b ^ c ^ c1.4 常量混淆运行时计算常量值// 原始key0x12345678;// 混淆后a0x11111111;b0x01234567;keyab;// 运行时计算或使用复杂的数学运算key((0x48d159e2^0x5ae40f9a)*3-0x12345678)0xFFFFFFFF;2. 数据混淆2.1 字符串加密字符串是逆向的重要线索通常会被加密// 加密的字符串unsignedcharencrypted[]{0x48,0x65,0x6c,0x6c,0x6f};charkey0x00;// 运行时解密for(inti0;isizeof(encrypted);i){encrypted[i]^key;}// 现在 encrypted Hello分析方法找到解密函数提取解密后的字符串使用 IDAPython 脚本批量解密动态调试在解密后断点2.2 变量拆分将一个变量拆成多个// 原始intsecret0xDEADBEEF;// 拆分后intpart10xDEAD0000;intpart20x0000BEEF;intsecretpart1|part2;3. 代码虚拟化3.1 原理将原始机器码转换为自定义的字节码运行时由嵌入的虚拟机解释执行原始 x86 代码 → 编译器 → 自定义字节码 ↓ 嵌入的 VM 解释器 ↓ 执行3.2 VM 结构典型的虚拟机包含字节码自定义的指令集分发器读取字节码跳转到对应处理器处理器每个虚拟指令的实现虚拟寄存器/栈保存 VM 状态voidvm_execute(unsignedchar*bytecode){unsignedchar*pcbytecode;intregs[16]{0};intstack[1024];intsp0;while(1){unsignedcharopcode*pc;switch(opcode){case0x01:// PUSH immstack[sp]*(int*)pc;pc4;break;case0x02:// POP regregs[*pc]stack[--sp];break;case0x03:// ADDstack[sp-2]stack[sp-1];sp--;break;case0xFF:// EXITreturn;// ... 更多指令}}}3.3 商业保护方案产品特点VMProtect代码虚拟化 反调试 授权系统Themida多层保护虚拟化强度高Code Virtualizer轻量级虚拟化Obsidium综合保护方案3.4 分析方法识别 VM 入口找到分发器循环分析指令集逆向每个处理器提取字节码dump 受保护的字节码反编译将字节码转回伪代码工具VMAttack - IDA 插件NoVmp - VMProtect 分析4. 加壳技术4.1 壳的作用压缩减小体积加密保护代码反调试反 dump4.2 常见壳开源/免费UPX - 压缩壳可直接脱MPRESS - 类似 UPX商业壳VMProtect - 虚拟化保护Themida/WinLicense - 强保护ASProtect - 老牌保护Enigma Protector4.3 脱壳流程识别壳类型# 使用 DIE (Detect It Easy)die.exe target.exe找到 OEP (Original Entry Point)硬件断点法内存断点法单步跟踪法dump 内存在 OEP 处 dump 进程内存工具Scylla、PE-Bear修复 IAT (Import Address Table)使用 Scylla 重建导入表4.4 UPX 脱壳示例# 直接脱壳如果没有修改upx-dpacked.exe-ounpacked.exe# 如果修改了 UPX 标识手动脱壳# 1. 运行程序# 2. 在 popad/jmp 处断点# 3. 跳转后就是 OEP# 4. dump5. 代码完整性检查5.1 校验和检测检测代码是否被修改unsignedintcalculate_checksum(void*start,size_tlen){unsignedintsum0;unsignedchar*p(unsignedchar*)start;for(size_ti0;ilen;i){sump[i];}returnsum;}voidcheck_integrity(){unsignedintexpected0x12345678;// 预计算的值unsignedintactualcalculate_checksum(code_start,code_size);if(actual!expected){// 代码被修改}}5.2 API Hook 检测检测关键函数是否被 hookvoidcheck_hook(){unsignedchar*func(unsignedchar*)IsDebuggerPresent;// 检查函数开头是否是跳转指令if(func[0]0xE9||func[0]0xEB){// JMP// 可能被 hook}}6. 对抗混淆的方法6.1 动态分析在关键点断点观察实际行为记录执行轨迹使用符号执行6.2 模式识别识别混淆框架LLVM-Obfuscator、Tigress 等应用对应的去混淆脚本6.3 自动化工具Miasm- 符号执行框架Triton- 动态二进制分析angr- 二进制分析平台7. 练习练习 1识别混淆给定一个混淆的程序识别使用了哪些混淆技术。练习 2UPX 脱壳用 UPX 加壳一个程序手动脱壳不使用 upx -d练习 3字符串解密分析一个加密字符串的程序提取所有字符串。本章总结代码保护技术层次层次技术分析难度基础字符串加密简单中级控制流混淆中等高级代码虚拟化困难综合商业保护壳非常困难分析策略先判断保护类型和强度优先尝试动态分析使用自动化工具辅助必要时深入静态分析扩展资源LLVM-Obfuscator - 开源混淆器Tigress - C 代码混淆器UnpacMe - 在线自动脱壳《Practical Binary Analysis》第 10 章

相关新闻