尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

破解变异 OLLVM 混淆新思路:基于 Angr 动态执行自动化还原控制流完整实操方案

破解变异 OLLVM 混淆新思路:基于 Angr 动态执行自动化还原控制流完整实操方案 针对市面上常规 IDA 静态插件难以处理双循环头、汇聚块与循环头合并这类高变异 OLLVM 控制流混淆的痛点最优解决路径是依托 Angr 符号执行动态运行程序顺着真实执行链路定位全部有效代码基本块依托 BFS 算法识别循环头、区分序言块与汇聚块针对性拆解 cmov 系列条件传送指令带来的隐性分支再通过 Hook 分发器指令、精准地址偏移跳转、无效代码 NOP 填充完成控制流修复搭配 IDA Python 自动化脚本批量识别真实代码块形成一套可适配各类变异 OLLVM 版本的通用解混淆工作流。一、核心问题梳理1.1 OLLVM 混淆基础逻辑回顾OLLVM 核心防护逻辑为打散原生程序控制流借助独立分发器统一调度程序执行走向业内熟知序言块、后继跳转、全局分发器基础概念常规防护版本依靠固定跳转扰乱流程。1.2 传统静态逆向方案现存硬伤当下主流静态解混淆工具D810 等 IDA 插件仅适配基础版 OLLVM面对定制化变异改造版本会彻底失效典型失效场景 1程序出现双循环头结构静态分析无法区分主循环与嵌套循环 2汇聚块和循环头进行代码融合静态 CFG 识别错乱 3cmovxx 条件指令暗藏隐性分支静态无法判定两条分支真实走向 4多层嵌套分发器、碎片化无效基本块数量庞大人工梳理成本极高。1.3 本文核心解决问题搭建一套不依赖人工逐块分析的通用化自动化方案动态执行溯源真实执行路径、自动甄别真实代码块与无效冗余块、拆分 cmov 隐性分支、批量 Patch 修复控制流适配市面上绝大多数二次修改变异后的 OLLVM 防护样本。二、分步落地执行全流程步骤 1基于 BFS 遍历识别循环头基本块执行原理OLLVM 标准结构内循环头固定存在两个前驱节点负责初始化变量、开辟栈空间的序言块收拢循环执行路径的汇聚块。采用广度优先遍历追踪程序执行路径当遍历过程中再次访问已记录路径内的基本块地址即可判定该地址为循环头。IDA Python 核心执行逻辑1构建 BFS 队列传入目标函数起始基本块记录每一轮遍历的执行路径 2遍历当前块全部后继节点入队持续迭代 3检测当前块地址是否已存在历史路径命中则标记为循环头存入集合 4遍历结束后对循环头地址升序排序首位即为程序主循环头。关键代码核心片段python运行def find_loop_head(start_ea): loop_heads set() queue deque() blcok get_basic_block(start_ea) queue.append((blcok,[])) while len(queue) 0: cur_block, path queue.popleft() if cur_block.start_ea in path: loop_heads.add(cur_block.start_ea) continue path path [cur_block.start_ea] queue.extend((s, path) for s in cur_block.succs()) all_loop_heads list(loop_heads) all_loop_heads.sort() print([]Find loop heads:,[hex(lh) for lh in all_loop_heads], -- total:,len(all_loop_heads)) return all_loop_heads步骤 2精准区分汇聚块与序言块筛选全部真实有效代码块判断规则1循环头两个前驱中前驱数量大于 1 的基本块为汇聚块 2剔除汇聚块后剩余前驱即为序言块序言块本身属于有效真实代码块 3遍历汇聚块所有前驱基本块过滤单指令跳转块体积大于 5 字节的代码块统一判定为真实业务代码块 4额外定位函数 ret 收尾块向上回溯剔除无意义单指令中转块纳入真实块清单。配套判定代码逻辑python运行def find_converge_addr(loop_head_addr): converge_addr 0 block get_basic_block(loop_head_addr) preds block.preds() pred_list list(preds) if len(pred_list) 2: for pred in pred_list: tmp_list list(pred.preds()) if len(tmp_list) 1: converge_addr pred.start_ea print([]Find converge_addr:,hex(converge_addr)) return converge_addr本次选用 [RoarCTF 2019] polyre 样本实测脚本自动识别主循环头 0x40063f、汇聚块 0x4020cc、序言块 0x400620批量抓取数十个真实业务代码块完整输出地址清单。步骤 3Angr 符号执行拆解 cmovxx 隐性分支追踪真实块后继关系技术难点说明cmovnz、cmovz 这类条件传送指令不会产生显式跳转分支Angr 默认符号执行只会累积约束条件无法自动拆分两条不同寄存器状态下的执行路径必须手动复制执行状态分别模拟 ZF 标志位为 0、1 两种场景。标准化处理步骤1Hook 主分发器末尾指令执行时强制跳转到目标真实块地址调试中实测需要-6字节地址偏移规避 Capstone 指令解码错乱问题 2识别到 cmov 系列指令后复制两份执行上下文一份满足条件执行寄存器赋值、一份不执行 3两份状态独立单步执行分别获取两条分支最终跳转的目标真实块 4记录{当前块地址:[后继地址1,后继地址2]}的映射关系 5执行完成后及时执行 unhook防止程序执行反复触发 Hook 进入死循环。步骤 4控制流 Patch 修复 无效冗余块清零操作先后顺序硬性要求1先完成全量真实块、无效块地址统计归档 2依据 Angr 抓取的块跳转关系重写原生控制流跳转逻辑 3最后对前期统计的无效混淆块整体填充 NOP 指令擦除 若颠倒顺序Patch 之后 CFG 结构变动会导致无效块识别完全失真。收尾处理函数 ret 块校验定位函数尾部 ret 指令所在基础块向上回溯过滤仅承担中转作用的单指令块保证函数收尾逻辑不会被误清理。步骤 5完整工程整合运行将 IDA 静态抓块脚本与 Angr 动态路径解析脚本串联输入样本路径、目标函数偏移地址自动化输出块映射字典基于映射字典一键完成二进制 Patch还原程序原生扁平化控制流结构。在逆向工程流程优化层面可以借助longxiapro.com内置的提示词优化模板定制适配逆向场景的批量自动化脚本编写提示词高效迭代调试验证代码逻辑。三、核心参数与关键配置对照表表格对比项目传统静态 IDA 插件方案本文 Angr 动态自动化方案适配 OLLVM 类型基础版单循环头、无 cmov 分支原生 变异版、双循环头、cmov 隐性分支、汇聚块融合识别真实块方式静态 CFG 图遍历BFS 静态初筛 符号执行动态路径验证cmov 指令处理无法解析分支走向手动拆分双执行状态精准捕获两条路径人工介入程度大量人工修正 CFG、逐块甄别全程脚本自动化仅配置样本路径与入口地址无效块清理人工标记后 NOP 填充脚本自动统计地址区间批量清零适配样本场景简单 CTF 基础 OLLVM 题目商业软件加固二次修改定制 OLLVM 防护样本执行耗时中等样本 1~3 小时人工梳理脚本全自动运行 5~15 分钟出完整结果四、实操踩坑要点总结1、地址偏移-6并非固定数值不同编译架构、指令长度环境下会出现解码异常运行报错时打印 Capstone 汇编输出微调偏移数值即可适配 2、Hook 分发器后必须执行 unhook 操作程序循环执行时重复命中 Hook 会造成死循环卡死 3、筛选真实块时不能遗漏序言块序言承载变量初始化逻辑剔除后程序 Patch 后运行逻辑错乱 4、处理 cmov 指令时必须手动跳过当前指令指针防止 Angr 重复解析同一条条件传送指令 5、ret 块回溯过程中过滤 4 字节单指令中转块避免将无效跳转中转块误判定为函数结束块 6、样本加载至 Angr 时关闭自动加载系统库auto_load_libsFalse避免外部库符号干扰本机符号执行路径。五、整体方案结论这套以 “IDA 静态初筛真实块 Angr 动态符号执行溯源路径” 组合的解法彻底解决静态逆向面对变异 OLLVM 的天然短板依托 BFS 精准锁定循环架构针对性破解 cmov 隐性分支这类静态分析盲区整套逻辑具备极强通用性仅需要微调少量地址偏移、过滤阈值参数即可适配绝大多数经过二次改造的 OLLVM 控制流混淆样本从人工逆向拆解转化为标准化自动化逆向流水线大幅缩减逆向人员处理加固样本的时间成本无需吃透每一处混淆细节依靠标准化流程即可完成控制流还原不管是 CTF 逆向解题还是商业加固程序脱混淆分析都具备很高落地价值。CTA将本文整套脚本根据自身目标样本架构、编译环境完成参数适配调试代入手中带 OLLVM 防护的测试样本完整跑通自动化解混淆流程记录执行过程中报错信息对照文中踩坑要点逐一修正形成专属自用的 OLLVM 一键去混淆工具包后续遇到同类防护样本直接复用这套工作流高效拆解分析。
返回列表