就还挺奇怪的,我也不知道为什么在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
能够编译成功,但是最后会报错: