什么是OLLVM的平坦化
控制流平坦化 是 OLLVM 提供的一种代码混淆技术。它的核心目标是破坏程序原始的控制流结构,使其变得难以阅读和分析,从而增加逆向工程和破解的难度。
OLLVM的平坦化是如何实现的?
原始代码:
1 | int main() { |
经过平坦化后:
- 创建“分发器”和一个状态变量:
- 引入一个状态变量(例如
state),它决定了下一个要执行哪个基本块。 - 创建一个循环结构作为分发器,其内部是一个巨大的
switch-case语句,case的值就是state的值。
- 引入一个状态变量(例如
- 拆分原始基本块:
- 将原始函数中的所有基本块(除了入口块)都提取出来。
- 为每个基本块分配一个唯一的状态值(例如,原始块
B对应state = 2)。
- 重写基本块末尾的指令:
- 这是最关键的一步。修改每个基本块的结束指令(如
jmp,br,ret),使其不再是直接跳转到下一个块,而是更新状态变量state,然后跳回到分发器循环。 - 例如,原始基本块
A执行完后应该跳转到块B。平坦化后,块A的末尾被修改为state = 2; goto dispatcher;。
- 这是最关键的一步。修改每个基本块的结束指令(如
- 在分发器中调度:
- 分发器循环不停地检查
state的值,然后通过switch-case跳转到对应的基本块去执行。 - 执行完的基本块会设置新的
state,然后跳回分发器,分发器再根据新的state调度下一个基本块。
- 分发器循环不停地检查
平坦化后的伪代码结构:
1 | int main() { |
如何去OLLVM的平坦化
法一
首先我要下载这个deflat这个工具,将py文件和要处理的文件放在同一个目录中
1 | python deflat.py -f OLLVM-deflat --addr 0x4006F0 |
起始地址用IDA查看,比如main的起始地址。
本题
1 | python deflat.py -f OLLVM-deflat --addr 0x4006F0 |
让我们来看看效果
未去:


已去:


很明显去除后逻辑更加清晰。
去除后再开始解题:
general_inspection验证sudoku的合法性
1 | __int64 __fastcall general_inspection(int (*a1)[9]) |
trace对sudoku进行求解
1 | void __fastcall trace(__int64 a1, int *a2, int a3) |
check1
- 前半部分与后半部分交换
- 每对相邻字符交换
- 位操作和算术变换
1 | size_t __fastcall check1(char *a1) |
check3就是个验证函数
check2检查输入字符串是否能正确填充一个数独网格
提取数独
1 | 1 0 5 3 2 7 0 0 8 |
求解数独
1 | def is_valid(board, row, col, num): |
1 | def build_reverse_map(): |
法二
D810去平坦化插件使用
把文件夹和.py复制到IDA目录的plugin下即可

效果很好。