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

针对市面上常规 IDA 静态插件难以处理双循环头、汇聚块与循环头合并这类高变异 OLLVM 控制流混淆的痛点,最优解决路径是依托 Angr 符号执行动态运行程序,顺着真实执行链路定位全部有效代码基本块,依托 BFS 算法识别循环头、区分序言块与汇聚块,针对性拆解 cmov 系列条件传送指令带来的隐性分支,再通过 Hook 分发器指令、精准地址偏移跳转、无效代码 NOP 填充完成控制流修复,搭配 IDA Python 自动化脚本批量识别真实代码块,形成一套可适配各类变异 OLLVM 版本的通用解混淆工作流。

一、核心问题梳理

1.1 OLLVM 混淆基础逻辑回顾

OLLVM 核心防护逻辑为打散原生程序控制流,借助独立分发器统一调度程序执行走向,业内熟知序言块、后继跳转、全局分发器基础概念,常规防护版本依靠固定跳转扰乱流程。

1.2 传统静态逆向方案现存硬伤

当下主流静态解混淆工具(D810 等 IDA 插件)仅适配基础版 OLLVM,面对定制化变异改造版本会彻底失效,典型失效场景: 1)程序出现双循环头结构,静态分析无法区分主循环与嵌套循环; 2)汇聚块和循环头进行代码融合,静态 CFG 识别错乱; 3)cmovxx 条件指令暗藏隐性分支,静态无法判定两条分支真实走向; 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,批量抓取数十个真实业务代码块,完整输出地址清单。

步骤 3:Angr 符号执行拆解 cmovxx 隐性分支,追踪真实块后继关系

技术难点说明

cmovnz、cmovz 这类条件传送指令不会产生显式跳转分支,Angr 默认符号执行只会累积约束条件,无法自动拆分两条不同寄存器状态下的执行路径,必须手动复制执行状态分别模拟 ZF 标志位为 0、1 两种场景。

标准化处理步骤

1)Hook 主分发器末尾指令,执行时强制跳转到目标真实块地址,调试中实测需要-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_libs=False,避免外部库符号干扰本机符号执行路径。

五、整体方案结论

这套以 "IDA 静态初筛真实块 + Angr 动态符号执行溯源路径" 组合的解法,彻底解决静态逆向面对变异 OLLVM 的天然短板,依托 BFS 精准锁定循环架构,针对性破解 cmov 隐性分支这类静态分析盲区,整套逻辑具备极强通用性,仅需要微调少量地址偏移、过滤阈值参数,即可适配绝大多数经过二次改造的 OLLVM 控制流混淆样本,从人工逆向拆解转化为标准化自动化逆向流水线,大幅缩减逆向人员处理加固样本的时间成本,无需吃透每一处混淆细节,依靠标准化流程即可完成控制流还原,不管是 CTF 逆向解题还是商业加固程序脱混淆分析都具备很高落地价值。

CTA

将本文整套脚本根据自身目标样本架构、编译环境完成参数适配调试,代入手中带 OLLVM 防护的测试样本完整跑通自动化解混淆流程,记录执行过程中报错信息,对照文中踩坑要点逐一修正,形成专属自用的 OLLVM 一键去混淆工具包,后续遇到同类防护样本直接复用这套工作流高效拆解分析。

相关推荐
@Mr_LiuYang1 小时前
《深入理解 AI Agent:设计原理与工程实践 》实验1-1上下文的关键作用
人工智能
大模型丫丫1 小时前
MCP协议开发实战:从零搭建AI Agent工具链
人工智能
wangxin2081 小时前
大模型稀疏注意力和MoE的宽度丢失与多智能体的维度补充
人工智能·ai·多智能体·管理学·组织管理·coordclaw·稀释注意力
ZEB11061 小时前
深耕矿山智能赛道 长沙迪迈科技以持续技术创新赋能矿业高质量转型
人工智能·科技·制造
一碗白开水一1 小时前
入门实践工程四:基于 PyTorch 的手写数字识别(MNIST 图像分类)|附:环境依赖环境及工程源码
人工智能·pytorch·分类
A15362551 小时前
2026 电商物流系统推荐:多渠道仓配履约数字化选型指南
大数据·数据库·人工智能
SEO_juper1 小时前
2026年Schema自动注入实战:用Python批量给1000个页面加上JSON-LD,AI引用率实测提升38%
人工智能·python·json·seo·独立站
雪的季节1 小时前
不安装YOLO只安装 PyTorch,加载已有yolo数据,从无到有创建模型训练数据并加载使用(重要)
人工智能·pytorch·yolo
超智算科技1 小时前
超智算领衔协办“NVIDIA创业企业展示·西安站”,全栈AI服务赋能行业生态协同发展
大数据·网络·人工智能·物联网·百度