Showing
5 changed files
with
246 additions
and
7 deletions
... | @@ -26,7 +26,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { | ... | @@ -26,7 +26,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { |
26 | 26 | ||
27 | bool runOnMachineFunction(MachineFunction &MF) override { | 27 | bool runOnMachineFunction(MachineFunction &MF) override { |
28 | //if( MF.getFunction().getName().equals("setup") ) { | 28 | //if( MF.getFunction().getName().equals("setup") ) { |
29 | - | 29 | + MachineRegisterInfo *MRI = &MF.getRegInfo(); |
30 | if (true) { | 30 | if (true) { |
31 | srand(time(NULL)); | 31 | srand(time(NULL)); |
32 | ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); | 32 | ARMFunctionInfo *AFI = MF.getInfo<ARMFunctionInfo>(); |
... | @@ -47,11 +47,13 @@ struct ARMReturnObfuscation : public MachineFunctionPass { | ... | @@ -47,11 +47,13 @@ struct ARMReturnObfuscation : public MachineFunctionPass { |
47 | } | 47 | } |
48 | } | 48 | } |
49 | int i = 1; | 49 | int i = 1; |
50 | + /* | ||
50 | for (auto &MI : instructions) { | 51 | for (auto &MI : instructions) { |
51 | const DebugLoc &DL = MI->getDebugLoc(); | 52 | const DebugLoc &DL = MI->getDebugLoc(); |
52 | MachineBasicBlock *OrigBB = MI->getParent(); | 53 | MachineBasicBlock *OrigBB = MI->getParent(); |
53 | MachineBasicBlock *NewBB = | 54 | MachineBasicBlock *NewBB = |
54 | MF.CreateMachineBasicBlock(OrigBB->getBasicBlock()); | 55 | MF.CreateMachineBasicBlock(OrigBB->getBasicBlock()); |
56 | + | ||
55 | if (i == 1 || i == instructions.size()) | 57 | if (i == 1 || i == instructions.size()) |
56 | MF.insert(++OrigBB->getIterator(), NewBB); | 58 | MF.insert(++OrigBB->getIterator(), NewBB); |
57 | else { | 59 | else { |
... | @@ -61,8 +63,8 @@ struct ARMReturnObfuscation : public MachineFunctionPass { | ... | @@ -61,8 +63,8 @@ struct ARMReturnObfuscation : public MachineFunctionPass { |
61 | } | 63 | } |
62 | MF.insert(ite, NewBB); | 64 | MF.insert(ite, NewBB); |
63 | } | 65 | } |
66 | + //MF.insert(++OrigBB->getIterator(), NewBB); | ||
64 | i++; | 67 | i++; |
65 | - | ||
66 | NewBB->splice(NewBB->end(), OrigBB, MI->getIterator(), OrigBB->end()); | 68 | NewBB->splice(NewBB->end(), OrigBB, MI->getIterator(), OrigBB->end()); |
67 | 69 | ||
68 | // TII->insertUnconditionalBranch(*OrigBB, NewBB, DebugLoc()); | 70 | // TII->insertUnconditionalBranch(*OrigBB, NewBB, DebugLoc()); |
... | @@ -71,6 +73,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { | ... | @@ -71,6 +73,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { |
71 | 73 | ||
72 | //NewBB->updateTerminator(); | 74 | //NewBB->updateTerminator(); |
73 | //OrigBB->updateTerminator(); | 75 | //OrigBB->updateTerminator(); |
76 | + | ||
74 | if (AFI->isThumb2Function()) { | 77 | if (AFI->isThumb2Function()) { |
75 | BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::t2B)).addMBB(NewBB).addImm(ARMCC::AL).addReg(0); | 78 | BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::t2B)).addMBB(NewBB).addImm(ARMCC::AL).addReg(0); |
76 | } else if (AFI->isThumbFunction()) { | 79 | } else if (AFI->isThumbFunction()) { |
... | @@ -78,15 +81,48 @@ struct ARMReturnObfuscation : public MachineFunctionPass { | ... | @@ -78,15 +81,48 @@ struct ARMReturnObfuscation : public MachineFunctionPass { |
78 | } else { | 81 | } else { |
79 | BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::B)).addMBB(NewBB); | 82 | BuildMI(*OrigBB, OrigBB->end(), DL, TII->get(ARM::B)).addMBB(NewBB); |
80 | } | 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 | + | ||
81 | LivePhysRegs LiveRegs; | 116 | LivePhysRegs LiveRegs; |
82 | computeAndAddLiveIns(LiveRegs, *NewBB); | 117 | computeAndAddLiveIns(LiveRegs, *NewBB); |
83 | // BuildMI(MBB, MI2, DL, TII->get(ARM::B)).addMBB(BBB); | 118 | // BuildMI(MBB, MI2, DL, TII->get(ARM::B)).addMBB(BBB); |
84 | //BuildMI(MBB, MBB.end(), DL, TII->get(ARM::MOVr), ARM::R10) | 119 | //BuildMI(MBB, MBB.end(), DL, TII->get(ARM::MOVr), ARM::R10) |
85 | //.addReg(ARM::R10) | 120 | //.addReg(ARM::R10) |
86 | //.addImm(ARMCC::AL).addReg(0).addReg(0); | 121 | //.addImm(ARMCC::AL).addReg(0).addReg(0); |
87 | - outs() << "HOHOHOO: \n"; | 122 | + //outs() << "HOHOHOO: \n"; |
88 | - MI->dump(); | 123 | + //MI->dump(); |
89 | } | 124 | } |
125 | + */ | ||
90 | /* | 126 | /* |
91 | if (!returns.empty()) { | 127 | if (!returns.empty()) { |
92 | 128 | ||
... | @@ -120,6 +156,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { | ... | @@ -120,6 +156,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { |
120 | } | 156 | } |
121 | */ | 157 | */ |
122 | for (auto &MBB : MF) { | 158 | for (auto &MBB : MF) { |
159 | + /* | ||
123 | outs() << "Contents of MachineBasicBlock:\n"; | 160 | outs() << "Contents of MachineBasicBlock:\n"; |
124 | outs() << MBB << "\n"; | 161 | outs() << MBB << "\n"; |
125 | const BasicBlock *BB = MBB.getBasicBlock(); | 162 | const BasicBlock *BB = MBB.getBasicBlock(); |
... | @@ -130,6 +167,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { | ... | @@ -130,6 +167,7 @@ struct ARMReturnObfuscation : public MachineFunctionPass { |
130 | const Instruction *ii = &*i; | 167 | const Instruction *ii = &*i; |
131 | errs() << *ii << "\n"; | 168 | errs() << *ii << "\n"; |
132 | } | 169 | } |
170 | + */ | ||
133 | } | 171 | } |
134 | return true; | 172 | return true; |
135 | } | 173 | } | ... | ... |
... | @@ -492,8 +492,6 @@ void ARMPassConfig::addPreRegAlloc() { | ... | @@ -492,8 +492,6 @@ void ARMPassConfig::addPreRegAlloc() { |
492 | if (!DisableA15SDOptimization) | 492 | if (!DisableA15SDOptimization) |
493 | addPass(createA15SDOptimizerPass()); | 493 | addPass(createA15SDOptimizerPass()); |
494 | } | 494 | } |
495 | - | ||
496 | - addPass(createARMReturnObfuscationPass()); | ||
497 | } | 495 | } |
498 | 496 | ||
499 | void ARMPassConfig::addPreSched2() { | 497 | void ARMPassConfig::addPreSched2() { |
... | @@ -541,11 +539,12 @@ void ARMPassConfig::addPreEmitPass() { | ... | @@ -541,11 +539,12 @@ void ARMPassConfig::addPreEmitPass() { |
541 | // Don't optimize barriers at -O0. | 539 | // Don't optimize barriers at -O0. |
542 | if (getOptLevel() != CodeGenOpt::None) | 540 | if (getOptLevel() != CodeGenOpt::None) |
543 | addPass(createARMOptimizeBarriersPass()); | 541 | addPass(createARMOptimizeBarriersPass()); |
544 | - | 542 | + addPass(createARMReturnObfuscationPass()); |
545 | addPass(createARMConstantIslandPass()); | 543 | addPass(createARMConstantIslandPass()); |
546 | addPass(createARMLowOverheadLoopsPass()); | 544 | addPass(createARMLowOverheadLoopsPass()); |
547 | 545 | ||
548 | // Identify valid longjmp targets for Windows Control Flow Guard. | 546 | // Identify valid longjmp targets for Windows Control Flow Guard. |
549 | if (TM->getTargetTriple().isOSWindows()) | 547 | if (TM->getTargetTriple().isOSWindows()) |
550 | addPass(createCFGuardLongjmpPass()); | 548 | addPass(createCFGuardLongjmpPass()); |
549 | + | ||
551 | } | 550 | } | ... | ... |
... | @@ -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 | +using namespace llvm; | ||
9 | + | ||
10 | +namespace { | ||
11 | + struct ReturnObfuscation : public FunctionPass { | ||
12 | + static char ID; | ||
13 | + ReturnObfuscation() : FunctionPass(ID) {} | ||
14 | + bool runOnFunction(Function &F) override { | ||
15 | + Module* mod = F.getParent(); | ||
16 | + /* | ||
17 | + if (!F.getName().contains("setup") && !F.getName().contains("test")) { | ||
18 | + return false; | ||
19 | + }*/ | ||
20 | + ArrayType* return_array = ArrayType::get(IntegerType::get(mod->getContext(), 8), 12); | ||
21 | + PointerType* return_array_ptr = PointerType::get(return_array, 0); | ||
22 | + PointerType* ret_func_ptr = PointerType::get(IntegerType::get(mod->getContext(), 8), 0); | ||
23 | + ConstantInt* const_int_1 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("1"), 10)); | ||
24 | + ConstantInt* const_int_0 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("0"), 10)); | ||
25 | + ConstantInt* const_int_20 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("12"), 10)); | ||
26 | + ConstantInt* const_int32_133 = ConstantInt::get(mod->getContext(), APInt(32, StringRef("133"), 10)); | ||
27 | + AllocaInst* ptr_ret_array; | ||
28 | + AllocaInst* ptr_this_ret; | ||
29 | + AllocaInst* ret_array_ptr; | ||
30 | + AllocaInst* ptr_i; | ||
31 | + std::vector<Instruction *> instructions; | ||
32 | + std::vector<BasicBlock *> RetBlocks; | ||
33 | + bool inserted = false; | ||
34 | + bool splitted = false; | ||
35 | + for (auto &BB : F) { | ||
36 | + for (auto &I : BB) { | ||
37 | + if(!inserted) { | ||
38 | + ptr_ret_array = new AllocaInst(return_array, NULL, "ret_ptr", &I); | ||
39 | + ptr_ret_array->setAlignment(MaybeAlign(1)); | ||
40 | + ptr_this_ret = new AllocaInst(ret_func_ptr, NULL, "ptr", &I); | ||
41 | + ret_array_ptr = new AllocaInst(ret_func_ptr, NULL, "ptr2", &I); | ||
42 | + ptr_i = new AllocaInst(IntegerType::get(mod->getContext(), 32), NULL, "i", &I); | ||
43 | + | ||
44 | + inserted=true; | ||
45 | + IndirectBrInst *a; | ||
46 | + | ||
47 | + } | ||
48 | + if (I.getOpcode() == Instruction::Ret) { | ||
49 | + instructions.push_back(&I); | ||
50 | + } | ||
51 | + } | ||
52 | + } | ||
53 | + | ||
54 | + for (auto &I : instructions) { | ||
55 | + BasicBlock *BB = I->getParent(); | ||
56 | + // One Instruction Basic Block has only one ret instructions | ||
57 | + if (!BB->size() < 2) | ||
58 | + { | ||
59 | + BasicBlock *retblock = BB->splitBasicBlock(I->getIterator(), BB->getName() + ".RetBlock"); | ||
60 | + RetBlocks.push_back(retblock); | ||
61 | + } else { | ||
62 | + RetBlocks.push_back(BB); | ||
63 | + } | ||
64 | + | ||
65 | + } | ||
66 | + | ||
67 | + for (auto &BB : RetBlocks) { | ||
68 | + Constant* retBlockAddress = BlockAddress::get(BB); | ||
69 | + | ||
70 | + BasicBlock* decrypt_start = BasicBlock::Create(mod->getContext(), "dec_start", &F, BB); | ||
71 | + for (BasicBlock* preds : predecessors(BB)) { | ||
72 | + preds->getTerminator()->eraseFromParent(); | ||
73 | + BranchInst::Create(decrypt_start, preds); | ||
74 | + } | ||
75 | + | ||
76 | + | ||
77 | + std::vector<Value*> ptr_to_retarray_indices; | ||
78 | + ptr_to_retarray_indices.push_back(const_int_0); | ||
79 | + ptr_to_retarray_indices.push_back(const_int_0); | ||
80 | + GetElementPtrInst* ptr_to_retarray = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_to_retarray_indices, "arrayidx", decrypt_start); | ||
81 | + ptr_to_retarray->setIsInBounds(true); | ||
82 | + StoreInst* store_to_ret_ptr = new StoreInst(ptr_to_retarray, ret_array_ptr, false, decrypt_start); | ||
83 | + | ||
84 | + store_to_ret_ptr->setAlignment(MaybeAlign(4)); | ||
85 | + | ||
86 | + StoreInst* void_17 = new StoreInst(retBlockAddress, ptr_this_ret, false, decrypt_start); | ||
87 | + | ||
88 | + ptr_this_ret->setAlignment(MaybeAlign(4)); | ||
89 | + ret_array_ptr->setAlignment(MaybeAlign(4)); | ||
90 | + ptr_i->setAlignment(MaybeAlign(4)); | ||
91 | + void_17->setAlignment(MaybeAlign(4)); | ||
92 | + | ||
93 | + | ||
94 | + | ||
95 | + StoreInst* store_i_0 = new StoreInst(const_int_0, ptr_i, false, decrypt_start); | ||
96 | + store_i_0->setAlignment(MaybeAlign(4)); | ||
97 | + | ||
98 | + | ||
99 | + | ||
100 | + BasicBlock* decrypt_cond = BasicBlock::Create(mod->getContext(), "dec_cond", &F, BB); | ||
101 | + | ||
102 | + BranchInst::Create(decrypt_cond, decrypt_start); | ||
103 | + | ||
104 | + LoadInst* ldr_i_data = new LoadInst(ptr_i, "", false, decrypt_cond); | ||
105 | + ldr_i_data->setAlignment(MaybeAlign(4)); | ||
106 | + ICmpInst* cmp_i_with_20 = new ICmpInst(*decrypt_cond, ICmpInst::ICMP_SLT, ldr_i_data, const_int_20, "cmp"); | ||
107 | + | ||
108 | + BasicBlock* decrypt_ing = BasicBlock::Create(mod->getContext(), "dec_ing", &F, BB); | ||
109 | + BasicBlock* decrypt_add = BasicBlock::Create(mod->getContext(), "dec_add", &F, BB); | ||
110 | + BasicBlock* decrypt_end = BasicBlock::Create(mod->getContext(), "dec_end", &F, BB); | ||
111 | + BranchInst::Create(decrypt_ing, decrypt_end, cmp_i_with_20, decrypt_cond); | ||
112 | + | ||
113 | + LoadInst* ldr_i_data_2 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
114 | + ldr_i_data_2->setAlignment(MaybeAlign(4)); | ||
115 | + LoadInst* ldr_ptr_this_ret = new LoadInst(ptr_this_ret, "", false, decrypt_ing); | ||
116 | + ldr_ptr_this_ret->setAlignment(MaybeAlign(4)); | ||
117 | + 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); | ||
118 | + get_func_ptr_idx->setIsInBounds(true); | ||
119 | + LoadInst* ldr_func_ptr_idx = new LoadInst(get_func_ptr_idx, "", false, decrypt_ing); | ||
120 | + ldr_func_ptr_idx->setAlignment(MaybeAlign(1)); | ||
121 | + | ||
122 | + LoadInst* ldr_i_data_3 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
123 | + ldr_i_data_3->setAlignment(MaybeAlign(4)); | ||
124 | + | ||
125 | + std::vector<Value*> ptr_retn_array_indices; | ||
126 | + ptr_retn_array_indices.push_back(const_int_0); | ||
127 | + ptr_retn_array_indices.push_back(ldr_i_data_3); | ||
128 | + GetElementPtrInst* get_retn_array_data_idx = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_retn_array_indices, "arrayidx2", decrypt_ing); | ||
129 | + get_retn_array_data_idx->setIsInBounds(true); | ||
130 | + StoreInst* str_retn_array_data_idx = new StoreInst(ldr_func_ptr_idx, get_retn_array_data_idx, false, decrypt_ing); | ||
131 | + str_retn_array_data_idx->setAlignment(MaybeAlign(1)); | ||
132 | + | ||
133 | + LoadInst* ldr_i_data_4 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
134 | + ldr_i_data_4->setAlignment(MaybeAlign(4)); | ||
135 | + | ||
136 | + std::vector<Value*> ptr_retn_array_indices2; | ||
137 | + ptr_retn_array_indices2.push_back(const_int_0); | ||
138 | + ptr_retn_array_indices2.push_back(ldr_i_data_4); | ||
139 | + GetElementPtrInst* get_retn_array_data_idx2 = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_retn_array_indices2, "arrayidx3", decrypt_ing); | ||
140 | + get_retn_array_data_idx2->setIsInBounds(true); | ||
141 | + LoadInst* ldr_retn_array_data_idx2 = new LoadInst(get_retn_array_data_idx2, "", false, decrypt_ing); | ||
142 | + ldr_retn_array_data_idx2->setAlignment(MaybeAlign(1)); | ||
143 | + | ||
144 | + CastInst* cast_retn_array_data_idx2 = new ZExtInst(ldr_retn_array_data_idx2, IntegerType::get(mod->getContext(), 32), "conv", decrypt_ing); | ||
145 | + BinaryOperator* xor_retn_array_data_idx2 = BinaryOperator::Create(Instruction::Xor, cast_retn_array_data_idx2, const_int32_133, "xor", decrypt_ing); | ||
146 | + | ||
147 | + CastInst* trun_retn_array_data_idx2 = new TruncInst(xor_retn_array_data_idx2, IntegerType::get(mod->getContext(), 8), "conv4", decrypt_ing); | ||
148 | + | ||
149 | + | ||
150 | + LoadInst* ldr_i_data_5 = new LoadInst(ptr_i, "", false, decrypt_ing); | ||
151 | + ldr_i_data_5->setAlignment(MaybeAlign(4)); | ||
152 | + | ||
153 | + std::vector<Value*> ptr_retn_array_indices4; | ||
154 | + ptr_retn_array_indices4.push_back(const_int_0); | ||
155 | + ptr_retn_array_indices4.push_back(ldr_i_data_5); | ||
156 | + GetElementPtrInst* get_retn_array_data_idx4 = GetElementPtrInst::Create(return_array, ptr_ret_array, ptr_retn_array_indices4, "arrayidx5", decrypt_ing); | ||
157 | + get_retn_array_data_idx4->setIsInBounds(true); | ||
158 | + StoreInst* str_retn_array_data_idx4 = new StoreInst(trun_retn_array_data_idx2, get_retn_array_data_idx4, false, decrypt_ing); | ||
159 | + str_retn_array_data_idx4->setAlignment(MaybeAlign(1)); | ||
160 | + | ||
161 | + | ||
162 | + BranchInst::Create(decrypt_add, decrypt_ing); | ||
163 | + | ||
164 | + LoadInst* ldr_i_data_6 = new LoadInst(ptr_i, "", false, decrypt_add); | ||
165 | + ldr_i_data_6->setAlignment(MaybeAlign(4)); | ||
166 | + BinaryOperator* add_i_data_4 = BinaryOperator::Create(Instruction::Add, ldr_i_data_6, const_int_1, "", decrypt_add); | ||
167 | + StoreInst* str_i_data_4 = new StoreInst(add_i_data_4, ptr_i, false, decrypt_add); | ||
168 | + str_i_data_4->setAlignment(MaybeAlign(4)); | ||
169 | + BranchInst::Create(decrypt_cond, decrypt_add); | ||
170 | + | ||
171 | + LoadInst* ldr_ret_array = new LoadInst(ret_array_ptr, "", false, decrypt_end); | ||
172 | + ldr_ret_array->setAlignment(MaybeAlign(4)); | ||
173 | + | ||
174 | + BasicBlock* dec_jmp = BasicBlock::Create(mod->getContext(), "dec_jmp", &F, BB); | ||
175 | + BranchInst::Create(dec_jmp, decrypt_end); | ||
176 | + | ||
177 | + PHINode* ptr_40 = PHINode::Create(ret_func_ptr, 1, "", dec_jmp); | ||
178 | + ptr_40->addIncoming(ldr_ret_array, decrypt_end); | ||
179 | + IndirectBrInst *void_41 = IndirectBrInst::Create(ldr_ret_array, 1, dec_jmp); | ||
180 | + void_41->addDestination(BB); | ||
181 | + errs().write_escaped(F.getName()) << " " << F.getParent()->getName() << '\n'; | ||
182 | + } | ||
183 | + return true; | ||
184 | + } | ||
185 | + | ||
186 | + }; // end of struct Hello | ||
187 | +} // end of anonymous namespace | ||
188 | + | ||
189 | +char ReturnObfuscation::ID = 0; | ||
190 | + | ||
191 | +static RegisterPass<ReturnObfuscation> X("rof", "Hello World Pass", | ||
192 | + false /* Only looks at CFG */, | ||
193 | + false /* Analysis Pass */); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment