SO文件保护与OLLVM混淆逆向

1. ELF文件保护技术解析

1.1 SO文件加固方案

主流保护技术矩阵

技术类型 实现方式 对抗难点
符号混淆 strip删除符号表 + 自定义哈希命名 函数边界识别
代码段加密 基于TEE的.init_array解密 内存Dump时机捕捉
控制流混淆 OLLVM平坦化 + 虚假跳转 CFG重建
动态加载 dlopen分段加载核心逻辑 运行时行为捕获
1.1.1 加密段特征识别
readelf -S libtarget.so | grep encrypted  
  [16] .encrypted         PROGBITS        0001a000 01a000 02000 00  WA  0   0 16  

动态解密Hook点定位

Interceptor.attach(Module.findExportByName(null, "mprotect"), {  
    onEnter: function(args) {  
        if (args[2] === 7) { // RWX权限  
            console.log("解密触发地址:", args[0]);  
        }  
    }  
});  

2. OLLVM混淆深度剖析

2.1 控制流平坦化结构

原始控制流

graph TD  
    A[入口] --> B[条件1]  
    B -->|真| C[逻辑块1]  
    B -->|假| D[逻辑块2]  
    C --> E[出口]  
    D --> E  

平坦化后结构

graph TD  
    A[入口] --> S[状态分发器]  
    S -->|状态0| B[垃圾块]  
    S -->|状态1| C[真实逻辑块]  
    S -->|状态2| D[垃圾块]  
    C --> S  

2.2 虚假分支注入模式

ARM64混淆代码特征

_start:  
    MOV X19, #0x1234    ; 状态寄存器初始化  
    ADRP X8, #jumptable@PAGE  
    ADD X8, X8, #jumptable@PAGEOFF  
loop:  
    LDR X9, [X8, X19, LSL #3]  ; 加载跳转地址  
    BR X9  
jumptable:  
    .quad 0x0000A000  ; 垃圾块  
    .quad 0x0000B000  ; 真实逻辑  
    .quad 0x0000C000  ; 垃圾块  

3. 反混淆工具链构建

3.1 符号恢复技术

基于特征码的函数识别

def find_encrypt_func(so_path):  
    patterns = {  
        "AES_init": b"\x20\x47\x0F\xB5\xA0\xB1",  
        "RSA_generate": b"\x80\xB5\x2D\xE9\x00\xAF"  
    }  
    with open(so_path, 'rb') as f:  
        data = f.read()  
        for name, sig in patterns.items():  
            offset = data.find(sig)  
            if offset != -1:  
                rebase_symbol(offset, name)  

3.2 控制流重建方案

Angr符号执行反混淆

proj = angr.Project('obfuscated.so', auto_load_libs=False)  
cfg = proj.analyses.CFGFast()  

for func in cfg.functions:  
    if is_flattened(func):  
        simgr = proj.factory.simgr(proj.factory.full_init_state())  
        simgr.explore(find=func.end)  
        if simgr.found:  
            rebuild_cfg(func, simgr.found[0].history)  

4. 动态分析技术突破

4.1 内存完整度校验绕过

Hook校验函数

const verify_ptr = Module.findExportByName("libtarget.so", "verify_integrity");  
Interceptor.attach(verify_ptr, {  
    onEnter: function(args) {  
        this.expected = args[1].readPointer();  
    },  
    onLeave: function(retval) {  
        retval.replace(this.expected); // 强制返回预期值  
    }  
});  

4.2 实时指令追踪

Unicorn引擎动态模拟

from unicorn import Uc, UC_ARCH_ARM64, UC_MODE_ARM  

def trace_block(uc, address, size, user_data):  
    code = uc.mem_read(address, size)  
    print(f"执行地址: {hex(address)} 指令: {code.hex()}")  

mu = Uc(UC_ARCH_ARM64, UC_MODE_ARM)  
mu.mem_map(0x1000, 0x1000)  
mu.mem_write(0x1000, code)  
mu.hook_add(UC_HOOK_BLOCK, trace_block)  
mu.emu_start(0x1000, 0x1000 + len(code))  

5. 企业级混淆对抗案例

5.1 某IoT设备固件逆向

挑战

  • 三重控制流平坦化

  • 基于TEE的代码段加密

  • 运行时自修改代码(SMC)

解决方案

  1. 动态代码捕获

qemu-arm -g 1234 -L ./ rootfs/bin/main # 启动GDB调试  
python3 -m libheap -p 1234 dump -b 0xbeef0000 -s 0x1000  
  1. SMC处理策略

def handle_smc(uc, address, size, user_data):  
    code = uc.mem_read(address, size)  
    decrypted = tea_decrypt(code, key)  
    uc.mem_write(address, decrypted)  

5.2 金融安全芯片逆向

技术路线

  1. JTAG调试接口激活

openocd -f interface/ftdi/jtagkey2.cfg -f target/stm32f4x.cfg  
  1. 混淆指令级跟踪

mov r0, #0          ; 虚假指令  
b real_code         ; 混淆跳转  
.byte 0xDE,0xAD     ; 垃圾数据  
real_code:  
    push {lr}       ; 真实逻辑开始  

反混淆脚本

def clean_asm(code):  
    patterns = [  
        (b"\x00\x20", b"\x00\xBF"),  // nop替换虚假指令  
        (b"\xDE\xAD", b"\x00\x00")   // 清除垃圾数据  
    ]  
    for pat, rep in patterns:  
        code = code.replace(pat, rep)  
    return code  

6. 防护技术演进趋势

6.1 量子计算混淆

量子门操作混淆原理

void quantum_obfuscate(uint32_t* data) {  
    __asm__ __volatile__ (  
        "QOBS %0, %1, #0x3F"  
        : "=r" (*data)  
        : "r" (*data)  
    );  
}  

逆向突破口

  • 量子模拟器(QEMU扩展)

  • 门操作模式识别

6.2 神经符号混淆

AI生成的不可逆混淆

from transformers import GPT2LMHeadModel, GPT2Tokenizer  

model = GPT2LMHeadModel.from_pretrained("obfuscator-2.0")  
tokenizer = GPT2Tokenizer.from_pretrained("obfuscator-2.0")  

code = "int main() { return 0; }"  
inputs = tokenizer.encode(code, return_tensors="pt")  
obf_output = model.generate(inputs, max_length=200)  
print(tokenizer.decode(obf_output[0]))  

对抗策略

  • 基于attention权重的模式恢复

  • 对抗训练去混淆模型


技术验证清单

  • 完成OLLVM平坦化控制流重建

  • 实现SMC代码动态解密

  • 开发量子混淆模拟环境

  • 构建神经混淆对抗模型

  • 复现企业级芯片逆向案例

本章实验需在授权硬件设备上进行,推荐使用STLink/V2调试器配合开源固件。涉及量子计算内容需遵循国家密码管理局相关规定。

关于作者:

15年互联网开发、带过10-20人的团队,多次帮助公司从0到1完成项目开发,在TX等大厂都工作过。当下为退役状态,写此篇文章属个人爱好。本人开发期间收集了很多开发课程等资料,需要可联系我