Skip to content

Commit

Permalink
ollvm support llvm 18.1.8
Browse files Browse the repository at this point in the history
  • Loading branch information
CYRUS-STUDIO committed Dec 11, 2024
1 parent 4806ce0 commit 98e0b5c
Show file tree
Hide file tree
Showing 27 changed files with 6,019 additions and 0 deletions.
13 changes: 13 additions & 0 deletions llvm/lib/Passes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,19 @@ add_llvm_component_library(LLVMPasses
PassPlugin.cpp
StandardInstrumentations.cpp

Obfuscation/Utils.cpp
Obfuscation/CryptoUtils.cpp
Obfuscation/ObfuscationOptions.cpp
Obfuscation/BogusControlFlow.cpp
Obfuscation/IPObfuscationContext.cpp
Obfuscation/Flattening.cpp
Obfuscation/StringEncryption.cpp
Obfuscation/SplitBasicBlock.cpp
Obfuscation/Substitution.cpp
Obfuscation/IndirectBranch.cpp
Obfuscation/IndirectCall.cpp
Obfuscation/IndirectGlobalVariable.cpp

ADDITIONAL_HEADER_DIRS
${LLVM_MAIN_INCLUDE_DIR}/llvm
${LLVM_MAIN_INCLUDE_DIR}/llvm/Passes
Expand Down
682 changes: 682 additions & 0 deletions llvm/lib/Passes/Obfuscation/BogusControlFlow.cpp

Large diffs are not rendered by default.

50 changes: 50 additions & 0 deletions llvm/lib/Passes/Obfuscation/BogusControlFlow.h
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
1,254 changes: 1,254 additions & 0 deletions llvm/lib/Passes/Obfuscation/CryptoUtils.cpp

Large diffs are not rendered by default.

147 changes: 147 additions & 0 deletions llvm/lib/Passes/Obfuscation/CryptoUtils.h
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
130 changes: 130 additions & 0 deletions llvm/lib/Passes/Obfuscation/Flattening.cpp
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);
}
30 changes: 30 additions & 0 deletions llvm/lib/Passes/Obfuscation/Flattening.h
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
Loading

0 comments on commit 98e0b5c

Please sign in to comment.