mdsecactivebreach/functionpeekaboo
GitHub: mdsecactivebreach/functionpeekaboo
基于 LLVM 后端 pass 的代码混淆工具,通过在编译阶段修改函数序言尾声并注入自定义入口点,实现二进制级别的反逆向保护。
Stars: 60 | Forks: 2
# Function Peakaboo
## 构建说明
### LLVM backend pass 注册
- pass 的逻辑在 X86RetModPass.cpp 中实现。
- 将 X86RetModPass.h 包含到 ***llvm-project/llvm/lib/Target/X86/X86TargetMachine.cpp*** 中。
- 在 X86TargetMachine.cpp 中,有一个函数 - ***void X86PassConfig::addPreEmitPass()***,在该函数末尾添加以下代码。
// LLVM 将在 PreEmit 阶段运行我们的 pass
addPass(new X86RetModPass());
- 现在我们已经成功注册了自定义的 backend pass。
### 修改 LLVM 内部实现
- 这里我们将修改 LLVM 的汇编打印组件(X86AsmPrinter 类)。
- 我们将在 ***X86AsmPrinter*** 类定义中添加一个新的私有成员 ***EpilogueStubSymbol***。
llvm-project/llvm/lib/Target/X86/X86AsmPrinter.h
- 添加新的类成员后,我们需要修改下面提到的两个 ***X86AsmPrinter*** 类方法:
- ***void X86AsmPrinter::emitFunctionBodyStart()***
- ***void X86AsmPrinter::emitFunctionBodyEnd()***
- 你可以在下面提到的文件中找到 ***X86AsmPrinter*** 类的实现。
llvm-project/llvm/lib/Target/X86/X86AsmPrinter.cpp
- 只需用本仓库中提供的 ***X86AsmPrinter.cpp*** 中的代码替换 ***emitFunctionBodyStart()*** 和 ***emitFunctionBodyEnd()*** 中的内容即可。不要忘记在 ***X86AsmPrinter.h*** 中添加 ***EpilogueStubSymbol***
### 构建 LLVM(使用 CCACHE)并测试可执行文件
- 现在我们已经准备好从头构建 LLVM,并将我们的修改内置其中。
- 确保在安装的其他依赖项中也安装了 ***CCACHE***。
```
--------------------------------------------------------------------------------------------------------------
Configure CCACHE (optional)
--------------------------------------------------------------------------------------------------------------
ccache --max-size=10G
--------------------------------------------------------------------------------------------------------------
llvm building
--------------------------------------------------------------------------------------------------------------
git clone https://github.com/llvm/llvm-project.git
cmake -G Ninja ../llvm-project/llvm -DLLVM_ENABLE_PROJECTS="clang;lld" -DCMAKE_BUILD_TYPE=Release -DLLVM_TARGETS_TO_BUILD="X86" -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_INSTALL_PREFIX=../llvm-install -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache
ninja install
--------------------------------------------------------------------------------------------------------------
Compile and linking test sample test.cpp
--------------------------------------------------------------------------------------------------------------
llvm-install/bin/clang++ -static -static-libstdc++ -static-libgcc -target x86_64-w64-windows-gnu -fuse-ld=lld -O0 test.cpp -o out.exe -Wl,--strip-all -Wl,--gc-sections -v
--------------------------------------------------------------------------------------------------------------
Inject custom entrypoint stub
--------------------------------------------------------------------------------------------------------------
python3 modifyEP.py out.exe final.exe
```
## 注意事项
- LLVM 的向后兼容性非常差,因此未来的 LLVM 更新可能(也可能不会)导致编译失败。
## 测试
- 在注入自定义 entry point stub 之前,不要尝试运行该二进制文件,因为这会导致崩溃。
- 测试代码 test.cpp 的内容如下所示。
// test.cpp
#include
#include
#include
struct MyStruct
{
void* func;
uint32_t len;
};
// Place xor key here, POC uses single byte keys. eg 0x00000008
__attribute__((section(".funcmeta")))
uint32_t myfuncsec_key = 0x12345678;
// Macro to register a function
#define REGISTER_FUNCTION(fn) \
__attribute__((section(".funcmeta"))) \
struct MyStruct fn##_entry = { (void*)fn, 0xDEADBEEF };
void REG_foo2()
{
std::cout << "\nhello from foo2";
}
int REG_foo(int a, int b, int c, int d, int e)
{
int i = 0;
int x = a + b + c + d + e;
std::cout << "\n" << x;
MessageBoxA(NULL, "Hello from foo", "Test", MB_OK);
if (i)
{
return 0;
}
else{
i++;
}
return x;
}
//Register your functions here
REGISTER_FUNCTION(REG_foo)
REGISTER_FUNCTION(REG_foo2)
int main()
{
bool p = VirtualProtect(0,0,0,0);
std::cout << "MAIN here";
int a = REG_foo(1,2,3,4,5);
std::cout << "\n Ret val :" << a;
REG_foo2();
return 0;
}
标签:Bash脚本, LLVM, X86架构, 代码混淆, 后端开发, 汇编, 编译器, 逆向工具