代码混淆技术系列
LLVM 基本块分割
00 分钟
2022-12-19
2024-11-11
type
status
date
slug
summary
tags
category
icon
password

基本块分割是什么

基本块分割是将一个基本块分割为等价的若干个基本块,在分割后的基本块之间 加上无条件跳转(等价代换)
notion image
基本块分割不能算是混淆,但是可以提高某些代码混淆的混淆效果 (需要结合使用其他混淆技术)

对基本块进行分割的好处

  • 在许多基于基本块的代码混淆中,基本块数量越多,代码混淆后的复杂度越大
  • 通过增加基本块的数量,可以到达提高混淆效果的目的
    • notion image

实现思路

  1. 遍历每个函数中的每个基本块,对每个基本块进行分割即可
  1. 注意,有 PHI 指令的基本块我们选择跳过 (不跳过的话, 分割完的基本块,phi 指令会错误的识别前基本快)

使用到的 API

  1. 额外参数指定 (我们可以自定义下分割参数)
  1. SplitBasicBlock(主要的 api,实现基本块的分割)
  1. Isa<>函数

额外参数指定

在 LLVM 中,可以通过 cl:: opt 模板类获取指令中的参数,这里的 opt 是选 项 option 的缩写,不是优化器 opt 的意思

SplitBasicBlock 函数

splitBasicBlock 函数是 BasicBlock 类的一个成员函数。 可以去 BasicBlock. h 头文件里看这个函数的两种用法, 一种是用迭代器,一种是用 instrucktion实现

isa<> 函数

isa<> 是一个模板函数,用于判断一个指针指向的数据的类型是不是给定的类型,类似于 Java 中的 instanceof。 我们主要用这个判断基本块是否存在 PHI 指令

代码实现

目录

notion image

SplitBasicBlock. cpp

SplitBasicBlock. h

我们在 llvm 命名空间里添加一个函数 FunctionPass* createSplitBasicBlockPass (); 。 这个函数将在SplitBasicBlock.cpp里实现。 这样的话其他 LLVM Pass 就可以通过引入头文件 SplitBasicBlock. h 调用 createSplitBasicBlockPass 函数来创建一个 SplitBasicBlock Pass,完成基本块的分割。 这就是 c++封装的简单应用

CMakeLists. txt

Test.sh

最后

我们把编译完的可执行文件丢进 ida 里面
notion image
 
notion image
好像我们的基本块分割,没有啥作用,这是为什么呢? 因为在编译过程中被优化器给优化了,简单来说就是你写一个字符串数组丢进 ida 反编译,ida 把你优化成了字符串,本来是一个一个的,给你优化回去了
不过后面基本块的分割与 OLLVM 的联动产生的威力,可以期待一下

参考于

上一篇
常见代码混淆技术汇总
下一篇
搞定ida结构体和导入sig签名库