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
|
for (CSPEntry *Entry: ConstantStringPool) { getRandomBytes(Entry->EncKey, 16, 32); for (unsigned i = 0; i < Entry->Data.size(); ++i) { Entry->Data[i] ^= Entry->EncKey[i % Entry->EncKey.size()]; } 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); 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; ++ArgIt; Argument *Data = ArgIt;
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; }
|