llvm代码混淆学习(二)

720 字
4 分钟
llvm代码混淆学习(二)
写在前面
随便学学 llvm 代码混淆,顺便做个毕设,水几篇文章就当做做笔记
LLVM Pass 常用 API
LLVM Pass 框架中,三个最核心的类是 Function、BasicBlock和Instruction,分别对应 LLVM IR 中的函数、基本块和指令,还有一个基本类Value,所有可以被当作指令操作数的类型都是 Value 的子类
Function 类
与 Function 有关的操作主要是获取函数的一些属性,比如名称等等,以及对函数中基本块的遍历:
- 获取函数名称:F.getName()
- 获取入口快:F.getEntryBlock()
- 函数中基本块的遍历
可以通过 foreach 循环对函数 Function 中的每个基本块 BasicBlock 进行遍历
bool runOnFunction(Function &F){ // 使用引用是为了能修改传入参数Function类 for(BasicBlock &BB : F){ // 遍历F中的基本块,同样使用引用 // to do }}BasicBlock 类
与 BasicBlcok 有关的操作主要是基本块的克隆、分裂、移动等,以及对基本块中指令的遍历:
- 获取基本块名称:BB.getName()
- 获取基本块的终结指令:BB.getTerminator()
- 基本块的克隆
- 基本块的分裂
- 基本块的移动
- 基本块中指令的遍历
可以通过 foreach 循环对基本块 BasickBlock 中的每个指令 Instruction 进行遍历
bool runOnFunction(Function &F){ // 使用引用是为了能修改传入参数Function类 for(BasicBlock &BB : F){ // 遍历F中的基本块,同样使用引用 for(Instruction &I : BB){ // 遍历BB中的指令,同样使用引用 // to do } }}Instruction 类
指令可以有很多种,亦即 Instruction 类可以拥有多个子类,如:BinaryOpterator, AllocaInst, BranchInst 等
- 二元运算:BinaryOperator
- 内存访问和寻址:
- Allocalnst
- StoreInst
- LoadInst
- 分支指令:
- Branchlnst
- Switchlnst
- 其他指令
- Calllnst
- ICmplnst
- PHINode
与 Instruction 有关的操作主要是指令的创建、删除、修改以及指令中操作数的遍历:
可以通过 for 循环对指令 Instruction 中的每个操作数 Value* 进行遍历
bool runOnFunction(Function &F){ // 使用引用是为了能修改传入参数Function类 for(BasicBlock &BB : F){ // 遍历F中的基本块,同样使用引用 for(Instruction &I : BB){ // 遍历BB中的指令,同样使用引用 for(int i = 0;i < I.getNumOperands(); i++){ Value *V = I.getOperand(i); // to do } } }}Value 类
所有可以被当做指令操作数的类型都是 Value 的子类,Value 有以下五种类型的子类
- 常量:Constant
- 参数:Argument
- 指令(运算结果):Instruction
- 函数(指针):Function
- 基本块:BasicBlock
输出流
在 C++ 中可以通过 cout, cerr, clog 输出流来进行打印,在 LLVM 中则建议使用 outs(), errs(), dbgs() 三个函数来获取输出流,然后打印
bool runOnFunction(Function &F){ // 一般信息打印 outs() << "Function: " << F.getName() << "\n"; // 错误信息打印 if something wrong errs() << "Something wrong." << "\n"; // 调试信息打印 debug dbgs() << "Debug" << "\n";}LLVM 部分相关文档

文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!
llvm代码混淆学习(二)
https://c1everf0x.cn/posts/llvm-obfuscation-2/




