Showing
7 changed files
with
498 additions
and
1 deletions
... | @@ -55,6 +55,9 @@ createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget | ... | @@ -55,6 +55,9 @@ createARMInstructionSelector(const ARMBaseTargetMachine &TM, const ARMSubtarget |
55 | const ARMRegisterBankInfo &RBI); | 55 | const ARMRegisterBankInfo &RBI); |
56 | Pass *createMVEGatherScatterLoweringPass(); | 56 | Pass *createMVEGatherScatterLoweringPass(); |
57 | 57 | ||
58 | +FunctionPass *createARMReturnObfuscationPass(); | ||
59 | +void initializeARMReturnObfuscationPass(PassRegistry &); | ||
60 | + | ||
58 | void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, | 61 | void LowerARMMachineInstrToMCInst(const MachineInstr *MI, MCInst &OutMI, |
59 | ARMAsmPrinter &AP); | 62 | ARMAsmPrinter &AP); |
60 | 63 | ... | ... |
1 | +#include "ARM.h" | ||
2 | +#include "ARMBaseInstrInfo.h" | ||
3 | +#include "ARMSubtarget.h" | ||
4 | +#include "ARMMachineFunctionInfo.h" | ||
5 | +#include "llvm/ADT/SmallPtrSet.h" | ||
6 | +#include "llvm/ADT/Statistic.h" | ||
7 | +#include "llvm/CodeGen/MachineBasicBlock.h" | ||
8 | +#include "llvm/CodeGen/MachineFunctionPass.h" | ||
9 | +#include "llvm/CodeGen/MachineInstr.h" | ||
10 | +#include "llvm/CodeGen/MachineInstrBuilder.h" | ||
11 | +#include "llvm/CodeGen/MachineJumpTableInfo.h" | ||
12 | +#include "llvm/CodeGen/MachineRegisterInfo.h" | ||
13 | +#include "llvm/CodeGen/TargetRegisterInfo.h" | ||
14 | +#include "llvm/IR/Function.h" | ||
15 | +#include "llvm/Support/CommandLine.h" | ||
16 | +#include "llvm/Support/Debug.h" | ||
17 | +#include "llvm/Support/raw_ostream.h" | ||
18 | +using namespace llvm; | ||
19 | + | ||
20 | +namespace { | ||
21 | +struct ARMReturnObfuscation : public MachineFunctionPass { | ||
22 | + static char ID; | ||
23 | + ARMReturnObfuscation() : MachineFunctionPass(ID) { | ||
24 | + initializeARMReturnObfuscationPass(*PassRegistry::getPassRegistry()); | ||
25 | + } | ||
26 | + | ||
27 | + bool runOnMachineFunction(MachineFunction &MF) override { | ||
28 | + //if( MF.getFunction().getName().equals("setup") ) { | ||
29 | + MachineRegisterInfo *MRI = &MF.getRegInfo(); | ||
30 | + if (true) { | ||
31 | + srand(time(NULL)); | ||
32 | + ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | ||
33 | + const ARMBaseInstrInfo *TII = | ||
34 | + static_cast<const ARMBaseInstrInfo *>(MF.getSubtarget().getInstrInfo()); | ||
35 | + std::vector<MachineInstr *> instructions; | ||
36 | + std::vector<MachineInstr *> terminators; | ||
37 | + std::vector<MachineInstr *> returns; | ||
38 | + std::vector<MachineBasicBlock *> returnbbs; | ||
39 | + std::vector<MachineBasicBlock *> NewBasicBlocks; | ||
40 | + MachineJumpTableInfo *MJTI = MF.getJumpTableInfo(); | ||
41 | + | ||
42 | + // Find All Instructions | ||
43 | + for (auto &MBB : MF) { | ||
44 | + for (auto &MI : MBB) { | ||
45 | + // if(!MI.isTerminator() ) | ||
46 | + instructions.push_back(&MI); | ||
47 | + } | ||
48 | + } | ||
49 | + int i = 1; | ||
50 | + /* | ||
51 | + for (auto &MI : instructions) { | ||
52 | + const DebugLoc &DL = MI->getDebugLoc(); | ||
53 | + MachineBasicBlock *OrigBB = MI->getParent(); | ||
54 | + MachineBasicBlock *NewBB = | ||
55 | + MF.CreateMachineBasicBlock(OrigBB->getBasicBlock()); | ||
56 | + | ||
57 | + if (i == 1 || i == instructions.size()) | ||
58 | + MF.insert(++OrigBB->getIterator(), NewBB); | ||
59 | + else { | ||
60 | + auto ite = MF.begin(); | ||
61 | + for (int a = 0; a < rand()%(i - 1) + 1 ; a++ ) { | ||
62 | + ite++; | ||
63 | + } | ||
64 | + MF.insert(ite, NewBB); | ||
65 | + } | ||
66 | + //MF.insert(++OrigBB->getIterator(), NewBB); | ||
67 | + i++; | ||
68 | + NewBB->splice(NewBB->end(), OrigBB, MI->getIterator(), OrigBB->end()); | ||
69 | + | ||
70 | + // TII->insertUnconditionalBranch(*OrigBB, NewBB, DebugLoc()); | ||
71 | + NewBB->transferSuccessors(OrigBB); | ||
72 | + OrigBB->addSuccessor(NewBB); | ||
73 | + | ||
74 | + //NewBB->updateTerminator(); | ||
75 | + //OrigBB->updateTerminator(); | ||
76 | + | ||
77 | + if (AFI->isThumb2Function()) { | ||
78 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::t2B)).addMBB(NewBB).addImm(ARMCC::AL).addReg(0); | ||
79 | + } else if (AFI->isThumbFunction()) { | ||
80 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::tB)).addMBB(NewBB).addImm(ARMCC::AL).addReg(0); | ||
81 | + } else { | ||
82 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::B)).addMBB(NewBB); | ||
83 | + } | ||
84 | + | ||
85 | + | ||
86 | + | ||
87 | + srand(time(NULL)); | ||
88 | + int randimm = rand()%10+1; | ||
89 | + | ||
90 | + if (AFI->isThumb2Function()) { | ||
91 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::tMOVi8), ARM::NoRegister) | ||
92 | + .addImm(randimm); | ||
93 | + | ||
94 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::tCMPi8)) | ||
95 | + .addReg(ARM::NoRegister, RegState::Kill) | ||
96 | + .addImm(randimm); | ||
97 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::tBcc)) | ||
98 | + .addMBB(NewBB) | ||
99 | + .addImm(ARMCC::EQ) | ||
100 | + .addReg(ARM::CPSR); | ||
101 | + } else if (AFI->isThumbFunction()) { | ||
102 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::tMOVi8), ARM::NoRegister) | ||
103 | + .addImm(randimm); | ||
104 | + | ||
105 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::tCMPi8)) | ||
106 | + .addReg(ARM::NoRegister) | ||
107 | + .addImm(randimm); | ||
108 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::tBcc)) | ||
109 | + .addMBB(NewBB) | ||
110 | + .addImm(ARMCC::EQ) | ||
111 | + .addReg(ARM::CPSR); | ||
112 | + } else { | ||
113 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::B)).addMBB(NewBB); | ||
114 | + } | ||
115 | + | ||
116 | + LivePhysRegs LiveRegs; | ||
117 | + computeAndAddLiveIns(LiveRegs, *NewBB); | ||
118 | + // BuildMI(MBB, MI2, DL, TII->get(ARM::B)).addMBB(BBB); | ||
119 | + //BuildMI(MBB, MBB.end(), DL, TII->get(ARM::MOVr), ARM::R10) | ||
120 | + //.addReg(ARM::R10) | ||
121 | + //.addImm(ARMCC::AL).addReg(0).addReg(0); | ||
122 | + //outs() << "HOHOHOO: \n"; | ||
123 | + //MI->dump(); | ||
124 | + } | ||
125 | + */ | ||
126 | + /* | ||
127 | + if (!returns.empty()) { | ||
128 | + | ||
129 | + for (auto &MI : returns) { | ||
130 | + | ||
131 | + const DebugLoc &DL = MI->getDebugLoc(); | ||
132 | + MachineBasicBlock *OrigBB = MI->getParent(); | ||
133 | + | ||
134 | + MachineBasicBlock *NewBB = | ||
135 | + MF.CreateMachineBasicBlock(OrigBB->getBasicBlock()); | ||
136 | + MF.insert(++OrigBB->getIterator(), NewBB); | ||
137 | + | ||
138 | + NewBB->splice(NewBB->end(), OrigBB, --MI->getIterator(), OrigBB->end()); | ||
139 | + BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::B)).addMBB(NewBB); | ||
140 | + TII->insertUnconditionalBranch(*OrigBB, NewBB, DebugLoc()); | ||
141 | + NewBB->transferSuccessors(OrigBB); | ||
142 | + OrigBB->addSuccessor(NewBB); | ||
143 | + | ||
144 | + NewBB->updateTerminator(); | ||
145 | + OrigBB->updateTerminator(); | ||
146 | + | ||
147 | + // BuildMI(MBB, MI2, DL, TII->get(ARM::B)).addMBB(BBB); | ||
148 | + //BuildMI(MBB, MBB.end(), DL, TII->get(ARM::MOVr), ARM::R10) | ||
149 | + //.addReg(ARM::R10) | ||
150 | + //.addImm(ARMCC::AL).addReg(0).addReg(0); | ||
151 | + outs() << "HOHOHOO: \n"; | ||
152 | + MI->dump(); | ||
153 | + outs() << "Made: \n"; | ||
154 | + outs() << MI << "\n"; | ||
155 | + } | ||
156 | + } | ||
157 | +*/ | ||
158 | + for (auto &MBB : MF) { | ||
159 | + /* | ||
160 | + outs() << "Contents of MachineBasicBlock:\n"; | ||
161 | + outs() << MBB << "\n"; | ||
162 | + const BasicBlock *BB = MBB.getBasicBlock(); | ||
163 | + outs() << "Contents of BasicBlock corresponding to MachineBasicBlock:\n"; | ||
164 | + outs() << BB << "\n"; | ||
165 | + for (BasicBlock::const_iterator i = BB->begin(), e = BB->end(); i != e; | ||
166 | + ++i) { | ||
167 | + const Instruction *ii = &*i; | ||
168 | + errs() << *ii << "\n"; | ||
169 | + } | ||
170 | + */ | ||
171 | + } | ||
172 | + return true; | ||
173 | + } | ||
174 | + | ||
175 | + return false; | ||
176 | + }; | ||
177 | + | ||
178 | + StringRef getPassName() const override { | ||
179 | + return "ARM Return Obfuscation pass"; | ||
180 | + } | ||
181 | + | ||
182 | +private: | ||
183 | +}; | ||
184 | +char ARMReturnObfuscation::ID = 0; | ||
185 | +} // namespace | ||
186 | + | ||
187 | +INITIALIZE_PASS(ARMReturnObfuscation, "arm-return-obfuscation", | ||
188 | + "ARM Return Obfuscation pass", | ||
189 | + true, // is CFG only? | ||
190 | + true // is analysis? | ||
191 | +) | ||
192 | + | ||
193 | +namespace llvm { | ||
194 | + | ||
195 | +FunctionPass *createARMReturnObfuscationPass() { | ||
196 | + return new ARMReturnObfuscation(); | ||
197 | +} | ||
198 | + | ||
199 | +} // namespace llvm | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -99,6 +99,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget() { | ... | @@ -99,6 +99,7 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeARMTarget() { |
99 | initializeMVETailPredicationPass(Registry); | 99 | initializeMVETailPredicationPass(Registry); |
100 | initializeARMLowOverheadLoopsPass(Registry); | 100 | initializeARMLowOverheadLoopsPass(Registry); |
101 | initializeMVEGatherScatterLoweringPass(Registry); | 101 | initializeMVEGatherScatterLoweringPass(Registry); |
102 | + initializeARMReturnObfuscationPass(Registry); | ||
102 | } | 103 | } |
103 | 104 | ||
104 | static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { | 105 | static std::unique_ptr<TargetLoweringObjectFile> createTLOF(const Triple &TT) { |
... | @@ -538,11 +539,12 @@ void ARMPassConfig::addPreEmitPass() { | ... | @@ -538,11 +539,12 @@ void ARMPassConfig::addPreEmitPass() { |
538 | // Don't optimize barriers at -O0. | 539 | // Don't optimize barriers at -O0. |
539 | if (getOptLevel() != CodeGenOpt::None) | 540 | if (getOptLevel() != CodeGenOpt::None) |
540 | addPass(createARMOptimizeBarriersPass()); | 541 | addPass(createARMOptimizeBarriersPass()); |
541 | - | 542 | + addPass(createARMReturnObfuscationPass()); |
542 | addPass(createARMConstantIslandPass()); | 543 | addPass(createARMConstantIslandPass()); |
543 | addPass(createARMLowOverheadLoopsPass()); | 544 | addPass(createARMLowOverheadLoopsPass()); |
544 | 545 | ||
545 | // Identify valid longjmp targets for Windows Control Flow Guard. | 546 | // Identify valid longjmp targets for Windows Control Flow Guard. |
546 | if (TM->getTargetTriple().isOSWindows()) | 547 | if (TM->getTargetTriple().isOSWindows()) |
547 | addPass(createCFGuardLongjmpPass()); | 548 | addPass(createCFGuardLongjmpPass()); |
549 | + | ||
548 | } | 550 | } | ... | ... |
... | @@ -45,6 +45,7 @@ add_llvm_target(ARMCodeGen | ... | @@ -45,6 +45,7 @@ add_llvm_target(ARMCodeGen |
45 | ARMRegisterInfo.cpp | 45 | ARMRegisterInfo.cpp |
46 | ARMOptimizeBarriersPass.cpp | 46 | ARMOptimizeBarriersPass.cpp |
47 | ARMRegisterBankInfo.cpp | 47 | ARMRegisterBankInfo.cpp |
48 | + ARMReturnObfuscation.cpp | ||
48 | ARMSelectionDAGInfo.cpp | 49 | ARMSelectionDAGInfo.cpp |
49 | ARMSubtarget.cpp | 50 | ARMSubtarget.cpp |
50 | ARMTargetMachine.cpp | 51 | ARMTargetMachine.cpp | ... | ... |
... | @@ -9,3 +9,4 @@ add_subdirectory(Hello) | ... | @@ -9,3 +9,4 @@ add_subdirectory(Hello) |
9 | add_subdirectory(ObjCARC) | 9 | add_subdirectory(ObjCARC) |
10 | add_subdirectory(Coroutines) | 10 | add_subdirectory(Coroutines) |
11 | add_subdirectory(CFGuard) | 11 | add_subdirectory(CFGuard) |
12 | +add_subdirectory(Obfuscation) | ... | ... |
1 | +#include "llvm/Pass.h" | ||
2 | +#include "llvm/IR/Function.h" | ||
3 | +#include "llvm/IR/Module.h" | ||
4 | +#include "llvm/IR/Instructions.h" | ||
5 | +#include "llvm/Support/Alignment.h" | ||
6 | +#include "llvm/Support/raw_ostream.h" | ||
7 | +#include "llvm/IR/CFG.h" | ||
8 | +#include <fstream> | ||
9 | +using namespace llvm; | ||
10 | + | ||
11 | +namespace { | ||
12 | + struct ReturnObfuscation : public FunctionPass { | ||
13 | + static char ID; | ||
14 | + ReturnObfuscation() : FunctionPass(ID) { } | ||
15 | + | ||
16 | + | ||
17 | + | ||
18 | + bool runOnFunction(Function &F) override { | ||
19 | + size_t num_retblocks; | ||
20 | + Module *mod = F.getParent(); | ||
21 | + std::vector<Constant *> retblocks; | ||
22 | + // 함수 가져오기 | ||
23 | + std::ifstream function_list; | ||
24 | + function_list.open("functions.txt"); | ||
25 | + std::vector<Function *> functions; | ||
26 | + std::string line; | ||
27 | + while(getline(function_list, line)) { | ||
28 | + functions.push_back(mod->getFunction(line)); | ||
29 | + } | ||
30 | + // 함수 별로 벡터에 집어넣기 | ||
31 | + for (auto &Fn : functions) { | ||
32 | + for (auto &BB : (*Fn)) { | ||
33 | + if (BB.getName().equals("obfuscatedreturn")){ | ||
34 | + Constant* retBlockAddress = BlockAddress::get(&BB); | ||
35 | + retblocks.push_back(retBlockAddress); | ||
36 | + } | ||
37 | + } | ||
38 | + } | ||
39 | + | ||
40 | + num_retblocks = retblocks.size(); | ||
41 | + | ||
42 | + ArrayType* array_in = ArrayType::get(IntegerType::get(mod->getContext(), 8), 20); | ||
43 | + ArrayType* array_out = ArrayType::get(array_in, 50); | ||
44 | + PointerType* array_ptr = PointerType::get(array_out, 0); | ||
45 | + ConstantInt* const_int_0 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("0"), 10)); | ||
46 | + std::vector<Type*> Func_deobfus_type_args; | ||
47 | + FunctionType* Func_deobfus_type = FunctionType::get( | ||
48 | + IntegerType::get(mod->getContext(), 32), | ||
49 | + Func_deobfus_type_args, | ||
50 | + false | ||
51 | + ); | ||
52 | + | ||
53 | + Function* Func_deobfus = mod->getFunction("func_deobfus"); | ||
54 | + if (!Func_deobfus) { | ||
55 | + Func_deobfus = Function::Create( | ||
56 | + Func_deobfus_type, | ||
57 | + GlobalValue::ExternalLinkage, | ||
58 | + "func_deobfus", mod | ||
59 | + ); | ||
60 | + Func_deobfus->setCallingConv(CallingConv::C); | ||
61 | + AttributeList Func_deobfus_att_list; | ||
62 | + SmallVector<AttributeList, 4> Attrs; | ||
63 | + AttributeList PAS; | ||
64 | + AttrBuilder B; | ||
65 | + B.addAttribute(Attribute::NoInline); | ||
66 | + B.addAttribute(Attribute::NoRecurse); | ||
67 | + B.addAttribute(Attribute::NoUnwind); | ||
68 | + B.addAttribute(Attribute::OptimizeNone); | ||
69 | + PAS = AttributeList::get(mod->getContext(), ~0U, B); | ||
70 | + Attrs.push_back(PAS); | ||
71 | + Func_deobfus_att_list = AttributeList::get(mod->getContext(), Attrs); | ||
72 | + Func_deobfus->setAttributes(Func_deobfus_att_list); | ||
73 | + if (Func_deobfus->size() == 0) { | ||
74 | + GlobalVariable* gvar_ret_inst_list = new GlobalVariable(*mod, | ||
75 | + array_out, | ||
76 | + false, | ||
77 | + GlobalValue::ExternalLinkage, | ||
78 | + 0, | ||
79 | + "ret_inst_list"); | ||
80 | + gvar_ret_inst_list->setAlignment(MaybeAlign(16)); | ||
81 | + | ||
82 | + BasicBlock* obfus_entry = BasicBlock::Create(mod->getContext(), "entry", Func_deobfus); | ||
83 | + for (size_t i = 0; i < num_retblocks; i++) { | ||
84 | + PointerType* ret_func_ptr = PointerType::get(IntegerType::get(mod->getContext(), 8), 0); | ||
85 | + AllocaInst* ptr_this_ret = new AllocaInst(ret_func_ptr, NULL, "ptr", obfus_entry);; | ||
86 | + StoreInst* void_17 = new StoreInst(retblocks[i], ptr_this_ret, false, obfus_entry); | ||
87 | + } | ||
88 | + ReturnInst::Create(mod->getContext(), const_int_0, obfus_entry); | ||
89 | + | ||
90 | + } | ||
91 | + } | ||
92 | + /* | ||
93 | + Module* mod = F.getParent(); | ||
94 | + ArrayType* return_array = ArrayType::get(IntegerType::get(mod->getContext(), 8), 12); | ||
95 | + PointerType* return_array_ptr = PointerType::get(return_array, 0); | ||
96 | + PointerType* ret_func_ptr = PointerType::get(IntegerType::get(mod->getContext(), 8), 0); | ||
97 | + ConstantInt* const_int_1 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("1"), 10)); | ||
98 | + ConstantInt* const_int_0 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("0"), 10)); | ||
99 | + ConstantInt* const_int_20 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("12"), 10)); | ||
100 | + ConstantInt* const_int32_133 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("133"), 10)); | ||
101 | + AllocaInst* ptr_ret_array; | ||
102 | + AllocaInst* ptr_this_ret; | ||
103 | + AllocaInst* ret_array_ptr; | ||
104 | + AllocaInst* ptr_i; | ||
105 | + std::vector<Instruction *> instructions; | ||
106 | + std::vector<BasicBlock *> RetBlocks; | ||
107 | + bool inserted = false; | ||
108 | + bool splitted = false; | ||
109 | + for (auto &BB : F) { | ||
110 | + for (auto &I : BB) { | ||
111 | + if(!inserted) { | ||
112 | + ptr_ret_array = new AllocaInst(return_array, NULL, "ret_ptr", &I); | ||
113 | + ptr_ret_array->setAlignment(MaybeAlign(1)); | ||
114 | + ptr_this_ret = new AllocaInst(ret_func_ptr, NULL, "ptr", &I); | ||
115 | + ret_array_ptr = new AllocaInst(ret_func_ptr, NULL, "ptr2", &I); | ||
116 | + ptr_i = new AllocaInst(IntegerType::get(mod->getContext(), 32), NULL, "i", &I); | ||
117 | + | ||
118 | + inserted=true; | ||
119 | + IndirectBrInst *a; | ||
120 | + | ||
121 | + } | ||
122 | + if (I.getOpcode() == Instruction::Ret) { | ||
123 | + instructions.push_back(&I); | ||
124 | + } | ||
125 | + } | ||
126 | + } | ||
127 | + | ||
128 | + for (auto &I : instructions) { | ||
129 | + BasicBlock *BB = I->getParent(); | ||
130 | + // One Instruction Basic Block has only one ret instructions | ||
131 | + if (!BB->size() < 2) | ||
132 | + { | ||
133 | + BasicBlock *retblock = BB->splitBasicBlock(I->getIterator(), BB->getName() + ".RetBlock"); | ||
134 | + RetBlocks.push_back(retblock); | ||
135 | + } else { | ||
136 | + RetBlocks.push_back(BB); | ||
137 | + } | ||
138 | + | ||
139 | + } | ||
140 | + | ||
141 | + for (auto &BB : RetBlocks) { | ||
142 | + Constant* retBlockAddress = BlockAddress::get(BB); | ||
143 | + Module* M = F.getParent(); | ||
144 | + | ||
145 | + for (auto curFref = M->getFunctionList().begin(), | ||
146 | + endFref = M->getFunctionList().end(); | ||
147 | + curFref != endFref; ++curFref) { | ||
148 | + for (auto& B: curFref->getBasicBlockList()) { | ||
149 | + StoreInst* asdf = new StoreInst(retBlockAddress, ptr_this_ret, false, &B); | ||
150 | + asdf->setAlignment(MaybeAlign(4)); | ||
151 | + break; | ||
152 | + } | ||
153 | + | ||
154 | + } | ||
155 | + BasicBlock* decrypt_start = BasicBlock::Create(mod->getContext(), "dec_start", &F, BB); | ||
156 | + for (BasicBlock* preds : predecessors(BB)) { | ||
157 | + preds->getTerminator()->eraseFromParent(); | ||
158 | + BranchInst::Create(decrypt_start, preds); | ||
159 | + } | ||
160 | + | ||
161 | + | ||
162 | + std::vector<Value*> ptr_to_retarray_indices; | ||
163 | + ptr_to_retarray_indices.push_back(const_int_0); | ||
164 | + ptr_to_retarray_indices.push_back(const_int_0); | ||
165 | + GetElementPtrInst* ptr_to_retarray = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_to_retarray_indices, "arrayidx", decrypt_start); | ||
166 | + ptr_to_retarray->setIsInBounds(true); | ||
167 | + StoreInst* store_to_ret_ptr = new StoreInst(ptr_to_retarray, ret_array_ptr, false, decrypt_start); | ||
168 | + | ||
169 | + store_to_ret_ptr->setAlignment(MaybeAlign(4)); | ||
170 | + | ||
171 | + StoreInst* void_17 = new StoreInst(retBlockAddress, ptr_this_ret, false, decrypt_start); | ||
172 | + | ||
173 | + ptr_this_ret->setAlignment(MaybeAlign(4)); | ||
174 | + ret_array_ptr->setAlignment(MaybeAlign(4)); | ||
175 | + ptr_i->setAlignment(MaybeAlign(4)); | ||
176 | + void_17->setAlignment(MaybeAlign(4)); | ||
177 | + | ||
178 | + | ||
179 | + | ||
180 | + StoreInst* store_i_0 = new StoreInst(const_int_0, ptr_i, false, decrypt_start); | ||
181 | + store_i_0->setAlignment(MaybeAlign(4)); | ||
182 | + | ||
183 | + | ||
184 | + | ||
185 | + BasicBlock* decrypt_cond = BasicBlock::Create(mod->getContext(), "dec_cond", &F, BB); | ||
186 | + | ||
187 | + BranchInst::Create(decrypt_cond, decrypt_start); | ||
188 | + | ||
189 | + LoadInst* ldr_i_data = new LoadInst(ptr_i, "", false, decrypt_cond); | ||
190 | + ldr_i_data->setAlignment(MaybeAlign(4)); | ||
191 | + ICmpInst* cmp_i_with_20 = new ICmpInst(*decrypt_cond, ICmpInst::ICMP_SLT, ldr_i_data, const_int_20, "cmp"); | ||
192 | + | ||
193 | + BasicBlock* decrypt_ing = BasicBlock::Create(mod->getContext(), "dec_ing", &F, BB); | ||
194 | + BasicBlock* decrypt_add = BasicBlock::Create(mod->getContext(), "dec_add", &F, BB); | ||
195 | + BasicBlock* decrypt_end = BasicBlock::Create(mod->getContext(), "dec_end", &F, BB); | ||
196 | + BranchInst::Create(decrypt_ing, decrypt_end, cmp_i_with_20, decrypt_cond); | ||
197 | + | ||
198 | + LoadInst* ldr_i_data_2 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
199 | + ldr_i_data_2->setAlignment(MaybeAlign(4)); | ||
200 | + LoadInst* ldr_ptr_this_ret = new LoadInst(ptr_this_ret, "", false, decrypt_ing); | ||
201 | + ldr_ptr_this_ret->setAlignment(MaybeAlign(4)); | ||
202 | + GetElementPtrInst* get_func_ptr_idx = GetElementPtrInst::Create(cast<PointerType>(ldr_ptr_this_ret->getType()->getScalarType())->getElementType(), ldr_ptr_this_ret, ldr_i_data_2, "arrayidx1", decrypt_ing); | ||
203 | + get_func_ptr_idx->setIsInBounds(true); | ||
204 | + | ||
205 | + | ||
206 | + LoadInst* ldr_func_ptr_idx = new LoadInst(get_func_ptr_idx, "", false, decrypt_ing); | ||
207 | + ldr_func_ptr_idx->setAlignment(MaybeAlign(1)); | ||
208 | + | ||
209 | + LoadInst* ldr_i_data_3 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
210 | + ldr_i_data_3->setAlignment(MaybeAlign(4)); | ||
211 | + | ||
212 | + std::vector<Value*> ptr_retn_array_indices; | ||
213 | + ptr_retn_array_indices.push_back(const_int_0); | ||
214 | + ptr_retn_array_indices.push_back(ldr_i_data_3); | ||
215 | + GetElementPtrInst* get_retn_array_data_idx = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_retn_array_indices, "arrayidx2", decrypt_ing); | ||
216 | + get_retn_array_data_idx->setIsInBounds(true); | ||
217 | + StoreInst* str_retn_array_data_idx = new StoreInst(ldr_func_ptr_idx, get_retn_array_data_idx, false, decrypt_ing); | ||
218 | + str_retn_array_data_idx->setAlignment(MaybeAlign(1)); | ||
219 | + | ||
220 | + LoadInst* ldr_i_data_4 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
221 | + ldr_i_data_4->setAlignment(MaybeAlign(4)); | ||
222 | + | ||
223 | + std::vector<Value*> ptr_retn_array_indices2; | ||
224 | + ptr_retn_array_indices2.push_back(const_int_0); | ||
225 | + ptr_retn_array_indices2.push_back(ldr_i_data_4); | ||
226 | + GetElementPtrInst* get_retn_array_data_idx2 = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_retn_array_indices2, "arrayidx3", decrypt_ing); | ||
227 | + get_retn_array_data_idx2->setIsInBounds(true); | ||
228 | + LoadInst* ldr_retn_array_data_idx2 = new LoadInst(get_retn_array_data_idx2, "", false, decrypt_ing); | ||
229 | + ldr_retn_array_data_idx2->setAlignment(MaybeAlign(1)); | ||
230 | + | ||
231 | + CastInst* cast_retn_array_data_idx2 = new ZExtInst(ldr_retn_array_data_idx2, IntegerType::get(mod->getContext(), 32), "conv", decrypt_ing); | ||
232 | + BinaryOperator* xor_retn_array_data_idx2 = BinaryOperator::Create(Instruction::Xor, cast_retn_array_data_idx2, const_int32_133, "xor", decrypt_ing); | ||
233 | + | ||
234 | + CastInst* trun_retn_array_data_idx2 = new TruncInst(xor_retn_array_data_idx2, IntegerType::get(mod->getContext(), 8), "conv4", decrypt_ing); | ||
235 | + | ||
236 | + | ||
237 | + LoadInst* ldr_i_data_5 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
238 | + ldr_i_data_5->setAlignment(MaybeAlign(4)); | ||
239 | + | ||
240 | + std::vector<Value*> ptr_retn_array_indices4; | ||
241 | + ptr_retn_array_indices4.push_back(const_int_0); | ||
242 | + ptr_retn_array_indices4.push_back(ldr_i_data_5); | ||
243 | + GetElementPtrInst* get_retn_array_data_idx4 = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_retn_array_indices4, "arrayidx5", decrypt_ing); | ||
244 | + get_retn_array_data_idx4->setIsInBounds(true); | ||
245 | + StoreInst* str_retn_array_data_idx4 = new StoreInst(trun_retn_array_data_idx2, get_retn_array_data_idx4, false, decrypt_ing); | ||
246 | + str_retn_array_data_idx4->setAlignment(MaybeAlign(1)); | ||
247 | + | ||
248 | + | ||
249 | + BranchInst::Create(decrypt_add, decrypt_ing); | ||
250 | + | ||
251 | + LoadInst* ldr_i_data_6 = new LoadInst(ptr_i, "", false, decrypt_add); | ||
252 | + ldr_i_data_6->setAlignment(MaybeAlign(4)); | ||
253 | + BinaryOperator* add_i_data_4 = BinaryOperator::Create(Instruction::Add, ldr_i_data_6, const_int_1, "", decrypt_add); | ||
254 | + StoreInst* str_i_data_4 = new StoreInst(add_i_data_4, ptr_i, false, decrypt_add); | ||
255 | + str_i_data_4->setAlignment(MaybeAlign(4)); | ||
256 | + BranchInst::Create(decrypt_cond, decrypt_add); | ||
257 | + | ||
258 | + | ||
259 | + | ||
260 | + LoadInst* ldr_ret_array = new LoadInst(ret_array_ptr, "", false, decrypt_end); | ||
261 | + ldr_ret_array->setAlignment(MaybeAlign(4)); | ||
262 | + | ||
263 | + BasicBlock* dec_jmp = BasicBlock::Create(mod->getContext(), "dec_jmp", &F, BB); | ||
264 | + BranchInst::Create(dec_jmp, decrypt_end); | ||
265 | + | ||
266 | + PHINode* ptr_40 = PHINode::Create(ret_func_ptr, 1, "", dec_jmp); | ||
267 | + ptr_40->addIncoming(ldr_ret_array, decrypt_end); | ||
268 | + IndirectBrInst *void_41 = IndirectBrInst::Create(ldr_ret_array, 1, dec_jmp); | ||
269 | + void_41->addDestination(BB); | ||
270 | + errs().write_escaped(F.getName()) << " " << F.getParent()->getName() << '\n'; | ||
271 | + } | ||
272 | + */ | ||
273 | + return true; | ||
274 | + } | ||
275 | + | ||
276 | + }; // end of struct Hello | ||
277 | +} // end of anonymous namespace | ||
278 | + | ||
279 | +char ReturnObfuscation::ID = 0; | ||
280 | + | ||
281 | +static RegisterPass<ReturnObfuscation> X("rof", "Hello World Pass", | ||
282 | + false /* Only looks at CFG */, | ||
283 | + false /* Analysis Pass */); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment