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

GlobalsEncryption 在编译 protobuf 时由于 llvm.ctros 没有正确处理而 crash #55

Open
mrh929 opened this issue Dec 13, 2023 · 0 comments

Comments

@mrh929
Copy link
Contributor

mrh929 commented Dec 13, 2023

用 pluto-obfuscator -gle 选项编译 protobuf (https://github.com/protocolbuffers/protobuf/tree/79009d92375c4ba955ef37c810b84a6d047bb7ee) 的时候模块出现 crash

我的调试代码如下:

bool GlobalsEncryption::runOnModule(Module &M) {
    if (!enable) {
        return false;
    }
    INIT_CONTEXT(M);

    int gv_count;
    vector<GlobalVariable *> GVs;

    gv_count = M.getGlobalList().size();
    for (GlobalVariable &GV : M.getGlobalList()) {
        GVs.push_back(&GV);
    }
    for (int i = 0; i < ObfuTimes; i++) {
        for (GlobalVariable *GV : GVs) {

        // for (GlobalVariable &T : M.getGlobalList()) {
        // GlobalVariable *GV = &T;

        outs() << "original gv_count: " << gv_count << "  now: " << M.getGlobalList().size() << "\n";

        outs() << "debug: ===============\n";
        
        outs() << "isa<GlobalVariable>:" << isa<GlobalVariable>(GV) << "\n";

        outs() << "GV->classof(GV):" << GV->classof(GV) << "\n";
        
        GV->dump();
 
        // Only encrypt globals of integer and array
        if (!GV->getValueType()->isIntegerTy() &&
            !GV->getValueType()->isArrayTy()) {
            continue;
        }

        outs() << "-----------------------\n";

        if (GV->hasInitializer() && GV->getInitializer() &&
            (GV->getName().contains(".str") || !OnlyStr)
            // Do not encrypt globals having a section named "llvm.metadata"
            && !GV->getSection().equals("llvm.metadata")) {
            Constant *initializer = GV->getInitializer();
            ConstantInt *intData = dyn_cast<ConstantInt>(initializer);
            ConstantDataArray *arrData = dyn_cast<ConstantDataArray>(initializer);
            if (arrData) {
            uint32_t eleSize = arrData->getElementByteSize();
            uint32_t eleNum = arrData->getNumElements();
            uint32_t arrLen = eleNum * eleSize;
            char *data = const_cast<char *>(arrData->getRawDataValues().data());
            char *dataCopy = new char[arrLen];
            memcpy(dataCopy, data, arrLen);
            uint64_t key = cryptoutils->get_uint64_t();
            // A simple xor encryption
            for (uint32_t i = 0; i < arrLen; i++) {
                dataCopy[i] ^= ((char *)&key)[i % eleSize];
            }
            GV->setInitializer(ConstantDataArray::getRaw(
                StringRef(dataCopy, arrLen), eleNum, arrData->getElementType()));
            GV->setConstant(false);
            insertArrayDecryption(M, {GV, key, eleNum});
            } else if (intData) {
            uint64_t key = cryptoutils->get_uint64_t();
            ConstantInt *enc =
                CONST(intData->getType(), key ^ intData->getZExtValue());
            GV->setInitializer(enc);
            GV->setConstant(false);
            insertIntDecryption(M, {GV, key, 1LL});
            }
        }
        }
    }
    return true;
}

部分编译错误信息: 新建 文本文档.txt
复现代码: gmock-all-5d551a.zip

目前初步结论是 M.getGlobalList() 函数返回的列表中的某些元素在处理的过程中有发生改变。而这里我们的代码直接在一开始就把列表中的元素全部放入了 vector 内,等到 vector 取出该元素时,它已经不是一个合法的 GlobalVariable 了,导致 pass crash 掉。

还发现了几个其他的 bug,晚点我会申请 pr

@mrh929 mrh929 changed the title GlobalsEncryption 在编译 c++ 时 crash GlobalsEncryption 在编译 protobuf 时 crash Dec 13, 2023
@mrh929 mrh929 changed the title GlobalsEncryption 在编译 protobuf 时 crash GlobalsEncryption 在编译 protobuf 时由于 llvm.ctros 没有正确处理而 crash Dec 17, 2023
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

1 participant