论坛首页 逆向工程技术区 阅读主题

[原创]OLLVM扁平化还原—新角度:状态机

144 浏览 14 回复
#1 楼主 2026-06-01 21:09:10
[原创]安卓逆向的核心流程里面分享了安卓逆向技能树的“树干”。“树干”上有多个“树枝”,其中有一个就是“混淆还原”,用来还原复杂难懂的代码。然后这个“树枝”上又有多个“树叶”,接下来分享的就是里面的“扁平化还原”。
  大多OLLVM扁平化还原的核心思路是基于:块关系。
  这篇文章从另外一个角度进行还原:状态机。
  样本来自:[原创]OLLVM控制流平坦化混淆还原,目标函数:.init_proc

  先说一下对OLLVM扁平化的理解

  正常一个函数,会有多个基本块,逻辑清晰  函数通过OLLVM扁平化之后,逻辑变得复杂  所谓的扁平化,本质上是用状态机的方式对所有基本块进行重新调度。
  原本直观的层次关系被抹除,所有基本块扁平成一排,从而提高静态分析的成本。
  更形象地理解:一本书本来是章节结构清晰的,扁平化后每一段后面写着下一段的编号,要去找到这个编号才能串起来。  这里先梳理一下状态机的调度过程,后续还原要用到:
  因为改变状态之后,都会回到分发器:goto dispatcher,这就意味着dispatcher引用有很多个
  这个函数只有一个集中返回的点,这里简单粗暴定为引用最多次数就是dispatcher。  对应可以写一个找dispatcher的脚本  0x43120对应有29个引用


  状态寄存器存放状态值,分发器根据状态值进行调度,举个例子:  对应可以写一个找状态寄存的脚本:  调度过程都是:改变状态+返回分发器
  返回分发器直接找:B dispatcher_ea
  改变状态有2种情况:  对应的可以写一个寻找改变状态块的脚本  先比较状态,再执行基本块,具体有2种情况:  对应的可以写一个寻找命中状态块的脚本  OLLVM扁平化的还原,实际上是去掉分发器,从而还原基本块的关系  上面说到基本块的结束有2种情况,所以还原扁平化的脚本要处理2种情况:还原之前:逻辑复杂,总共181行
还原之后:逻辑清晰,总共53行,是原来的29%


  基于状态机的角度进行还原,关键的步骤如下:实战过程遇到的情况会复杂很多,比如:
  1、同个函数里面存在多个分发器;
  2、“存放状态的寄存器”和“比较状态的寄存器”不是同一个;
  3、比较状态不是直接判断值是否相等,而是用等价的表达式。
  如果代码写得好,一键还原还挺爽的。  PS:块关系的角度,是先对所有基本块进行分类,再找出真实块之间的关联。但真实块之间的关联需要执行才知道(真机trace、模拟运行或者符号执行)。int demo(int x) {

---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-288598.htm
#2 2026-06-01 21:09:10
感谢分享
#3 2026-06-01 21:09:10
感谢分享
#4 2026-06-01 21:09:10
看看隐藏
#5 2026-06-01 21:09:10
感谢分享
#6 2026-06-01 21:09:10
感谢分享
#7 2026-06-01 21:09:10
感谢分享
#8 2026-06-01 21:09:10
感谢分享
#9 2026-06-01 21:09:10
学习学习
#10 2026-06-01 21:09:10
学习学习
#11 2026-06-01 21:09:10
学下,谢谢
#12 2026-06-01 21:09:10
说是新思路,看下
#13 2026-06-01 21:09:10
跟我的思路一样,果然天才的想法都是一样的!
#14 2026-06-01 21:09:10
牛逼
#15 2026-06-01 21:09:10
逆天而行


跟我的思路一样,果然天才的想法都是一样的![em_013]

不,你是逆天

请登录后参与讨论

立即登录 注册账号