Skip to content

Commit b1c31b0

Browse files
sr-treamMaxXor
authored andcommitted
Add support for new PassManager
1 parent b9e26cd commit b1c31b0

15 files changed

+961
-748
lines changed

README.md

+6-4
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ Obfuscator-LLVM is a project initiated in June 2010 by the information security
66

77
Here is a list of the different features that are currently available:
88

9-
* [Instructions Substitution](https://github.com/obfuscator-llvm/obfuscator/wiki/Instructions-Substitution) `-mllvm -sub`
10-
* [Bogus Control Flow](https://github.com/obfuscator-llvm/obfuscator/wiki/Bogus-Control-Flow) `-mllvm -bcf`
11-
* [Control Flow Flattening](https://github.com/obfuscator-llvm/obfuscator/wiki/Control-Flow-Flattening) `-mllvm -fla`
12-
* [Functions annotations](https://github.com/obfuscator-llvm/obfuscator/wiki/Functions-annotations)
9+
* [Instructions Substitution](https://github.com/obfuscator-llvm/obfuscator/wiki/Instructions-Substitution) `-mllvm -sub` (only old PassManager)
10+
* [Bogus Control Flow](https://github.com/obfuscator-llvm/obfuscator/wiki/Bogus-Control-Flow) `-mllvm -bcf` (only old PassManager)
11+
* [Control Flow Flattening](https://github.com/obfuscator-llvm/obfuscator/wiki/Control-Flow-Flattening) `-mllvm -fla` (only old PassManager)
12+
* [Functions annotations](https://github.com/obfuscator-llvm/obfuscator/wiki/Functions-annotations) (any pass manager)
1313

1414
## Building
1515

@@ -22,6 +22,8 @@ cmake ../
2222
cmake --build .
2323
```
2424

25+
To build for old PassManager add CMake flag `-DLLVM_ENABLE_NEW_PASS_MANAGER=OFF`.
26+
2527
## Usage
2628

2729
Adding the obfuscator to existing projects which use an LLVM compiler is very easy. For the Make (or rather Makefile) buildsystem simply adjust the small example below to fit your needs:

obfuscator-llvm/BogusControlFlow.cpp

+606-514
Large diffs are not rendered by default.

obfuscator-llvm/BogusControlFlow.h

+28-29
Original file line numberDiff line numberDiff line change
@@ -1,48 +1,47 @@
1-
//===- BogusControlFlow.h - BogusControlFlow Obfuscation pass------------------------===//
1+
//===- BogusControlFlow.h - bogus control flow obfuscation pass -----------===//
22
//
33
// The LLVM Compiler Infrastructure
44
//
55
// This file is distributed under the University of Illinois Open Source
66
// License. See LICENSE.TXT for details.
77
//
8-
//===--------------------------------------------------------------------------------===//
8+
//===----------------------------------------------------------------------===//
99
//
10-
// This file contains includes and defines for the bogusControlFlow pass
10+
// This file contains includes and defines for the bogus control flow pass
1111
//
12-
//===--------------------------------------------------------------------------------===//
12+
//===----------------------------------------------------------------------===//
13+
#ifndef _OBFUSCATION_BOGUSCONTROLFLOW_H_
14+
#define _OBFUSCATION_BOGUSCONTROLFLOW_H_
1315

14-
#ifndef _BOGUSCONTROLFLOW_H_
15-
#define _BOGUSCONTROLFLOW_H_
16-
17-
18-
// LLVM include
19-
#include "llvm/Pass.h"
20-
#include "llvm/IR/Module.h"
21-
#include "llvm/IR/Function.h"
16+
#include "llvm/ADT/Statistic.h"
17+
#include "llvm/CodeGen/ISDOpcodes.h"
2218
#include "llvm/IR/BasicBlock.h"
23-
#include "llvm/IR/Instructions.h"
24-
#include "llvm/IR/InstrTypes.h"
2519
#include "llvm/IR/Constants.h"
26-
#include "llvm/IR/Type.h"
27-
#include "llvm/ADT/Statistic.h"
20+
#include "llvm/IR/Function.h"
2821
#include "llvm/IR/GlobalValue.h"
22+
#include "llvm/IR/InstrTypes.h"
23+
#include "llvm/IR/Instructions.h"
2924
#include "llvm/IR/LLVMContext.h"
30-
#include "llvm/Transforms/Utils/Cloning.h"
31-
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
32-
#include "llvm/CodeGen/ISDOpcodes.h"
33-
#include "llvm/Support/raw_ostream.h"
34-
#include "llvm/Support/Debug.h"
25+
#include "llvm/IR/Module.h"
26+
#include "llvm/IR/Type.h"
27+
#include "llvm/Pass.h"
3528
#include "llvm/Support/CommandLine.h"
29+
#include "llvm/Support/Debug.h"
30+
#include "llvm/Support/raw_ostream.h"
3631
#include "llvm/Transforms/IPO.h"
3732
#include "CryptoUtils.h"
38-
#include <list>
39-
40-
using namespace std;
41-
using namespace llvm;
33+
#include "llvm/Transforms/Utils/BasicBlockUtils.h"
34+
#include "llvm/Transforms/Utils/Cloning.h"
35+
#include "llvm/IR/PassManager.h" // New PassManager
4236

43-
// Namespace
4437
namespace llvm {
45-
Pass *createBogus (bool flag);
46-
}
47-
#endif
38+
Pass *createBogus();
39+
class BogusControlFlowPass : public PassInfoMixin<BogusControlFlowPass>{ // New PassManager
40+
public:
41+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
42+
43+
static bool isRequired() { return true; }
44+
};
45+
} // namespace llvm
4846

47+
#endif

obfuscator-llvm/CMakeLists.txt

+33-12
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,36 @@
1-
add_llvm_library(ObfuscatorLLVM MODULE
2-
# List your source files here.
3-
Obfuscation.cpp
4-
CryptoUtils.cpp
5-
Substitution.cpp
6-
BogusControlFlow.cpp
7-
SplitBasicBlocks.cpp
8-
Flattening.cpp
9-
Utils.cpp
10-
PLUGIN_TOOL
11-
opt
12-
)
1+
set(LLVM_ENABLE_NEW_PASS_MANAGER ON CACHE BOOL "Use new PM")
2+
3+
if (LLVM_ENABLE_NEW_PASS_MANAGER)
4+
add_llvm_pass_plugin(ObfuscatorLLVM
5+
Obfuscation.cpp
6+
CryptoUtils.cpp
7+
Substitution.cpp
8+
BogusControlFlow.cpp
9+
SplitBasicBlocks.cpp
10+
Flattening.cpp
11+
Utils.cpp
12+
)
13+
target_link_libraries(ObfuscatorLLVM
14+
PUBLIC
15+
LLVMSupport
16+
LLVMCore
17+
LLVMipo
18+
LLVMPasses
19+
)
20+
else()
21+
add_llvm_library(ObfuscatorLLVM MODULE
22+
# List your source files here.
23+
Obfuscation.cpp
24+
CryptoUtils.cpp
25+
Substitution.cpp
26+
BogusControlFlow.cpp
27+
SplitBasicBlocks.cpp
28+
Flattening.cpp
29+
Utils.cpp
30+
PLUGIN_TOOL
31+
opt
32+
)
33+
endif()
1334

1435
# Use C++11 to compile your pass (i.e., supply -std=c++11).
1536
target_compile_features(ObfuscatorLLVM PRIVATE cxx_range_for cxx_auto_type)

obfuscator-llvm/Flattening.cpp

+27-14
Original file line numberDiff line numberDiff line change
@@ -20,30 +20,31 @@
2020

2121
using namespace llvm;
2222

23+
static cl::opt<bool> FlatteningArg("fla", cl::init(false),
24+
cl::desc("Enable the flattening pass"));
25+
2326
// Stats
2427
STATISTIC(Flattened, "Functions flattened");
2528

2629
namespace {
2730
struct Flattening : public FunctionPass {
28-
static char ID; // Pass identification, replacement for typeid
29-
bool flag;
31+
static char ID; // Pass identification, replacement for typeid
3032

3133
Flattening() : FunctionPass(ID) {}
32-
Flattening(bool flag) : FunctionPass(ID) { this->flag = flag; }
3334

3435
bool runOnFunction(Function &F);
3536
bool flatten(Function *f);
3637
};
37-
}
38+
} // namespace
3839

3940
char Flattening::ID = 0;
4041
static RegisterPass<Flattening> X("flattening", "Call graph flattening");
41-
Pass *llvm::createFlattening(bool flag) { return new Flattening(flag); }
42+
Pass *llvm::createFlattening() { return new Flattening(); }
4243

4344
bool Flattening::runOnFunction(Function &F) {
4445
Function *tmp = &F;
4546
// Do we obfuscate
46-
if (toObfuscate(flag, tmp, "fla")) {
47+
if (toObfuscate(FlatteningArg, tmp, "fla")) {
4748
if (flatten(tmp)) {
4849
++Flattened;
4950
}
@@ -52,8 +53,15 @@ bool Flattening::runOnFunction(Function &F) {
5253
return false;
5354
}
5455

56+
PreservedAnalyses FlatteningPass::run(Function &F, FunctionAnalysisManager &AM){
57+
Flattening fla;
58+
fla.runOnFunction(F);
59+
60+
return PreservedAnalyses::none();
61+
}
62+
5563
bool Flattening::flatten(Function *f) {
56-
vector<BasicBlock *> origBB;
64+
std::vector<BasicBlock *> origBB;
5765
BasicBlock *loopEntry;
5866
BasicBlock *loopEnd;
5967
LoadInst *load;
@@ -65,9 +73,14 @@ bool Flattening::flatten(Function *f) {
6573
llvm::cryptoutils->get_bytes(scrambling_key, 16);
6674
// END OF SCRAMBLER
6775

76+
#if LLVM_VERSION_MAJOR >= 9
77+
// >=9.0, LowerSwitchPass depends on LazyValueInfoWrapperPass, which cause AssertError.
78+
// So I move LowerSwitchPass into register function, just before FlatteningPass.
79+
#else
6880
// Lower switch
6981
FunctionPass *lower = createLowerSwitchPass();
7082
lower->runOnFunction(*f);
83+
#endif
7184

7285
// Save all original BB
7386
for (Function::iterator i = f->begin(); i != f->end(); ++i) {
@@ -89,7 +102,7 @@ bool Flattening::flatten(Function *f) {
89102
origBB.erase(origBB.begin());
90103

91104
// Get a pointer on the first BB
92-
Function::iterator tmp = f->begin(); //++tmp;
105+
Function::iterator tmp = f->begin(); //++tmp;
93106
BasicBlock *insert = &*tmp;
94107

95108
// If main begin with an if
@@ -101,7 +114,7 @@ bool Flattening::flatten(Function *f) {
101114
if ((br != NULL && br->isConditional()) ||
102115
insert->getTerminator()->getNumSuccessors() > 1) {
103116
BasicBlock::iterator i = insert->end();
104-
--i;
117+
--i;
105118

106119
if (insert->size() > 1) {
107120
--i;
@@ -126,7 +139,7 @@ bool Flattening::flatten(Function *f) {
126139
loopEntry = BasicBlock::Create(f->getContext(), "loopEntry", f, insert);
127140
loopEnd = BasicBlock::Create(f->getContext(), "loopEnd", f, insert);
128141

129-
load = new LoadInst(switchVar->getAllocatedType(), switchVar, "switchVar", loopEntry);
142+
load = new LoadInst(switchVar->getType()->getElementType(), switchVar, "switchVar", loopEntry);
130143

131144
// Move first BB on top
132145
insert->moveBefore(loopEntry);
@@ -149,8 +162,8 @@ bool Flattening::flatten(Function *f) {
149162
BranchInst::Create(loopEntry, &*f->begin());
150163

151164
// Put all BB in the switch
152-
for (vector<BasicBlock *>::iterator b = origBB.begin(); b != origBB.end();
153-
++b) {
165+
for (std::vector<BasicBlock *>::iterator b = origBB.begin();
166+
b != origBB.end(); ++b) {
154167
BasicBlock *i = *b;
155168
ConstantInt *numCase = NULL;
156169

@@ -165,8 +178,8 @@ bool Flattening::flatten(Function *f) {
165178
}
166179

167180
// Recalculate switchVar
168-
for (vector<BasicBlock *>::iterator b = origBB.begin(); b != origBB.end();
169-
++b) {
181+
for (std::vector<BasicBlock *>::iterator b = origBB.begin();
182+
b != origBB.end(); ++b) {
170183
BasicBlock *i = *b;
171184
ConstantInt *numCase = NULL;
172185

obfuscator-llvm/Flattening.h

+17-15
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
//===- Flattening.h - Flattening Obfuscation pass--------------------------===//
1+
//===- FlatteningIncludes.h - Flattening Obfuscation pass------------------===//
22
//
33
// The LLVM Compiler Infrastructure
44
//
@@ -11,27 +11,29 @@
1111
//
1212
//===----------------------------------------------------------------------===//
1313

14-
#ifndef _FLATTENING_INCLUDES_
15-
#define _FLATTENING_INCLUDES_
14+
#ifndef _OBFUSCATION_FLATTENING_H_
15+
#define _OBFUSCATION_FLATTENING_H_
1616

17-
18-
// LLVM include
19-
#include "llvm/Pass.h"
20-
#include "llvm/IR/Function.h"
2117
#include "llvm/ADT/Statistic.h"
22-
#include "llvm/Transforms/Utils/Local.h" // For DemoteRegToStack and DemotePHIToStack
23-
#include "llvm/Transforms/IPO.h"
24-
#include "llvm/Transforms/Scalar.h"
18+
#include "llvm/IR/Function.h"
2519
#include "llvm/IR/Module.h"
20+
#include "llvm/Pass.h"
2621
#include "llvm/Support/CommandLine.h"
22+
#include "llvm/Transforms/IPO.h"
2723
#include "CryptoUtils.h"
2824
#include "Utils.h"
29-
30-
// Namespace
31-
using namespace std;
25+
#include "llvm/Transforms/Scalar.h"
26+
#include "llvm/Transforms/Utils/Local.h" // For DemoteRegToStack and DemotePHIToStack
27+
#include "llvm/IR/PassManager.h" // New PassManager
3228

3329
namespace llvm {
34-
Pass *createFlattening(bool flag);
35-
}
30+
Pass *createFlattening();
31+
class FlatteningPass : public PassInfoMixin<FlatteningPass>{ // New PassManager
32+
public:
33+
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
34+
35+
static bool isRequired() { return true; }
36+
};
37+
} // namespace llvm
3638

3739
#endif

obfuscator-llvm/Obfuscation.cpp

+29-8
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
11
#include "llvm/IR/LegacyPassManager.h"
22
#include "llvm/Transforms/IPO/PassManagerBuilder.h"
3+
#include "llvm/Passes/PassPlugin.h"
4+
#include "llvm/Passes/PassBuilder.h"
35
#include "Substitution.h"
46
#include "Flattening.h"
57
#include "SplitBasicBlocks.h"
68
#include "BogusControlFlow.h"
79

10+
using namespace llvm;
11+
812
// Flags for obfuscation
9-
static cl::opt<bool> Flattening("fla", cl::init(false), cl::desc("Enable the flattening pass"));
10-
static cl::opt<bool> BogusControlFlow("bcf", cl::init(false), cl::desc("Enable bogus control flow"));
11-
static cl::opt<bool> Substitution("sub", cl::init(false), cl::desc("Enable instruction substitutions"));
1213
static cl::opt<std::string> AesSeed("aesSeed", cl::init(""), cl::desc("seed for the AES-CTR PRNG"));
13-
static cl::opt<bool> Split("spli", cl::init(false), cl::desc("Enable basic block splitting"));
1414

1515
static void loadPass(const PassManagerBuilder &Builder, legacy::PassManagerBase &PM) {
1616
// Initialization of the global cryptographically
@@ -20,10 +20,10 @@ static void loadPass(const PassManagerBuilder &Builder, legacy::PassManagerBase
2020
exit(1);
2121
}
2222
}
23-
PM.add(createSplitBasicBlock(Split));
24-
PM.add(createBogus(BogusControlFlow));
25-
PM.add(createFlattening(Flattening));
26-
PM.add(createSubstitution(Substitution));
23+
PM.add(createSplitBasicBlock());
24+
PM.add(createBogus());
25+
PM.add(createFlattening());
26+
PM.add(createSubstitution());
2727
}
2828

2929
// These constructors add our pass to a list of global extensions.
@@ -37,3 +37,24 @@ static RegisterStandardPasses clangtoolLoader_O0(PassManagerBuilder::EP_EnabledO
3737
// you're in -O0, and EP_OptimizerLast only runs if you're not). You can check
3838
// include/llvm/Transforms/IPO/PassManagerBuilder.h header and
3939
// lib/Transforms/IPO/PassManagerBuilder.cpp file for the exact behavior.
40+
41+
PassPluginLibraryInfo getObfuscatorLLVMPluginInfo(){
42+
return {LLVM_PLUGIN_API_VERSION, "ObfuscatorLLVM", LLVM_VERSION_STRING, [](PassBuilder &PB){
43+
PB.registerVectorizerStartEPCallback([](FunctionPassManager &PM, PassBuilder::OptimizationLevel level){
44+
if(!AesSeed.empty()) {
45+
if(!llvm::cryptoutils->prng_seed(AesSeed.c_str())) {
46+
exit(1);
47+
}
48+
}
49+
PM.addPass(SplitBasicBlockPass());
50+
PM.addPass(BogusControlFlowPass());
51+
PM.addPass(FlatteningPass());
52+
PM.addPass(SubstitutionPass());
53+
});
54+
}};
55+
}
56+
57+
extern "C" LLVM_ATTRIBUTE_WEAK ::llvm::PassPluginLibraryInfo
58+
llvmGetPassPluginInfo() {
59+
return getObfuscatorLLVMPluginInfo();
60+
}

0 commit comments

Comments
 (0)