😇 I'm I3r0nya, nickname is from Honkai3 character Bronya Zaychik
😇
😇 Learning Compile now... 😇
LLVM12.0.1 简单的字符串加密
就还挺奇怪的,我也不知道为什么在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:
********************
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.