type
status
date
slug
summary
tags
category
icon
password
基本块分割是什么
基本块分割是将一个基本块分割为等价的若干个基本块,在分割后的基本块之间 加上无条件跳转(等价代换)
基本块分割不能算是混淆,但是可以提高某些代码混淆的混淆效果 (需要结合使用其他混淆技术)
对基本块进行分割的好处
- 在许多基于基本块的代码混淆中,基本块数量越多,代码混淆后的复杂度越大
- 通过增加基本块的数量,可以到达提高混淆效果的目的
实现思路
- 遍历每个函数中的每个基本块,对每个基本块进行分割即可
- 注意,有 PHI 指令的基本块我们选择跳过 (不跳过的话, 分割完的基本块,phi 指令会错误的识别前基本快)
使用到的 API
- 额外参数指定 (我们可以自定义下分割参数)
- SplitBasicBlock(主要的 api,实现基本块的分割)
- Isa<>函数
额外参数指定
在 LLVM 中,可以通过 cl:: opt 模板类获取指令中的参数,这里的 opt 是选
项 option 的缩写,不是优化器 opt 的意思
SplitBasicBlock 函数
splitBasicBlock 函数是 BasicBlock 类的一个成员函数。
可以去 BasicBlock. h 头文件里看这个函数的两种用法, 一种是用迭代器,一种是用 instrucktion实现
isa<> 函数
isa<> 是一个模板函数,用于判断一个指针指向的数据的类型是不是给定的类型,类似于 Java 中的 instanceof。
我们主要用这个判断基本块是否存在 PHI 指令
代码实现
目录
SplitBasicBlock. cpp
SplitBasicBlock. h
我们在 llvm 命名空间里添加一个函数 FunctionPass* createSplitBasicBlockPass (); 。
这个函数将在SplitBasicBlock.cpp里实现。
这样的话其他 LLVM Pass 就可以通过引入头文件 SplitBasicBlock. h
调用 createSplitBasicBlockPass 函数来创建一个 SplitBasicBlock Pass,完成基本块的分割。
这就是 c++封装的简单应用
CMakeLists. txt
Test.sh
最后
我们把编译完的可执行文件丢进 ida 里面
好像我们的基本块分割,没有啥作用,这是为什么呢?
因为在编译过程中被优化器给优化了,简单来说就是你写一个字符串数组丢进 ida 反编译,ida 把你优化成了字符串,本来是一个一个的,给你优化回去了
不过后面基本块的分割与 OLLVM 的联动产生的威力,可以期待一下