基于FART的脱壳技术与DEX修复

1. FART脱壳原理与框架设计

1.1 FART工作机制解析

脱壳流程

graph TD  
    A[目标APP启动] --> B[类加载器监控]  
    B --> C{检测到DEX加载}  
    C -->|是| D[触发内存Dump]  
    D --> E[捕获DEX/ODEX字节流]  
    E --> F[重组与修复文件头]  
    F --> G[生成可分析的DEX]  

核心技术点

  • 动态监控:Hook DexFileClassLoader的加载过程

  • 内存捕获:在defineClassloadClass时Dump内存

  • 主动唤醒:通过反射调用触发加壳代码解密


2. 环境配置与工具链搭建

2.1 设备与系统要求

组件 推荐配置 备注
Android版本 Android 7.0-11 ART运行时兼容性最佳
设备 Google Pixel系列 易解锁Bootloader,支持Treble兼容
FART版本 FART 3.2 支持多DEX和动态加载
Python环境 Python 3.8+ 用于脚本处理Dump数据

2.2 FART刷入与配置

Magisk模块安装

# 通过TWRP刷入  
adb push fart.zip /sdcard/  
adb shell twrp install /sdcard/fart.zip  

# 或通过Magisk安装  
1. 下载FART模块ZIP  
2. Magisk → 模块 → 从存储安装  
3. 重启设备  

环境验证脚本

import subprocess  

def check_fart():  
    result = subprocess.run(['adb', 'shell', 'ls /system/bin/fart'], capture_output=True)  
    return "No such file" not in result.stderr.decode()  
print("FART环境就绪" if check_fart() else "安装失败")  

3. 主动脱壳技术实战

3.1 基础脱壳流程

步骤详解

  1. 启动目标应用

    adb shell am start -n com.target.app/.MainActivity  
  2. 触发类加载

    # 通过Broadcast唤醒解密逻辑  
    adb shell am broadcast -a com.target.app.INIT_DECRYPT  
  3. 执行内存Dump

    adb shell fart -p com.target.app -o /sdcard/dump.dex  
  4. 导出DEX文件

    adb pull /sdcard/dump.dex .  

3.2 多DEX处理策略

分段Dump脚本

import os  

for i in range(5):  # 假设应用分5个DEX加载  
    os.system(f'adb shell fart -p com.target.app -n {i} -o /sdcard/dex_{i}.dex')  
    os.system(f'adb pull /sdcard/dex_{i}.dex')  

4. DEX修复与重组技术

4.1 文件头修复工具

RebuildDex工具链

# 修复魔数与校验和  
python3 rebuild_dex.py --input broken.dex --output fixed.dex \  
    --magic "dex\n035" --checksum auto  

关键修复参数

  • --magic:指定正确的DEX魔数(如dex\n035

  • --checksum:自动计算Adler32校验和

  • --offset:调整文件段偏移(针对篡改头部的壳)

4.2 索引表重建算法

字符串池修复代码

def fix_string_ids(dex_bytes):  
    header = dex_bytes[:0x70]  
    string_ids_size = int.from_bytes(header[0x38:0x3C], 'little')  
    string_ids_off = int.from_bytes(header[0x3C:0x40], 'little')  

    # 遍历字符串池  
    for i in range(string_ids_size):  
        offset = string_ids_off + i * 4  
        str_offset = int.from_bytes(dex_bytes[offset:offset+4], 'little')  
        str_data = read_uleb128(dex_bytes[str_offset:])  
        if not validate_utf8(str_data):  
            rebuild_string_table()  

5. 企业级脱壳实战案例

5.1 某金融APP脱壳分析

挑战

  • 时间戳校验:DEX加载后10秒自毁

  • 动态解密:仅核心类在运行时解密

解决方案

  1. 精准时序控制

    # 启动后立即触发脱壳  
    adb shell "am start -n com.bank.app/.MainActivity && sleep 3 && fart -p com.bank.app"  
  2. 关键类Hook

    Java.perform(() => {  
        const ActivityThread = Java.use('android.app.ActivityThread');  
        ActivityThread.performLaunchActivity.overload().implementation = function() {  
            const result = this.performLaunchActivity();  
            sendBroadcast("DUMP_NOW");  // 触发Dump  
            return result;  
        };  
    });  

Dump Unity3D代码逻辑

  1. 定位il2cpp入口

    frida -U -f com.game.app -l dump_il2cpp.js  
  2. 脚本示例

    const il2cpp_base = Module.findBaseAddress('libil2cpp.so');  
    const metadata = Memory.readByteArray(il2cpp_base, 0x100000);  
  3. 重组DLL

    using Il2CppDumper;  
    var config = new Config {  
        DumpMethod = DumpMethod.Auto,  
        GenerateScript = false  
    };  
    Il2CppDumper.Il2CppDumper.PerformDump("libil2cpp.so", "global-metadata.dat", config);  


6. 反脱壳对抗技术

6.1 内存陷阱检测

反Hook机制

void check_memory_integrity() {  
    uint8_t* code_start = (uint8_t*)&check_memory_integrity;  
    uint32_t crc = calculate_crc(code_start, 0x1000);  
    if (crc != EXPECTED_CRC) {  
        exit(0);  
    }  
}  

绕过方案

Interceptor.attach(Module.findExportByName(null, "memcmp"), {  
    onEnter: function(args) {  
        const expected = Memory.readCString(args[1]);  
        if (expected.includes("dex")) {  
            args[1].writeUtf8String("");  // 清空预期值  
        }  
    }  
});  

6.2 动态代码加密

运行时解密策略

_start:  
    LDR R0, =encrypted_code  
    MOV R1, #0x1000  
    BL  decrypt          @ 解密代码  
    BX  R0              @ 跳转到解密后的代码  
decrypt:  
    @ AES-CBC解密实现  
    ...  

内存捕获时机

# 监控解密后的内存区域  
frida -U -p PID --runtime=v8 -l dump_on_decrypt.js  

7. 自动化脱壳框架

7.1 FART增强版功能

新增特性

  • 多进程支持:同时监控多个APP进程

  • 增量Dump:仅捕获新增类加载

  • 云同步:自动上传DEX到分析平台

配置示例

<!-- fart_config.xml -->  
<config>  
    <target package="com.target.app"/>  
    <mode incremental="true"/>  
    <output dir="/sdcard/fart_dumps"/>  
    <triggers>  
        <trigger class="com.target.app.MainActivity"/>  
    </triggers>  
</config>  

7.2 集群化脱壳系统

架构设计

graph TD  
    A[控制中心] --> B[任务队列]  
    B --> C[脱壳节点1]  
    B --> D[脱壳节点2]  
    C --> E[存储集群]  
    D --> E  
    E --> F[分析引擎]  

技术验证清单

  • 成功通过FART脱壳获取完整DEX

  • 修复被篡改的DEX文件头

  • 绕过内存CRC校验机制

  • 实现Unity3D代码重组

  • 构建自动化脱壳集群

本章实验需在已授权的测试设备进行,推荐使用开源应用(如F-Droid项目)作为分析对象。所有脱壳行为需遵守《网络安全法》与《数据安全法》相关规定。

关于作者:

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

猜你喜欢

转载自blog.csdn.net/u012263104/article/details/146501204
今日推荐