Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

大佬,IPObfuscationContext是干什么的 #14

Open
BRYNHILDRINTHEDARKNESS opened this issue Aug 30, 2023 · 6 comments
Open

大佬,IPObfuscationContext是干什么的 #14

BRYNHILDRINTHEDARKNESS opened this issue Aug 30, 2023 · 6 comments

Comments

@BRYNHILDRINTHEDARKNESS
Copy link

大佬,goron中有IPObfuscationContext.cpp,但是你移植过来的就删掉了,这个具体是干什么的,请大佬解答解答

@KomiMoe
Copy link
Owner

KomiMoe commented Sep 1, 2023

忘了。好像是有兼容性问题?

@pomelohan
Copy link

大佬,goron中有IPObfuscationContext.cpp,但是你移植过来的就删掉了,这个具体是干什么的,请大佬解答解答

IPObfuscationContext 主要是用来生成 MySecret 的信息的,具体可以参考原版 Control Flow Flattening 和 IndirectCall 这两个 Pass 中的代码,这个移植作者采用的方案是直接不使用生成的 SecretArg,而是使用 0 代替;而在原版中的逻辑是只有当 SecretArg 生成失败了才会使用 0 代替,因此这样直接导致了 goron 特色消失

@BRYNHILDRINTHEDARKNESS
Copy link
Author

大佬,goron中有IPObfuscationContext.cpp,但是你移植过来的就删掉了,这个具体是干什么的,请大佬解答解答

IPObfuscationContext 主要是用来生成 MySecret 的信息的,具体可以参考原版 Control Flow Flattening 和 IndirectCall 这两个 Pass 中的代码,这个移植作者采用的方案是直接不使用生成的 SecretArg,而是使用 0 代替;而在原版中的逻辑是只有当 SecretArg 生成失败了才会使用 0 代替,因此这样直接导致了 goron 特色消失

MySecret具体是什么东西呢?如果使用了MySecret,goron会有什么不同

@pomelohan
Copy link

举个栗子,下面代码取自 goron IndirectCall

    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);
    }
      Constant *X;
      if (SecretInfo) {
        X = ConstantExpr::getSub(SecretInfo->SecretCI, EncKey);
      } else {
        X = ConstantExpr::getSub(Zero, EncKey);
      }

      Value *Secret = IRB.CreateSub(X, MySecret);
      Value *DestAddr = IRB.CreateGEP(EncDestAddr, Secret);

      Value *FnPtr = IRB.CreateBitCast(DestAddr, FTy->getPointerTo());

以上就是原版的 goron 逻辑,追踪到 IPObfuscationContext 中可以看到下面的代码

  // Load Secret Token from the secret argument
  IntegerType *I32Ty = Type::getInt32Ty(NF->getContext());
  IRBuilder<> IRB(&NF->getEntryBlock().front());
  Value *Ptr = IRB.CreateBitCast(NF->arg_begin(), I32Ty->getPointerTo());
  LoadInst *MySecret = IRB.CreateLoad(Ptr);

你可以把 MySecret 当成一个密钥;至于有什么不同,当然是增加攻击者攻击的难度,下面引用 @61bcdefg 大佬的一句话解释:

会给被混淆的函数加个参数,当作解密的key

这个版本中直接丢掉了 IPObfuscationContext,四舍五入就是 key = 0

@BRYNHILDRINTHEDARKNESS
Copy link
Author

举个栗子,下面代码取自 goron IndirectCall

    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);
    }
      Constant *X;
      if (SecretInfo) {
        X = ConstantExpr::getSub(SecretInfo->SecretCI, EncKey);
      } else {
        X = ConstantExpr::getSub(Zero, EncKey);
      }

      Value *Secret = IRB.CreateSub(X, MySecret);
      Value *DestAddr = IRB.CreateGEP(EncDestAddr, Secret);

      Value *FnPtr = IRB.CreateBitCast(DestAddr, FTy->getPointerTo());

以上就是原版的 goron 逻辑,追踪到 IPObfuscationContext 中可以看到下面的代码

  // Load Secret Token from the secret argument
  IntegerType *I32Ty = Type::getInt32Ty(NF->getContext());
  IRBuilder<> IRB(&NF->getEntryBlock().front());
  Value *Ptr = IRB.CreateBitCast(NF->arg_begin(), I32Ty->getPointerTo());
  LoadInst *MySecret = IRB.CreateLoad(Ptr);

你可以把 MySecret 当成一个密钥;至于有什么不同,当然是增加攻击者攻击的难度,下面引用 @61bcdefg 大佬的一句话解释:

会给被混淆的函数加个参数,当作解密的key

这个版本中直接丢掉了 IPObfuscationContext,四舍五入就是 key = 0

原来如此,大佬能否将IPObfuscationContext也适配进llvm17呢

@pomelohan
Copy link

举个栗子,下面代码取自 goron IndirectCall

    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);
    }
      Constant *X;
      if (SecretInfo) {
        X = ConstantExpr::getSub(SecretInfo->SecretCI, EncKey);
      } else {
        X = ConstantExpr::getSub(Zero, EncKey);
      }

      Value *Secret = IRB.CreateSub(X, MySecret);
      Value *DestAddr = IRB.CreateGEP(EncDestAddr, Secret);

      Value *FnPtr = IRB.CreateBitCast(DestAddr, FTy->getPointerTo());

以上就是原版的 goron 逻辑,追踪到 IPObfuscationContext 中可以看到下面的代码

  // Load Secret Token from the secret argument
  IntegerType *I32Ty = Type::getInt32Ty(NF->getContext());
  IRBuilder<> IRB(&NF->getEntryBlock().front());
  Value *Ptr = IRB.CreateBitCast(NF->arg_begin(), I32Ty->getPointerTo());
  LoadInst *MySecret = IRB.CreateLoad(Ptr);

你可以把 MySecret 当成一个密钥;至于有什么不同,当然是增加攻击者攻击的难度,下面引用 @61bcdefg 大佬的一句话解释:

会给被混淆的函数加个参数,当作解密的key

这个版本中直接丢掉了 IPObfuscationContext,四舍五入就是 key = 0

原来如此,大佬能否将IPObfuscationContext也适配进llvm17呢

可以询问项目的原作者或者自己移植,我暂时对这个不感兴趣 & 没有时间

@enenH enenH mentioned this issue Oct 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants