目录

Ollvm混淆与反混淆: goron框架间接全局变量引用的实现原理

目录
警告
本文最后更新于 2023-03-30,文中内容可能已过时。

与间接函数调用同理,可参考

  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
 98
 99
100
101
102
103
// llvm/lib/Transforms/Obfuscation/IndirectGlobalVariable.cpp

bool runOnFunction(Function &Fn) override {
    if (!toObfuscate(flag, &Fn, "indgv")) {
      return false;
    }

    if (Options && Options->skipFunction(Fn.getName())) {
      return false;
    }

    LLVMContext &Ctx = Fn.getContext();

    GVNumbering.clear();
    GlobalVariables.clear();

    LowerConstantExpr(Fn);
    NumberGlobalVariable(Fn);

    if (GlobalVariables.empty()) {
      return false;
    }

    uint32_t V = RandomEngine.get_uint32_t() & ~3;
    ConstantInt *EncKey = ConstantInt::get(Type::getInt32Ty(Ctx), V, false);

    const IPObfuscationContext::IPOInfo *SecretInfo = nullptr;
    if (IPO) {
      SecretInfo = IPO->getIPOInfo(&Fn);
    }

    Value *MySecret;
    if (SecretInfo) {
      MySecret = SecretInfo->SecretLI;
    } else {
      MySecret = ConstantInt::get(Type::getInt32Ty(Ctx), 0, true);
    }

    ConstantInt *Zero = ConstantInt::get(Type::getInt32Ty(Ctx), 0);
    GlobalVariable *GVars = getIndirectGlobalVariables(Fn, EncKey);

    for (inst_iterator I = inst_begin(Fn), E = inst_end(Fn); I != E; ++I) {
      Instruction *Inst = &*I;
      if (PHINode *PHI = dyn_cast<PHINode>(Inst)) {
        for (unsigned int i = 0; i < PHI->getNumIncomingValues(); ++i) {
          Value *val = PHI->getIncomingValue(i);
          if (GlobalVariable *GV = dyn_cast<GlobalVariable>(val)) {
            if (GVNumbering.count(GV) == 0) {
              continue;
            }

            Instruction *IP = PHI->getIncomingBlock(i)->getTerminator();
            IRBuilder<> IRB(IP);

            Value *Idx = ConstantInt::get(Type::getInt32Ty(Ctx), GVNumbering[GV]);
            Value *GEP = IRB.CreateGEP(GVars, {Zero, Idx});
            LoadInst *EncGVAddr = IRB.CreateLoad(GEP, GV->getName());
            Constant *X;
            if (SecretInfo) {
              X = ConstantExpr::getSub(SecretInfo->SecretCI, EncKey);
            } else {
              X = ConstantExpr::getSub(Zero, EncKey);
            }

            Value *Secret = IRB.CreateSub(X, MySecret);
            Value *GVAddr = IRB.CreateGEP(EncGVAddr, Secret);
            GVAddr = IRB.CreateBitCast(GVAddr, GV->getType());
            GVAddr->setName("IndGV");
            Inst->replaceUsesOfWith(GV, GVAddr);
          }
        }
      } else {
        for (User::op_iterator op = Inst->op_begin(); op != Inst->op_end(); ++op) {
          if (GlobalVariable *GV = dyn_cast<GlobalVariable>(*op)) {
            if (GVNumbering.count(GV) == 0) {
              continue;
            }

            IRBuilder<> IRB(Inst);
            Value *Idx = ConstantInt::get(Type::getInt32Ty(Ctx), GVNumbering[GV]);
            Value *GEP = IRB.CreateGEP(GVars, {Zero, Idx});
            LoadInst *EncGVAddr = IRB.CreateLoad(GEP, GV->getName());
            Constant *X;
            if (SecretInfo) {
              X = ConstantExpr::getSub(SecretInfo->SecretCI, EncKey);
            } else {
              X = ConstantExpr::getSub(Zero, EncKey);
            }

            Value *Secret = IRB.CreateSub(X, MySecret);
            Value *GVAddr = IRB.CreateGEP(EncGVAddr, Secret);
            GVAddr = IRB.CreateBitCast(GVAddr, GV->getType());
            GVAddr->setName("IndGV");
            Inst->replaceUsesOfWith(GV, GVAddr);
          }
        }
      }
    }

      return true;
    }

  };

相关内容