llvm代码混淆学习(二)
写在前面
随便学学 llvm 代码混淆,顺便做个毕设,水几篇文章就当做做笔记
LLVM Pass 常用 API
LLVM Pass 框架中,三个最核心的类是 Function
、BasicBlock
和Instruction
,分别对应 LLVM IR 中的函数、基本块和指令,还有一个基本类Value
,所有可以被当作指令操作数的类型都是 Value
的子类
Function 类
与 Function 有关的操作主要是获取函数的一些属性,比如名称等等,以及对函数中基本块的遍历:
- 获取函数名称:F.getName()
- 获取入口快:F.getEntryBlock()
- 函数中基本块的遍历
可以通过 foreach 循环对函数 Function 中的每个基本块 BasicBlock 进行遍历
1 | bool runOnFunction(Function &F){ // 使用引用是为了能修改传入参数Function类 |
BasicBlock 类
与 BasicBlcok 有关的操作主要是基本块的克隆、分裂、移动等,以及对基本块中指令的遍历:
- 获取基本块名称:BB.getName()
- 获取基本块的终结指令:BB.getTerminator()
- 基本块的克隆
- 基本块的分裂
- 基本块的移动
- 基本块中指令的遍历
可以通过 foreach 循环对基本块 BasickBlock 中的每个指令 Instruction 进行遍历
1 | bool runOnFunction(Function &F){ // 使用引用是为了能修改传入参数Function类 |
Instruction 类
指令可以有很多种,亦即 Instruction 类可以拥有多个子类,如:BinaryOpterator, AllocaInst, BranchInst 等
- 二元运算:BinaryOperator
- 内存访问和寻址:
- Allocalnst
- StoreInst
- LoadInst
- 分支指令:
- Branchlnst
- Switchlnst
- 其他指令
- Calllnst
- ICmplnst
- PHINode
与 Instruction 有关的操作主要是指令的创建、删除、修改以及指令中操作数的遍历:
可以通过 for 循环对指令 Instruction 中的每个操作数 Value* 进行遍历
1 | bool runOnFunction(Function &F){ // 使用引用是为了能修改传入参数Function类 |
Value 类
所有可以被当做指令操作数的类型都是 Value 的子类,Value 有以下五种类型的子类
- 常量:Constant
- 参数:Argument
- 指令(运算结果):Instruction
- 函数(指针):Function
- 基本块:BasicBlock
输出流
在 C++ 中可以通过 cout, cerr, clog 输出流来进行打印,在 LLVM 中则建议使用 outs(), errs(), dbgs() 三个函数来获取输出流,然后打印
1 | bool runOnFunction(Function &F){ |
LLVM 部分相关文档
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 C1everF0x的博客!