diff --git a/Plugin.cpp b/Plugin.cpp index 946d489..8b58636 100644 --- a/Plugin.cpp +++ b/Plugin.cpp @@ -45,7 +45,9 @@ bool addPassWithName(FunctionPassManager &FPM, StringRef &passName) { bool addPassWithName(ModulePassManager &MPM, StringRef &passName) { if (passName == "string-encryption") { - MPM.addPass(StringObfuscatorPass()); + size_t maxSize = 0; + getEnvVar(EnvVarPrefix + "MAX_STRING_LENGTH").getAsInteger(10, maxSize); + MPM.addPass(StringObfuscatorPass{maxSize}); } else { return false; } diff --git a/README.md b/README.md index 949b53e..4ae2e55 100644 --- a/README.md +++ b/README.md @@ -55,6 +55,9 @@ Or you can run the string encryption pass with: Refer to the llvm::PassBuilder documentation for more information on each insertion point. +You can limit the length of strings that are obfuscated with the `LLVM_OBF_MAX_STRING_LENGTH` environment variable. A +value of 0 (the default) means no limit. + ### With opt [`opt`](https://llvm.org/docs/CommandGuide/opt.html) can be used to apply specific passes from LLRM-IR you diff --git a/flattening/Flattening.cpp b/flattening/Flattening.cpp index d8792e8..01a0222 100644 --- a/flattening/Flattening.cpp +++ b/flattening/Flattening.cpp @@ -17,7 +17,11 @@ #include "llvm/Analysis/LazyValueInfo.h" #include "llvm/IR/PassManager.h" #include "llvm/Passes/PassBuilder.h" +#if LLVM_VERSION_MAJOR >= 22 +#include "llvm/Plugins/PassPlugin.h" +#else #include "llvm/Passes/PassPlugin.h" +#endif #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/LowerSwitch.h" diff --git a/split/SplitBasicBlocks.cpp b/split/SplitBasicBlocks.cpp index 3b3f43e..5ded046 100644 --- a/split/SplitBasicBlocks.cpp +++ b/split/SplitBasicBlocks.cpp @@ -15,7 +15,11 @@ #include "utils/Utils.h" #include "llvm/IR/PassManager.h" #include "llvm/Passes/PassBuilder.h" +#if LLVM_VERSION_MAJOR >= 22 +#include "llvm/Plugins/PassPlugin.h" +#else #include "llvm/Passes/PassPlugin.h" +#endif #include "utils/CryptoUtils.h" diff --git a/string/StringObfuscation.cpp b/string/StringObfuscation.cpp index ca15028..c15f6f7 100644 --- a/string/StringObfuscation.cpp +++ b/string/StringObfuscation.cpp @@ -7,7 +7,11 @@ #include "llvm/IR/IRBuilder.h" #include "llvm/IR/PassManager.h" #include "llvm/Passes/PassBuilder.h" +#if LLVM_VERSION_MAJOR >= 22 +#include "llvm/Plugins/PassPlugin.h" +#else #include "llvm/Passes/PassPlugin.h" +#endif #include "llvm/Transforms/Scalar.h" #include "llvm/Transforms/Utils.h" #include "llvm/Transforms/Utils/Cloning.h" @@ -28,14 +32,8 @@ ConstantDataArray *StringObfuscatorPass::encodeStringDataArray(LLVMContext &ctx, const char *str, size_t size, uint8_t key) { - // Check this is a valid string (not containing zeros) - if (str[size - 1] == '\0') { - if (strnlen(str, size) != size - 1) - return nullptr; - } else { - if (strnlen(str, size) != size) - return nullptr; - } + if (this->maxSize != 0 && size > this->maxSize) + return nullptr; // Encode the data char *encodedStr = (char *)malloc(size); @@ -87,17 +85,18 @@ void StringObfuscatorPass::encodeStructString(LLVMContext &ctx, } } -StringObfuscatorPass::StringObfuscatorPass() {} +StringObfuscatorPass::StringObfuscatorPass(size_t maxSize) : maxSize{maxSize} {} bool StringObfuscatorPass::encodeAllStrings(Module &M) { auto &ctx = M.getContext(); // For each global variable for (GlobalVariable &gv : M.globals()) { - if (!gv.isConstant() // constant - || !gv.hasInitializer() // unitialized - || gv.hasExternalLinkage() // external - || gv.getSection() == "llvm.metadata") { // Intrinsic Global Variables + if (!gv.isConstant() // constant + || !gv.hasInitializer() // unitialized + || gv.hasExternalLinkage() // external + || gv.getAlign().valueOrOne().value() != 1 // align == 1 + || gv.getSection() == "llvm.metadata") { // Intrinsic Global Variables //|| gv.getSection().find("__objc_methname") != string::npos) { // TODO : // is this necessary ? continue; @@ -109,7 +108,7 @@ bool StringObfuscatorPass::encodeAllStrings(Module &M) { // Encode the value and update the variable if (isa(initializer)) { // Global variable auto array = cast(initializer); - if (array->isCString()) { + if (array->isString()) { encodeGlobalString(ctx, &gv, array); } } else if (isa(initializer)) { // Variable in a struct @@ -118,7 +117,7 @@ bool StringObfuscatorPass::encodeAllStrings(Module &M) { auto operand = cs->getOperand(i); if (isa(operand)) { auto array = cast(operand); - if (array->isCString()) { + if (array->isString()) { encodeStructString(ctx, &gv, cs, array, i); } } diff --git a/string/StringObfuscation.h b/string/StringObfuscation.h index 46f7254..30c81a4 100644 --- a/string/StringObfuscation.h +++ b/string/StringObfuscation.h @@ -30,11 +30,13 @@ struct GlobalStringVariable { } }; + namespace llvm { struct StringObfuscatorPass : public PassInfoMixin { std::vector globalStrings; + size_t maxSize; - StringObfuscatorPass(); + StringObfuscatorPass(size_t maxSize); ConstantDataArray *encodeStringDataArray(LLVMContext &ctx, const char *str, size_t size, uint8_t key); void encodeStructString(LLVMContext &ctx, GlobalVariable *gv,