1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
// llvm/lib/Transforms/Obfuscation/StringEncryption.cpp
for (CSPEntry *Entry: ConstantStringPool) {
// 生成enckey,针对每个module不同
getRandomBytes(Entry->EncKey, 16, 32);
// 每个字符串进行加密
for (unsigned i = 0; i < Entry->Data.size(); ++i) {
Entry->Data[i] ^= Entry->EncKey[i % Entry->EncKey.size()];
}
// 为每个module的解密函数生成
Entry->DecFunc = buildDecryptFunction(&M, Entry);
}
void StringEncryption::getRandomBytes(std::vector<uint8_t> &Bytes, uint32_t MinSize, uint32_t MaxSize) {
uint32_t N = RandomEngine.get_uint32_t();
uint32_t Len;
assert(MaxSize >= MinSize);
if (MinSize == MaxSize) {
Len = MinSize;
} else {
Len = MinSize + (N % (MaxSize - MinSize));
}
char *Buffer = new char[Len];
RandomEngine.get_bytes(Buffer, Len);
for (uint32_t i = 0; i < Len; ++i) {
Bytes.push_back(static_cast<uint8_t>(Buffer[i]));
}
delete[] Buffer;
}
Function *StringEncryption::buildDecryptFunction(Module *M, const StringEncryption::CSPEntry *Entry) {
LLVMContext &Ctx = M->getContext();
IRBuilder<> IRB(Ctx);
// 根据开头所说,module包含func、func包含块,因此创建逻辑也根据此
FunctionType *FuncTy = FunctionType::get(Type::getVoidTy(Ctx), {IRB.getInt8PtrTy(), IRB.getInt8PtrTy()}, false);
// 函数创建
Function *DecFunc =
Function::Create(FuncTy, GlobalValue::PrivateLinkage, "goron_decrypt_string_" + Twine::utohexstr(Entry->ID), M);
// 参数
auto ArgIt = DecFunc->arg_begin();
Argument *PlainString = ArgIt; // output
++ArgIt;
Argument *Data = ArgIt; // input
PlainString->setName("plain_string");
PlainString->addAttr(Attribute::NoCapture);
Data->setName("data");
Data->addAttr(Attribute::NoCapture);
Data->addAttr(Attribute::ReadOnly);
// 创建块
BasicBlock *Enter = BasicBlock::Create(Ctx, "Enter", DecFunc);
BasicBlock *LoopBody = BasicBlock::Create(Ctx, "LoopBody", DecFunc);
BasicBlock *UpdateDecStatus = BasicBlock::Create(Ctx, "UpdateDecStatus", DecFunc);
BasicBlock *Exit = BasicBlock::Create(Ctx, "Exit", DecFunc);
IRB.SetInsertPoint(Enter);
ConstantInt *KeySize = ConstantInt::get(Type::getInt32Ty(Ctx), Entry->EncKey.size());
Value *EncPtr = IRB.CreateInBoundsGEP(Data, KeySize);
Value *DecStatus = IRB.CreateLoad(Entry->DecStatus);
Value *IsDecrypted = IRB.CreateICmpEQ(DecStatus, IRB.getInt32(1));
IRB.CreateCondBr(IsDecrypted, Exit, LoopBody);
IRB.SetInsertPoint(LoopBody);
PHINode *LoopCounter = IRB.CreatePHI(IRB.getInt32Ty(), 2);
LoopCounter->addIncoming(IRB.getInt32(0), Enter);
Value *EncCharPtr = IRB.CreateInBoundsGEP(EncPtr, LoopCounter);
Value *EncChar = IRB.CreateLoad(EncCharPtr);
Value *KeyIdx = IRB.CreateURem(LoopCounter, KeySize);
Value *KeyCharPtr = IRB.CreateInBoundsGEP(Data, KeyIdx);
Value *KeyChar = IRB.CreateLoad(KeyCharPtr);
Value *DecChar = IRB.CreateXor(EncChar, KeyChar);
Value *DecCharPtr = IRB.CreateInBoundsGEP(PlainString, LoopCounter);
IRB.CreateStore(DecChar, DecCharPtr);
Value *NewCounter = IRB.CreateAdd(LoopCounter, IRB.getInt32(1), "", true, true);
LoopCounter->addIncoming(NewCounter, LoopBody);
Value *Cond = IRB.CreateICmpEQ(NewCounter, IRB.getInt32(static_cast<uint32_t>(Entry->Data.size())));
IRB.CreateCondBr(Cond, UpdateDecStatus, LoopBody);
IRB.SetInsertPoint(UpdateDecStatus);
IRB.CreateStore(IRB.getInt32(1), Entry->DecStatus);
IRB.CreateBr(Exit);
IRB.SetInsertPoint(Exit);
IRB.CreateRetVoid();
return DecFunc;
}
|