Skip to content

Commit

Permalink
indgv增加3个混淆等级
Browse files Browse the repository at this point in the history
  • Loading branch information
KomiMoe committed Sep 1, 2024
1 parent 857f13a commit c6a3c83
Showing 1 changed file with 189 additions and 9 deletions.
198 changes: 189 additions & 9 deletions llvm/lib/Transforms/Obfuscation/IndirectGlobalVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#include "llvm/Transforms/Utils/ModuleUtils.h"
#include "llvm/IR/Module.h"

#include <random>

#define DEBUG_TYPE "indgv"

using namespace llvm;
Expand Down Expand Up @@ -35,15 +37,23 @@ struct IndirectGlobalVariable : public FunctionPass {
if (GlobalVariable *GV = dyn_cast<GlobalVariable>(val)) {
if (!GV->isThreadLocal() && GVNumbering.count(GV) == 0 &&
!GV->isDLLImportDependent()) {
GVNumbering[GV] = GlobalVariables.size();
GVNumbering[GV] = 0;
GlobalVariables.push_back((GlobalVariable *) val);
}
}
}
}

long seed = RandomEngine.get_uint32_t();
std::default_random_engine e(seed);
std::shuffle(GlobalVariables.begin(), GlobalVariables.end(), e);
unsigned N = 0;
for (auto GV:GlobalVariables) {
GVNumbering[GV] = N++;
}
}

GlobalVariable *getIndirectGlobalVariables(Function &F, ConstantInt *EncKey) const {
GlobalVariable *getIndirectGlobalVariables0(Function &F, ConstantInt *EncKey) const {
std::string GVName(F.getName().str() + "_IndirectGVars");
GlobalVariable *GV = F.getParent()->getNamedGlobal(GVName);
if (GV)
Expand All @@ -66,6 +76,103 @@ struct IndirectGlobalVariable : public FunctionPass {
return GV;
}

GlobalVariable *getIndirectGlobalVariables1(Function &F, ConstantInt *AddKey, ConstantInt *XorKey) const {
std::string GVName(F.getName().str() + "_IndirectGVars1");
GlobalVariable *GV = F.getParent()->getNamedGlobal(GVName);
if (GV)
return GV;

std::vector<Constant *> Elements;
for (auto GVar:GlobalVariables) {
Constant *CE = ConstantExpr::getBitCast(
GVar, PointerType::getUnqual(F.getContext()));
CE = ConstantExpr::getGetElementPtr(Type::getInt8Ty(F.getContext()), CE, ConstantExpr::getXor(AddKey, XorKey));
Elements.push_back(CE);
}

ArrayType *ATy =
ArrayType::get(PointerType::getUnqual(F.getContext()), Elements.size());
Constant *CA = ConstantArray::get(ATy, ArrayRef<Constant *>(Elements));
GV = new GlobalVariable(*F.getParent(), ATy, false, GlobalValue::LinkageTypes::PrivateLinkage,
CA, GVName);
appendToCompilerUsed(*F.getParent(), {GV});
return GV;
}

GlobalVariable *getIndirectGlobalVariables2(Function &F, ConstantInt *AddKey, ConstantInt *XorKey) {
std::string GVName(F.getName().str() + "_IndirectGVars2");
GlobalVariable *GV = F.getParent()->getNamedGlobal(GVName);
if (GV)
return GV;

auto& Ctx = F.getContext();
IntegerType *intType = Type::getInt32Ty(Ctx);
if (pointerSize == 8) {
intType = Type::getInt64Ty(Ctx);
}

std::vector<Constant *> Elements;
for (auto GVar:GlobalVariables) {
Constant *CE = ConstantExpr::getBitCast(
GVar, PointerType::getUnqual(F.getContext()));
CE = ConstantExpr::getGetElementPtr(Type::getInt8Ty(F.getContext()), CE, ConstantExpr::getXor(AddKey, ConstantExpr::getNSWMul(XorKey, ConstantInt::get(intType, GVNumbering[GVar], false))));
Elements.push_back(CE);
}

ArrayType *ATy =
ArrayType::get(PointerType::getUnqual(F.getContext()), Elements.size());
Constant *CA = ConstantArray::get(ATy, ArrayRef<Constant *>(Elements));
GV = new GlobalVariable(*F.getParent(), ATy, false, GlobalValue::LinkageTypes::PrivateLinkage,
CA, GVName);
appendToCompilerUsed(*F.getParent(), {GV});
return GV;
}

std::pair<GlobalVariable *, GlobalVariable *> getIndirectGlobalVariables3(Function &F, ConstantInt *AddKey) {
std::string GVNameAdd(F.getName().str() + "_IndirectGVars3");
std::string GVNameXor(F.getName().str() + "_IndirectGVars3Xor");
GlobalVariable *GVAdd = F.getParent()->getNamedGlobal(GVNameAdd);
GlobalVariable *GVXor = F.getParent()->getNamedGlobal(GVNameXor);
if (GVAdd && GVXor)
return std::make_pair(GVAdd, GVXor);

auto& Ctx = F.getContext();
IntegerType *intType = Type::getInt32Ty(Ctx);
if (pointerSize == 8) {
intType = Type::getInt64Ty(Ctx);
}

std::vector<Constant *> Elements;
std::vector<Constant *> XorKeys;
for (auto GVar:GlobalVariables) {
uint64_t V = RandomEngine.get_uint64_t();
Constant *XorKey = ConstantInt::get(intType, V, false);

Constant *CE = ConstantExpr::getBitCast(
GVar, PointerType::getUnqual(F.getContext()));
CE = ConstantExpr::getGetElementPtr(Type::getInt8Ty(F.getContext()), CE, ConstantExpr::getXor(AddKey, ConstantExpr::getNSWMul(XorKey, ConstantInt::get(intType, GVNumbering[GVar], false))));
Elements.push_back(CE);

XorKey = ConstantExpr::getNSWNeg(XorKey);
XorKey = ConstantExpr::getXor(XorKey, AddKey);
XorKey = ConstantExpr::getNSWNeg(XorKey);
XorKeys.push_back(XorKey);
}

ArrayType *ATy =
ArrayType::get(PointerType::getUnqual(F.getContext()), Elements.size());
Constant *CA = ConstantArray::get(ATy, ArrayRef<Constant *>(Elements));
GVAdd = new GlobalVariable(*F.getParent(), ATy, false, GlobalValue::LinkageTypes::PrivateLinkage,
CA, GVNameAdd);
appendToCompilerUsed(*F.getParent(), {GVAdd});

ArrayType *XTy = ArrayType::get(intType, XorKeys.size());
Constant *CX = ConstantArray::get(XTy, XorKeys);
GVXor = new GlobalVariable(*F.getParent(), XTy, false, GlobalValue::LinkageTypes::PrivateLinkage, CX, GVNameXor);
appendToCompilerUsed(*F.getParent(), {GVXor});
return std::make_pair(GVAdd, GVXor);
}

bool runOnFunction(Function &Fn) override {
const auto opt = ArgsOptions->toObfuscate(ArgsOptions->indGvOpt(), &Fn);
if (!opt.isEnabled()) {
Expand All @@ -85,18 +192,37 @@ struct IndirectGlobalVariable : public FunctionPass {
}

uint64_t V = RandomEngine.get_uint64_t();
uint64_t XV = RandomEngine.get_uint64_t();
IntegerType* intType = Type::getInt32Ty(Ctx);
if (pointerSize == 8) {
intType = Type::getInt64Ty(Ctx);
}

ConstantInt *EncKey = ConstantInt::get(intType, V, false);
ConstantInt *EncKey1 = ConstantInt::get(intType, -V, false);
ConstantInt *Zero = ConstantInt::get(intType, 0);

Value *MySecret = ConstantInt::get(intType, 0, true);
GlobalVariable *GXorKey = nullptr;
GlobalVariable *GVars = nullptr;
GlobalVariable *XorKeys = nullptr;

ConstantInt *Zero = ConstantInt::get(intType, 0);
GlobalVariable *GVars = getIndirectGlobalVariables(Fn, EncKey1);
if (opt.level() == 0) {
GVars = getIndirectGlobalVariables0(Fn, EncKey1);
} else if (opt.level() == 1 || opt.level() == 2) {
ConstantInt *CXK = ConstantInt::get(intType, XV, false);
GXorKey = new GlobalVariable(*Fn.getParent(), CXK->getType(), false, GlobalValue::LinkageTypes::PrivateLinkage,
CXK, Fn.getName() + "_IGVXorKey");
appendToCompilerUsed(*Fn.getParent(), {GXorKey});
if (opt.level() == 1) {
GVars = getIndirectGlobalVariables1(Fn, EncKey1, CXK);
} else {
GVars = getIndirectGlobalVariables2(Fn, EncKey1, CXK);
}
} else {
auto [fst, snd] = getIndirectGlobalVariables3(Fn, EncKey1);
GVars = fst;
XorKeys = snd;
}

for (inst_iterator I = inst_begin(Fn), E = inst_end(Fn); I != E; ++I) {
Instruction *Inst = &*I;
Expand Down Expand Up @@ -126,11 +252,38 @@ struct IndirectGlobalVariable : public FunctionPass {
GEP->getType(), GEP,
GV->getName());

Value *Secret = IRB.CreateAdd(EncKey, MySecret);
Value *DecKey = EncKey;
if (GXorKey) {
LoadInst *XorKey = IRB.CreateLoad(GXorKey->getValueType(), GXorKey);
XorKey->setVolatile(true);

if (opt.level() == 1) {
DecKey = IRB.CreateXor(EncKey1, XorKey);
DecKey = IRB.CreateNSWNeg(DecKey);
} else if (opt.level() == 2) {
DecKey = IRB.CreateXor(EncKey1, IRB.CreateNSWMul(XorKey, Idx));
DecKey = IRB.CreateNSWNeg(DecKey);
}
}

if (XorKeys) {
Value *XorKeysGEP = IRB.CreateGEP(XorKeys->getValueType(), XorKeys, {Zero, Idx});

Value *XorKey = IRB.CreateLoad(intType, XorKeysGEP);
dyn_cast<LoadInst>(XorKey)->setVolatile(true);

XorKey = IRB.CreateNSWNeg(XorKey);
XorKey = IRB.CreateXor(XorKey, EncKey1);
XorKey = IRB.CreateNSWNeg(XorKey);

DecKey = IRB.CreateXor(EncKey1, IRB.CreateNSWMul(XorKey, Idx));
DecKey = IRB.CreateNSWNeg(DecKey);
}

Value *GVAddr = IRB.CreateGEP(
Type::getInt8Ty(Ctx),
EncGVAddr,
Secret);
DecKey);
GVAddr = IRB.CreateBitCast(GVAddr, GV->getType());
GVAddr->setName("IndGV0_");
PHI->setIncomingValue(i, GVAddr);
Expand All @@ -154,11 +307,38 @@ struct IndirectGlobalVariable : public FunctionPass {
GEP,
GV->getName());

Value *Secret = IRB.CreateAdd(EncKey, MySecret);
Value *DecKey = EncKey;
if (GXorKey) {
LoadInst *XorKey = IRB.CreateLoad(GXorKey->getValueType(), GXorKey);
XorKey->setVolatile(true);

if (opt.level() == 1) {
DecKey = IRB.CreateXor(EncKey1, XorKey);
DecKey = IRB.CreateNSWNeg(DecKey);
} else if (opt.level() == 2) {
DecKey = IRB.CreateXor(EncKey1, IRB.CreateNSWMul(XorKey, Idx));
DecKey = IRB.CreateNSWNeg(DecKey);
}
}

if (XorKeys) {
Value *XorKeysGEP = IRB.CreateGEP(XorKeys->getValueType(), XorKeys, {Zero, Idx});

Value *XorKey = IRB.CreateLoad(intType, XorKeysGEP);
dyn_cast<LoadInst>(XorKey)->setVolatile(true);

XorKey = IRB.CreateNSWNeg(XorKey);
XorKey = IRB.CreateXor(XorKey, EncKey1);
XorKey = IRB.CreateNSWNeg(XorKey);

DecKey = IRB.CreateXor(EncKey1, IRB.CreateNSWMul(XorKey, Idx));
DecKey = IRB.CreateNSWNeg(DecKey);
}

Value *GVAddr = IRB.CreateGEP(
Type::getInt8Ty(Ctx),
EncGVAddr,
Secret);
DecKey);
GVAddr = IRB.CreateBitCast(GVAddr, GV->getType());
GVAddr->setName("IndGV1_");
Inst->replaceUsesOfWith(GV, GVAddr);
Expand Down

0 comments on commit c6a3c83

Please sign in to comment.