Open Dfault0 opened 10 months ago
就还挺奇怪的,我也不知道为什么在14.x上会出现这个错误:'common' global must have a zero initializer! 恳请大家帮忙看看,感谢感谢。 系统环境:mac os 13.2 代码: GlobalEncryption.h
#ifndef LLVM_TRANSFORMS_OBFUSCATION_GLOBALENCRYPTION_H #define LLVM_TRANSFORMS_OBFUSCATION_GLOBALENCRYPTION_H #include "llvm/IR/PassManager.h" namespace llvm { class GlobalEncryptionPass: public PassInfoMixin<GlobalEncryptionPass> { public: PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM); static bool isRequired() { return true; } }; } // namespace llvm #endif // LLVM_TRANSFORMS_OBFUSCATION_GLOBALENCRYPTION_H
GlobalEncryption.cpp:
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringRef.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/Constant.h" #include "llvm/IR/Constants.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/Function.h" #include "llvm/IR/GlobalVariable.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/PassManager.h" #include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FormatVariadic.h" #include "llvm/Support/SHA1.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Utils/ModuleUtils.h" #include <iomanip> #include <sstream> #include <vector> #include "llvm/Transforms/Obfuscation/CryptoUtils.h" #include "llvm/Transforms/Obfuscation/GlobalEncryption.h" using namespace llvm; struct EncryptedGV { GlobalVariable *GV; uint64_t key; uint32_t len; }; namespace { static cl::opt<bool> GlobalEncryption("sobf", cl::init(false), cl::desc("Enable String")); static cl::opt<int> ObfuTimes("gvobfus-times", cl::init(1), cl::desc("Run GlobalsEncryption pass <gvobfus-times> time(s)")); static cl::opt<bool> OnlyStr("onlystr", cl::init(false), cl::desc("Encrypt string variable only")); LLVMContext *ctx = nullptr; void InsertIntDecryption(Module &M, EncryptedGV encGV); void InsertArrayDecryption(Module &M, EncryptedGV encGV); std::string GenHashedName(GlobalVariable *GV) { Module &M = *GV->getParent(); std::string funcName = formatv("{0}_{1:x-}", M.getName(), M.getMDKindID(GV->getName())); SHA1 sha1; sha1.update(funcName); StringRef digest = sha1.final(); std::stringstream ss; ss << std::hex; for (size_t i = 0; i < digest.size(); i++) { ss << std::setw(2) << std::setfill('0') << (unsigned)(digest[i] & 0xFF); } return ss.str(); } void InsertIntDecryption(Module &M, EncryptedGV encGV) { std::vector<Type *> funcArgs; FunctionType *funcType = FunctionType::get(Type::getVoidTy(M.getContext()), funcArgs, false); std::string funcName = GenHashedName(encGV.GV); FunctionCallee callee = M.getOrInsertFunction(funcName, funcType); Function *func = cast<Function>(callee.getCallee()); BasicBlock *entry = BasicBlock::Create(*ctx, "entry", func); IRBuilder<> builder(*ctx); builder.SetInsertPoint(entry); LoadInst *val = builder.CreateLoad(encGV.GV->getValueType(),encGV.GV); Value *xorVal = builder.CreateXor( val, ConstantInt::get(encGV.GV->getValueType(), encGV.key)); builder.CreateStore(xorVal, encGV.GV); builder.CreateRetVoid(); appendToGlobalCtors(M, func, 0); } void InsertArrayDecryption(Module &M, EncryptedGV encGV) { std::vector<Type *> funcArgs; FunctionType *funcType = FunctionType::get(Type::getVoidTy(M.getContext()), funcArgs, false); std::string funcName = GenHashedName(encGV.GV); FunctionCallee callee = M.getOrInsertFunction(funcName, funcType); Function *func = cast<Function>(callee.getCallee()); BasicBlock *entry = BasicBlock::Create(*ctx, "entry", func); BasicBlock *forCond = BasicBlock::Create(*ctx, "for.cond", func); BasicBlock *forBody = BasicBlock::Create(*ctx, "for.body", func); BasicBlock *forInc = BasicBlock::Create(*ctx, "for.inc", func); BasicBlock *forEnd = BasicBlock::Create(*ctx, "for.inc", func); IRBuilder<> builder(*ctx); Type *Int32Ty = builder.getInt32Ty(); builder.SetInsertPoint(entry); AllocaInst *indexPtr = builder.CreateAlloca(Int32Ty, ConstantInt::get(Int32Ty, 1, false), "i"); builder.CreateStore(ConstantInt::get(Int32Ty, 0), indexPtr); builder.CreateBr(forCond); builder.SetInsertPoint(forCond); LoadInst *index = builder.CreateLoad(Int32Ty, indexPtr); ICmpInst *cond = cast<ICmpInst>( builder.CreateICmpSLT(index, ConstantInt::get(Int32Ty, encGV.len))); builder.CreateCondBr(cond, forBody, forEnd); builder.SetInsertPoint(forBody); Value *indexList[2] = {ConstantInt::get(Int32Ty, 0), index}; Value *ele = builder.CreateGEP(encGV.GV->getValueType(),encGV.GV, ArrayRef<Value *>(indexList, 2)); ArrayType *arrTy = cast<ArrayType>(encGV.GV->getValueType()); Type *eleTy = arrTy->getElementType(); Value *encEle = builder.CreateXor(builder.CreateLoad(eleTy,ele), ConstantInt::get(eleTy, encGV.key)); builder.CreateStore(encEle, ele); builder.CreateBr(forInc); builder.SetInsertPoint(forInc); builder.CreateStore(builder.CreateAdd(index, ConstantInt::get(Int32Ty, 1)), indexPtr); builder.CreateBr(forCond); builder.SetInsertPoint(forEnd); builder.CreateRetVoid(); appendToGlobalCtors(M, func, 0); } } // namespace PreservedAnalyses GlobalEncryptionPass::run(Module &M, ModuleAnalysisManager &MAM) { outs() << "Pass start...\n"; // if(!GlobalEncryption){ // return PreservedAnalyses::all(); // } ctx = &M.getContext(); std::vector<GlobalVariable *> GVs; for (auto &GV : M.globals()) { GVs.push_back(&GV); } for (int i = 0; i < ObfuTimes; i++) { outs() << "Current ObfuTimes: " << i << "\n"; for (auto *GV : GVs) { // 只对Integer和Array类型进行加密 if (!GV->getValueType()->isIntegerTy() && !GV->getValueType()->isArrayTy()) { continue; } // 筛出".str"全局变量,LLVM IR的metadata同样也要保留 if (GV->hasInitializer() && GV->getInitializer() && (GV->getName().contains(".str") || !OnlyStr) && !GV->getName().contains("llvm.metadata")) { Constant *initializer = GV->getInitializer(); ConstantInt *intData = dyn_cast<ConstantInt>(initializer); ConstantDataArray *arrayData = dyn_cast<ConstantDataArray>(initializer); // 处理数组 if (arrayData) { // 获取数组的长度和数组元素的大小 outs() << "Get global arraydata\n"; uint32_t eleSize = arrayData->getElementByteSize(); uint32_t eleNum = arrayData->getNumElements(); uint32_t arrLen = eleNum * eleSize; outs() << "Global Variable: " << *GV << "\n" << "Array Length: " << eleSize << " * " << eleNum << " = " << arrLen << "\n"; char *data = const_cast<char *>(arrayData->getRawDataValues().data()); char *dataCopy = new char[arrLen]; memcpy(dataCopy, data, arrLen); // 生成密钥 uint64_t key = cryptoutils->get_uint64_t(); for (uint32_t i = 0; i < arrLen; i++) { dataCopy[i] ^= ((char *)&key)[i % eleSize]; } outs()<<"setInitializer before\n"; GV->setInitializer( ConstantDataArray::getRaw(StringRef(dataCopy, arrLen), eleNum, arrayData->getElementType())); outs()<<"setInitializer after\n"; GV->setConstant(false); InsertArrayDecryption(M, {GV, key, eleNum}); } // 处理整数 else if (intData) { uint64_t key = cryptoutils->get_uint64_t(); outs()<<"\nintData->getType():"<<intData->getType()<<",key:"<<key<<",intData->getZExtValue():"<<intData->getZExtValue(); ConstantInt *enc = ConstantInt::get(intData->getType(), key ^ intData->getZExtValue()); outs()<<"\nenv:"<<enc->getZExtValue(); GV->setInitializer(enc); InsertIntDecryption(M, {GV, key, 1LL}); } } } } outs() << "Pass end...\n"; return PreservedAnalyses::all(); }
注册代码pass代码:
#include "llvm/Passes/PassBuilder.h" #include "llvm/Passes/PassPlugin.h" #include "llvm/Transforms/Obfuscation/GlobalEncryption.h" using namespace llvm; llvm::PassPluginLibraryInfo getObfuscationPluginInfo() { return { LLVM_PLUGIN_API_VERSION, "Obfuscation", LLVM_VERSION_STRING, [](PassBuilder &PB) { PB.registerPipelineStartEPCallback( [](llvm::ModulePassManager &MPM, llvm::OptimizationLevel) { MPM.addPass(GlobalEncryptionPass()); }); }}; } #ifndef LLVM_OBFUSCATION_LINK_INTO_TOOLS extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo llvmGetPassPluginInfo() { return getObfuscationPluginInfo(); } #endif
cmakelist.txt
add_llvm_pass_plugin(Obfuscation CryptoUtils.cpp Plugin.cpp GlobalEncryption.cpp ADDITIONAL_HEADER_DIRS ${PROJECT_SOURCE_DIR} DEPENDS intrinsics_gen LINK_COMPONENTS Core Support Analysis TransformUtils )
能够编译成功,但是最后会报错:
[~/Documents/文档/ollvm/test/mine]$ $clangPath/clang -isysroot `xcrun --show-sdk-path` -arch arm64 -mllvm -sobf -emit-llvm -S ../hello_ollvm.c -o hello_sobf.ll registerPipelineStartEPCallback registerOptimizerLastEPCallback BogusControlFlow ing:funca Pass start... Current ObfuTimes: 0 Get global arraydata Global Variable: @.str = private unnamed_addr constant [16 x i8] c"this is func a\0A\00", align 1 Array Length: 1 * 16 = 16 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.1 = private unnamed_addr constant [4 x i8] c"bcf\00", section "llvm.metadata" Array Length: 1 * 4 = 4 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.2 = private unnamed_addr constant [17 x i8] c"../hello_ollvm.c\00", section "llvm.metadata" Array Length: 1 * 17 = 17 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.3 = private unnamed_addr constant [16 x i8] c"this is func b\0A\00", align 1 Array Length: 1 * 16 = 16 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.4 = private unnamed_addr constant [4 x i8] c"fla\00", section "llvm.metadata" Array Length: 1 * 4 = 4 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.5 = private unnamed_addr constant [16 x i8] c"this is func c\0A\00", align 1 Array Length: 1 * 16 = 16 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.6 = private unnamed_addr constant [5 x i8] c"sobf\00", section "llvm.metadata" Array Length: 1 * 5 = 5 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.7 = private unnamed_addr constant [20 x i8] c"func a res is : %d\0A\00", align 1 Array Length: 1 * 20 = 20 setInitializer before setInitializer after Get global arraydata Global Variable: @.str.8 = private unnamed_addr constant [20 x i8] c"func b res is : %d\0A\00", align 1 Array Length: 1 * 20 = 20 setInitializer before setInitializer after intData->getType():0x132024908,key:10951636861935028358,intData->getZExtValue():0 env:2696284294 intData->getType():0x132024908,key:14553880688145529733,intData->getZExtValue():0 env:1213528965Pass end... 'common' global must have a zero initializer! i32* @x 'common' global must have a zero initializer! i32* @y fatal error: error in backend: Broken module found, compilation aborted! PLEASE submit a bug report to https://github.com/llvm/llvm-project/issues/ and include the crash backtrace, preprocessed source, and associated run script. Stack dump: 0. Program arguments: /Users/xxx/work/ollvm/build/mine/debug_14/bin/clang -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk -arch arm64 -mllvm -sobf -emit-llvm -S ../hello_ollvm.c -o hello_sobf.ll 1. <eof> parser at end of file 2. Optimizer Stack dump without symbol names (ensure you have llvm-symbolizer in your PATH or set the environment var `LLVM_SYMBOLIZER_PATH` to point to it): 0 clang-14 0x00000001089d78ec llvm::sys::PrintStackTrace(llvm::raw_ostream&, int) + 80 1 clang-14 0x00000001089d7e90 PrintStackTraceSignalHandler(void*) + 28 2 clang-14 0x00000001089d5f18 llvm::sys::RunSignalHandlers() + 148 3 clang-14 0x00000001089d70a0 llvm::sys::CleanupOnSignal(unsigned long) + 116 4 clang-14 0x000000010886c410 (anonymous namespace)::CrashRecoveryContextImpl::HandleCrash(int, unsigned long) + 200 5 clang-14 0x000000010886c330 llvm::CrashRecoveryContext::HandleExit(int) + 136 6 clang-14 0x00000001089d1490 llvm::sys::Process::Exit(int, bool) + 68 7 clang-14 0x0000000104b41a70 clang::CompilerInstance::getDiagnostics() const + 0 8 clang-14 0x000000010887ed8c llvm::report_fatal_error(llvm::Twine const&, bool) + 176 9 clang-14 0x000000010887ecdc llvm::report_fatal_error(llvm::Twine const&, bool) + 0 10 clang-14 0x0000000107a97b38 llvm::VerifierPass::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 120 11 clang-14 0x0000000108f92854 llvm::detail::PassModel<llvm::Module, llvm::VerifierPass, llvm::PreservedAnalyses, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 52 12 clang-14 0x0000000107a24c44 llvm::PassManager<llvm::Module, llvm::AnalysisManager<llvm::Module> >::run(llvm::Module&, llvm::AnalysisManager<llvm::Module>&) + 304 13 clang-14 0x0000000108f78f00 (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline(clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream> >&, std::__1::unique_ptr<llvm::ToolOutputFile, std::__1::default_delete<llvm::ToolOutputFile> >&) + 5140 14 clang-14 0x0000000108f64c04 (anonymous namespace)::EmitAssemblyHelper::EmitAssembly(clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream> >) + 348 15 clang-14 0x0000000108f63830 clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream> >) + 992 16 clang-14 0x00000001095155bc clang::BackendConsumer::HandleTranslationUnit(clang::ASTContext&) + 1572 17 clang-14 0x000000010c4e1da8 clang::ParseAST(clang::Sema&, bool, bool) + 820 18 clang-14 0x0000000109c7d80c clang::ASTFrontendAction::ExecuteAction() + 296 19 clang-14 0x0000000109513bc4 clang::CodeGenAction::ExecuteAction() + 92 20 clang-14 0x0000000109c7cee8 clang::FrontendAction::Execute() + 124 21 clang-14 0x0000000109b10968 clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) + 920 22 clang-14 0x0000000109d8b41c clang::ExecuteCompilerInvocation(clang::CompilerInstance*) + 1060 23 clang-14 0x0000000104b40f20 cc1_main(llvm::ArrayRef<char const*>, char const*, void*) + 1180 24 clang-14 0x0000000104b3280c ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&) + 304 25 clang-14 0x00000001098cbbbc clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, bool*) const::$_1::operator()() const + 40 26 clang-14 0x00000001098cbb88 void llvm::function_ref<void ()>::callback_fn<clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, bool*) const::$_1>(long) + 24 27 clang-14 0x000000010886c29c llvm::function_ref<void ()>::operator()() const + 32 28 clang-14 0x000000010886c220 llvm::CrashRecoveryContext::RunSafely(llvm::function_ref<void ()>) + 260 29 clang-14 0x00000001098c953c clang::driver::CC1Command::Execute(llvm::ArrayRef<llvm::Optional<llvm::StringRef> >, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >*, bool*) const + 380 30 clang-14 0x00000001098725a0 clang::driver::Compilation::ExecuteCommand(clang::driver::Command const&, clang::driver::Command const*&) const + 680 31 clang-14 0x000000010987281c clang::driver::Compilation::ExecuteJobs(clang::driver::JobList const&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*> >&) const + 144 32 clang-14 0x000000010988ad80 clang::driver::Driver::ExecuteCompilation(clang::driver::Compilation&, llvm::SmallVectorImpl<std::__1::pair<int, clang::driver::Command const*> >&) + 288 33 clang-14 0x0000000104b31e6c main + 2976 34 dyld 0x00000001af7c3e50 start + 2544 clang-14: error: clang frontend command failed with exit code 70 (use -v to see invocation) clang version 14.0.6 (https://github.com/llvm/llvm-project.git f28c006a5895fc0e329fe15fead81e37457cb1d1) Target: arm64-apple-darwin22.3.0 Thread model: posix InstalledDir: /Users/xxx/work/ollvm/build/mine/debug_14/bin clang-14: note: diagnostic msg: ******************** PLEASE ATTACH THE FOLLOWING FILES TO THE BUG REPORT: Preprocessed source(s) and associated run script(s) are located at: clang-14: note: diagnostic msg: /var/folders/vk/p3665v4j5_l3194pb3w5lqdc0000gp/T/hello_ollvm-a7e6b6.c clang-14: note: diagnostic msg: /var/folders/vk/p3665v4j5_l3194pb3w5lqdc0000gp/T/hello_ollvm-a7e6b6.sh clang-14: note: diagnostic msg: Crash backtrace is located in clang-14: note: diagnostic msg: /Users/xxx/Library/Logs/DiagnosticReports/clang-14_<YYYY-MM-DD-HHMMSS>_<hostname>.crash clang-14: note: diagnostic msg: (choose the .crash file that corresponds to your crash) clang-14: note: diagnostic msg: ********************
就还挺奇怪的,我也不知道为什么在14.x上会出现这个错误:'common' global must have a zero initializer! 恳请大家帮忙看看,感谢感谢。 系统环境:mac os 13.2 代码: GlobalEncryption.h
GlobalEncryption.cpp:
注册代码pass代码:
cmakelist.txt
能够编译成功,但是最后会报错: