LLVM的IR中字符串的形式:
字符串常量和字符数组都是ConstantDataSequential(CDS)
所有的字符串字面量, 都是i8/i16数组,
匿名的字符串常量为@.str(.n) = private unnamed_addr constant
具名的字符数组为@name = global 或 @name = internal constant
空的字符串字面量为private unnamed_addr constant [1 x i8] zeroinitializer
关于常量表达式退化:
将load,store,call等指令中的gep,bistcast等生成一条独立的指令, 方便后续进行处理
getAsInstruction + setOperand或replaceUsesOfWith
处理之后, 所有对GV的引用都只能是Inst的直接operand
所有的字符串字面量都是全局CDS
只存在指令直接引用全局CDS或者指令通过CA,CS,i8*等间接引用CDS
加密解密方案分析
Pass处理在IR中要找到所有的字符串常量是比较容易的, 直接遍历module->globals即可,
但是问题的关键是, 加密范围, 解密时机和解密存储位置, 目前来说开源方案的几种方案:
加密范围:
1: 指令中直接引用的CDS
2: 指令中间接引用的CDS
解密时机:
1: ctor解密
2: Function入口解密
3: Instruction前解密
解密存储位置:
1: 解密到段上
2: 解密到栈上
下面详细说说这几种方式的优缺点和局限性
解密时机:
1: