-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
4806ce0
commit 98e0b5c
Showing
27 changed files
with
6,019 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
#ifndef _BOGUSCONTROLFLOW_H_ | ||
#define _BOGUSCONTROLFLOW_H_ | ||
// LLVM libs | ||
#include "llvm/Pass.h" | ||
#include "llvm/IR/Module.h" | ||
#include "llvm/IR/Function.h" | ||
#include "llvm/IR/BasicBlock.h" | ||
#include "llvm/IR/Instructions.h" | ||
#include "llvm/IR/InstrTypes.h" | ||
#include "llvm/IR/Constants.h" | ||
#include "llvm/IR/Type.h" | ||
#include "llvm/ADT/Statistic.h" | ||
#include "llvm/IR/GlobalValue.h" | ||
#include "llvm/IR/LLVMContext.h" | ||
#include "llvm/Transforms/Utils/Cloning.h" | ||
#include "llvm/Transforms/Utils/BasicBlockUtils.h" | ||
#include "llvm/CodeGen/ISDOpcodes.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
#include "llvm/Support/Debug.h" | ||
#include "llvm/Support/CommandLine.h" | ||
#include "llvm/Transforms/IPO.h" | ||
#include "llvm/IR/IRBuilder.h" | ||
#include "llvm/IR/NoFolder.h" | ||
#include "llvm/Support/TargetSelect.h" | ||
#include "llvm/Transforms/Utils/Local.h" | ||
// System libs | ||
#include <list> | ||
#include <memory> | ||
// User libs | ||
#include "CryptoUtils.h" | ||
#include "Utils.h" | ||
using namespace std; | ||
using namespace llvm; | ||
namespace llvm{ // 基本块分割 | ||
class BogusControlFlowPass : public PassInfoMixin<BogusControlFlowPass>{ | ||
public: | ||
bool flag; | ||
BogusControlFlowPass(bool flag){ | ||
this->flag = flag; | ||
} // 携带flag的构造函数 | ||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); // Pass实现函数 | ||
void bogus(Function &F); | ||
void addBogusFlow(BasicBlock *basicBlock, Function &F); | ||
bool doF(Module &M, Function &F); | ||
static bool isRequired() { return true; } // 直接返回true即可 | ||
}; | ||
BogusControlFlowPass *createBogusControlFlow(bool flag); // 创建基本块分割 | ||
} | ||
|
||
#endif |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
//===- CryptoUtils.h - Cryptographically Secure Pseudo-Random Generator ---===// | ||
// | ||
// The LLVM Compiler Infrastructure | ||
// | ||
// This file is distributed under the University of Illinois Open Source | ||
// License. See LICENSE.TXT for details. | ||
// | ||
//===----------------------------------------------------------------------===// | ||
// | ||
// This file contains includes and defines for the AES CTR PRNG | ||
// The AES implementation has been derived and adapted | ||
// from libtomcrypt (see http://libtom.org) | ||
// Created on: 22 juin 2012 | ||
// Author(s): jrinaldini, pjunod | ||
//===----------------------------------------------------------------------===// | ||
#ifndef _OBFUSCATION_CRYPTUTILS_H | ||
#define _OBFUSCATION_CRYPTUTILS_H | ||
|
||
#include "llvm/Support/ManagedStatic.h" | ||
|
||
#include <cstdint> | ||
#include <cstdio> | ||
#include <string> | ||
|
||
namespace llvm { | ||
|
||
class CryptoUtils; | ||
extern ManagedStatic<CryptoUtils> cryptoutils; | ||
|
||
#define BYTE(x, n) (((x) >> (8 * (n))) & 0xFF) | ||
|
||
#if defined(__i386) || defined(__i386__) || defined(_M_IX86) || \ | ||
defined(INTEL_CC) || defined(_WIN64) || defined(_WIN32) | ||
|
||
#ifndef ENDIAN_LITTLE | ||
#define ENDIAN_LITTLE | ||
#endif | ||
#define ENDIAN_32BITWORD | ||
|
||
#if !defined(_WIN64) || !defined(_WIN32) | ||
#ifndef UNALIGNED | ||
#define UNALIGNED | ||
#endif | ||
#endif | ||
|
||
#elif defined(__alpha) | ||
|
||
#ifndef ENDIAN_LITTLE | ||
#define ENDIAN_LITTLE | ||
#endif | ||
#define ENDIAN_64BITWORD | ||
|
||
#elif defined(__x86_64__) | ||
|
||
#ifndef ENDIAN_LITTLE | ||
#define ENDIAN_LITTLE | ||
#endif | ||
#define ENDIAN_64BITWORD | ||
#define UNALIGNED | ||
|
||
#elif (defined(__R5900) || defined(R5900) || defined(__R5900__)) && \ | ||
(defined(_mips) || defined(__mips__) || defined(mips)) | ||
|
||
#ifndef ENDIAN_LITTLE | ||
#define ENDIAN_LITTLE | ||
#endif | ||
#define ENDIAN_64BITWORD | ||
|
||
#elif defined(__sparc) || defined(__aarch64__) | ||
|
||
#ifndef ENDIAN_BIG | ||
#define ENDIAN_BIG | ||
#endif | ||
#if defined(__arch64__) || defined(__aarch64__) | ||
#define ENDIAN_64BITWORD | ||
#else | ||
#define ENDIAN_32BITWORD | ||
#endif | ||
|
||
#endif | ||
|
||
#if defined(__BIG_ENDIAN__) || defined(_BIG_ENDIAN) | ||
#define ENDIAN_BIG | ||
#endif | ||
|
||
#if !defined(ENDIAN_BIG) && !defined(ENDIAN_LITTLE) | ||
#error \ | ||
"Unknown endianness of the compilation platform, check this header aes_encrypt.h" | ||
#endif | ||
|
||
#define CryptoUtils_POOL_SIZE (0x1 << 17) // 2^17 | ||
|
||
class CryptoUtils { | ||
public: | ||
CryptoUtils(); | ||
~CryptoUtils(); | ||
|
||
char *get_seed(); | ||
void get_bytes(char *buffer, const int len); | ||
char get_char(); | ||
bool prng_seed(std::string const &seed); | ||
|
||
// Returns a uniformly distributed 8-bit value | ||
uint8_t get_uint8_t(); | ||
// Returns a uniformly distributed 16-bit value | ||
uint16_t get_uint16_t(); | ||
// Returns a uniformly distributed 32-bit value | ||
uint32_t get_uint32_t(); | ||
// Returns an integer uniformly distributed on [0, max[ | ||
uint32_t get_range(const uint32_t max); | ||
// Returns a uniformly distributed 64-bit value | ||
uint64_t get_uint64_t(); | ||
|
||
// Scramble a 32-bit value depending on a 128-bit value | ||
unsigned scramble32(const unsigned in, const char key[16]); | ||
|
||
int sha256(const char *msg, unsigned char *hash); | ||
|
||
private: | ||
uint32_t ks[44]; | ||
char key[16]; | ||
char ctr[16]; | ||
char pool[CryptoUtils_POOL_SIZE]; | ||
uint32_t idx; | ||
std::string seed; | ||
bool seeded; | ||
|
||
typedef struct { | ||
uint64_t length; | ||
uint32_t state[8], curlen; | ||
unsigned char buf[64]; | ||
} sha256_state; | ||
|
||
void aes_compute_ks(uint32_t *ks, const char *k); | ||
void aes_encrypt(char *out, const char *in, const uint32_t *ks); | ||
bool prng_seed(); | ||
void inc_ctr(); | ||
void populate_pool(); | ||
int sha256_done(sha256_state *md, unsigned char *out); | ||
int sha256_init(sha256_state *md); | ||
static int sha256_compress(sha256_state *md, unsigned char *buf); | ||
int sha256_process(sha256_state *md, const unsigned char *in, | ||
unsigned long inlen); | ||
}; | ||
} // namespace llvm | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
#include "Utils.h" | ||
#include "CryptoUtils.h" | ||
#include "Flattening.h" | ||
#include "SplitBasicBlock.h" | ||
//#include "llvm/Transforms/Utils/LowerSwitch.h" | ||
// namespace | ||
using namespace llvm; | ||
using std::vector; | ||
|
||
#define DEBUG_TYPE "flattening" // 调试标识 | ||
// Stats | ||
STATISTIC(Flattened, "Functions flattened"); | ||
|
||
PreservedAnalyses FlatteningPass::run(Function& F, FunctionAnalysisManager& AM) { | ||
Function *tmp = &F; // 传入的Function | ||
// 判断是否需要开启控制流平坦化 | ||
if (toObfuscate(flag, tmp, "fla")) { | ||
INIT_CONTEXT(F); | ||
// outs()<<"[Soule] debug. "<< F.getName()<<" \n"; | ||
if (flatten(*tmp)) { | ||
++Flattened; | ||
} | ||
return PreservedAnalyses::none(); | ||
} | ||
return PreservedAnalyses::all(); | ||
} | ||
|
||
|
||
bool FlatteningPass::flatten(Function &F) { | ||
// 基本块数量不超过1则无需平坦化 | ||
if(F.size() <= 1){ | ||
//outs() << "\033[0;33mFunction size is lower then one\033[0m\n"; // warning | ||
return false; | ||
} | ||
// emmmm....... | ||
if (F.getName().str().find("$basic_ostream") != std::string::npos) { | ||
outs() << "[obf] force_nofla: " << F.getName().str().c_str() << "\n"; | ||
return false; | ||
} | ||
// 将除入口块(第一个基本块)以外的基本块保存到一个 vector 容器中,便于后续处理 | ||
// 首先保存所有基本块 | ||
vector<BasicBlock*> origBB; | ||
for(BasicBlock &BB: F){ | ||
origBB.push_back(&BB); | ||
} | ||
// 从vector中去除第一个基本块 | ||
origBB.erase(origBB.begin()); | ||
BasicBlock &entryBB = F.getEntryBlock(); | ||
// 如果第一个基本块的末尾是条件跳转,单独分离 | ||
bool bEntryBB_isConditional = false; | ||
if(BranchInst *br = dyn_cast<BranchInst>(entryBB.getTerminator())){ | ||
if(br->isConditional()){ | ||
BasicBlock *newBB = entryBB.splitBasicBlock(br, "newBB"); | ||
origBB.insert(origBB.begin(), newBB); | ||
bEntryBB_isConditional = true; | ||
} | ||
} | ||
|
||
// 创建分发块和返回块 | ||
BasicBlock *dispatchBB = BasicBlock::Create(*CONTEXT, "dispatchBB", &F, &entryBB); | ||
BasicBlock *returnBB = BasicBlock::Create(*CONTEXT, "returnBB", &F, &entryBB); | ||
BranchInst::Create(dispatchBB, returnBB); | ||
entryBB.moveBefore(dispatchBB); | ||
// 去除第一个基本块末尾的跳转 | ||
if (bEntryBB_isConditional) { | ||
entryBB.getTerminator()->eraseFromParent(); | ||
} | ||
// 使第一个基本块跳转到dispatchBB | ||
BranchInst *brDispatchBB = BranchInst::Create(dispatchBB, &entryBB); | ||
|
||
// 在入口块插入alloca和store指令创建并初始化switch变量,初始值为随机值 | ||
int randNumCase = rand(); | ||
AllocaInst *swVarPtr = new AllocaInst(TYPE_I32, 0, "swVar.ptr", brDispatchBB); | ||
new StoreInst(CONST_I32(randNumCase), swVarPtr, brDispatchBB); | ||
// 在分发块插入load指令读取switch变量 | ||
LoadInst *swVar = new LoadInst(TYPE_I32, swVarPtr, "swVar", false, dispatchBB); | ||
// 在分发块插入switch指令实现基本块的调度 | ||
BasicBlock *swDefault = BasicBlock::Create(*CONTEXT, "swDefault", &F, returnBB); | ||
BranchInst::Create(returnBB, swDefault); | ||
SwitchInst *swInst = SwitchInst::Create(swVar, swDefault, 0, dispatchBB); | ||
// 将原基本块插入到返回块之前,并分配case值 | ||
for(BasicBlock *BB : origBB){ | ||
BB->moveBefore(returnBB); | ||
swInst->addCase(CONST_I32(randNumCase), BB); | ||
randNumCase = rand(); | ||
} | ||
|
||
// 在每个基本块最后添加修改switch变量的指令和跳转到返回块的指令 | ||
for(BasicBlock *BB : origBB){ | ||
// retn BB | ||
if(BB->getTerminator()->getNumSuccessors() == 0){ | ||
continue; | ||
} | ||
// 非条件跳转 | ||
else if(BB->getTerminator()->getNumSuccessors() == 1){ | ||
BasicBlock *sucBB = BB->getTerminator()->getSuccessor(0); | ||
if (bEntryBB_isConditional) { | ||
entryBB.getTerminator()->eraseFromParent(); | ||
} | ||
ConstantInt *numCase = swInst->findCaseDest(sucBB); | ||
new StoreInst(numCase, swVarPtr, BB); | ||
BranchInst::Create(returnBB, BB); | ||
} | ||
// 条件跳转 | ||
else if(BB->getTerminator()->getNumSuccessors() == 2){ | ||
// BranchInst *br = cast<BranchInst>(BB->getTerminator()); | ||
BranchInst *br = dyn_cast<BranchInst>(BB->getTerminator()); | ||
if (!br) { | ||
//outs() << "[FAILED] dyn_cast<BranchInst>(BB->getTerminator()); " << BB->getName() << "\n"; | ||
continue; | ||
} | ||
if (!br->isConditional()) { | ||
//outs() << "[FAILED] br->isConditional(); " << BB->getName() << "\n"; | ||
continue; | ||
} | ||
ConstantInt *numCaseTrue = swInst->findCaseDest(BB->getTerminator()->getSuccessor(0)); | ||
ConstantInt *numCaseFalse = swInst->findCaseDest(BB->getTerminator()->getSuccessor(1)); | ||
SelectInst *sel = SelectInst::Create(br->getCondition(), numCaseTrue, numCaseFalse, "", BB->getTerminator()); | ||
BB->getTerminator()->eraseFromParent(); | ||
new StoreInst(sel, swVarPtr, BB); | ||
BranchInst::Create(returnBB, BB); | ||
} | ||
} | ||
fixStack(F); // 修复逃逸变量和PHI指令 | ||
return true; | ||
} | ||
|
||
FlatteningPass *llvm::createFlattening(bool flag) { | ||
return new FlatteningPass(flag); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
#ifndef LLVM_FLATTENING_H | ||
#define LLVM_FLATTENING_H | ||
// LLVM libs | ||
#include "llvm/Pass.h" | ||
#include "llvm/IR/Function.h" | ||
#include "llvm/IR/Instructions.h" | ||
#include "llvm/Transforms/Utils.h" | ||
#include "llvm/Support/CommandLine.h" | ||
#include "llvm/Support/raw_ostream.h" | ||
#include "llvm/IR/LegacyPassManager.h" | ||
#include "llvm/Transforms/Utils/Local.h" | ||
//#include "llvm/Transforms/IPO/PassManagerBuilder.h" | ||
// System libs | ||
#include <vector> | ||
#include <cstdlib> | ||
#include <ctime> | ||
namespace llvm{ | ||
class FlatteningPass : public PassInfoMixin<FlatteningPass>{ | ||
public: | ||
bool flag; | ||
FlatteningPass(bool flag){ | ||
this->flag = flag; | ||
} // 携带flag的构造函数 | ||
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM); | ||
bool flatten(Function &F); | ||
static bool isRequired() { return true; } | ||
}; | ||
FlatteningPass *createFlattening(bool flag); | ||
} | ||
#endif // LLVM_FLATTENING_H |
Oops, something went wrong.