首页
社区
课程
招聘
[原创]Android IOS 双端支持的 Trace 开源咯
发表于: 2026-3-19 12:44 13980

[原创]Android IOS 双端支持的 Trace 开源咯

2026-3-19 12:44
13980

Github: 776K9s2c8@1M7s2y4Q4x3@1q4Q4x3V1k6Q4x3V1k6Y4K9i4c8Z5N6h3u0Q4x3X3g2U0L8$3#2Q4x3V1k6D9K9h3c8G2L8X3N6&6L8$3!0G2i4K6u0r3c8%4g2E0g2s2u0S2j5$3f1`.

基于 Frida Gum (Stalker) 引擎的 ARM64 真机动态指令追踪工具,支持 Android 和 iOS 平台。

GumTrace 以共享库的形式注入目标进程,对指定模块进行指令级别的动态追踪,并将完整的执行轨迹写入日志文件。

项目附带一个独立的离线污点分析工具(src/taint/),可对 GumTrace 生成的日志进行正向/反向数据流追踪:

每行指令记录的格式如下:

示例:

GumTrace 编译为共享库,导出以下 C 接口:

初始化追踪器。

启动追踪。会创建一个后台线程定期刷写日志文件。

停止追踪,刷写并关闭日志文件。

通过 Frida 脚本加载 GumTrace 共享库并调用其导出接口,即可对目标进程进行指令追踪。完整示例见 example.js。

注意: 如果 SO 加载失败(dlopen 返回 NULL),通常是 SELinux 阻止了从 /data/local/tmp/ 加载共享库。需要先关闭 SELinux:

项目提供了 010 Editor 脚本 TaintTracker.1sc,可以在 010 Editor 中直接对 trace 日志进行交互式污点分析。

安装:

使用:

GumTrace 内置了对常见库函数参数的自动解析:

参数 类型 说明
module_names const char* 要追踪的模块名,多个用逗号分隔(如 "libtarget.so,libutils.so")
trace_file_path char* 日志输出文件路径
thread_id int 要追踪的线程 ID(0 表示追踪当前线程)
options GUM_OPTIONS 选项位掩码,1 启用 DEBUG 模式(高频刷写日志)
类别 函数
字符串操作 strlen, strcmp, strncmp, strcpy, strcat, strstr, strdup 等
内存操作 memcpy, memmove, memset, memcmp, memmem 等
文件操作 open, openat, read, write, fopen, close 等
内存分配 malloc, calloc, realloc, free
内存映射 mmap, mprotect
动态链接 dlopen, dlsym, dlclose
格式化 sprintf, snprintf, sscanf
系统 syscall, __system_property_get, sysconf
JNI (Android) FindClass, GetMethodID, CallObjectMethod, GetStringUTFChars 等全部 JNI 函数
ObjC (iOS) objc_msgSend, objc_retain, objc_release, NSClassFromString 等
[模块名] 0x绝对地址!0x相对偏移 助记符 操作数; 寄存器名=值 mem_r=地址 mem_w=地址
[libtarget.so] 0x7a3c001890!0x1890 ldr x0, [x1, #0x10]; x1=0x7a3c050000 mem_r=0x7a3c050010
-> x0=0x12345678
call func: strcmp(0x7a3c050010, 0x7a3c060000)
args0: hello
args1: world
ret: 0xffffffffffffffff
# 编辑 build_android.sh 中的 ANDROID_NDK_HOME 路径
./build_android.sh
# 产物: build_android/libGumTrace.so
./build_ios.sh
# 产物: build_ios/libGumTrace.dylib
cd src/taint
mkdir -p build && cd build
cmake ..
cmake --build .
# 产物: taint_tracker
adb push build_android/libGumTrace.so /data/local/tmp/
adb shell setenforce 0
let traceSoName = 'libGumTrace.so'
let targetSo = 'libtarget.so'

let gumtrace_init = null
let gumtrace_run = null
let gumtrace_unrun = null

// 加载 GumTrace 共享库并获取函数指针
function loadGumTrace() {
    let dlopen = new NativeFunction(Module.findGlobalExportByName('dlopen'), 'pointer', ['pointer', 'int'])
    let dlsym = new NativeFunction(Module.findGlobalExportByName('dlsym'), 'pointer', ['pointer', 'pointer'])

    let soHandle = dlopen(Memory.allocUtf8String('/data/local/tmp/' + traceSoName), 2)

    gumtrace_init = new NativeFunction(
        dlsym(soHandle, Memory.allocUtf8String('init')),
        'void', ['pointer', 'pointer', 'int', 'int'])
    gumtrace_run = new NativeFunction(
        dlsym(soHandle, Memory.allocUtf8String('run')),
        'void', [])
    gumtrace_unrun = new NativeFunction(
        dlsym(soHandle, Memory.allocUtf8String('unrun')),
        'void', [])
}

// 初始化并启动追踪
function startTrace() {
    loadGumTrace()
    let moduleNames = Memory.allocUtf8String(targetSo)
    let outputPath = Memory.allocUtf8String('/data/data/com.example.app/trace.log')
    let threadId = 0   // 0 = 当前线程
    let options = 0    // 1 = DEBUG 模式
    gumtrace_init(moduleNames, outputPath, threadId, options)
    gumtrace_run()
}

// 停止追踪
function stopTrace() {
    gumtrace_unrun()
}

// hook 目标函数,在其执行期间进行追踪
let targetModule = Process.findModuleByName(targetSo)
Interceptor.attach(targetModule.base.add(0x1234), {
    onEnter() {
        startTrace()
        this.tracing = true
    },
    onLeave() {
        if (this.tracing) stopTrace()
    }
})
frida -U -f com.example.app -l hook.js
adb pull /data/data/com.example.app/trace.log .
# 正向追踪:从第 100 行的 x0 寄存器开始追踪数据流向
./taint_tracker -i trace.log -o result.log -f x0 -l 100

# 反向追踪:从第 500 行的 x0 寄存器反向追溯数据来源
./taint_tracker -i trace.log -o result.log -b x0 -l 500

# 追踪内存地址
./taint_tracker -i trace.log -o result.log -f mem:0x1000 -l 100

# 按相对地址定位起始位置
./taint_tracker -i trace.log -o result.log -f x0 -a 0x1890

# 按字节偏移定位起始位置
./taint_tracker -i trace.log -o result.log -b x0 -p 1048576
GumTrace/
├── CMakeLists.txt              # 主构建脚本
├── build_android.sh            # Android 构建脚本
├── build_ios.sh                # iOS 构建脚本
├── example.js                  # Frida 使用示例脚本
├── libs/                       # Frida Gum 静态库和头文件
│   ├── FridaGum-Android-17.6.2.h
│   └── FridaGum-IOS-17.6.2.h
└── src/
    ├── main.cpp                # 入口,导出 init/run/unrun 接口
    ├── GumTrace.h/cpp          # 核心追踪引擎(Stalker 回调、指令解析、日志写入)
    ├── CallbackContext.h/cpp   # 指令上下文对象池
    ├── FuncPrinter.h/cpp       # 函数调用参数/返回值打印(含 JNI 和 ObjC)
    ├── Utils.h/cpp             # 工具函数(寄存器值读取、hexdump、字符串格式化)
    ├── platform.h              # 平台检测宏
    └── taint/                  # 离线污点分析工具
        ├── CMakeLists.txt
        ├── main.cpp            # 命令行入口
        ├── TraceParser.h/cpp   # 日志解析器(零分配设计)
        ├── TaintEngine.h/cpp   # 污点传播引擎(正向/反向)
        └── TaintTracker.1sc    # 010 Editor 污点分析脚本

注意: 如果 SO 加载失败(dlopen 返回 NULL),通常是 SELinux 阻止了从 /data/local/tmp/ 加载共享库。需要先关闭 SELinux:

adb shell setenforce 0
参数 类型 说明
module_names const char* 要追踪的模块名,多个用逗号分隔(如 "libtarget.so,libutils.so")
trace_file_path char* 日志输出文件路径
thread_id int 要追踪的线程 ID(0 表示追踪当前线程)
options GUM_OPTIONS 选项位掩码,1 启用 DEBUG 模式(高频刷写日志)
类别 函数
字符串操作 strlen, strcmp, strncmp, strcpy, strcat, strstr, strdup 等
内存操作 memcpy, memmove, memset, memcmp, memmem 等
文件操作 open, openat, read, write, fopen, close 等
内存分配 malloc, calloc, realloc, free
内存映射 mmap, mprotect
动态链接 dlopen, dlsym, dlclose
格式化 sprintf, snprintf, sscanf
系统 syscall, __system_property_get, sysconf
JNI (Android) FindClass, GetMethodID, CallObjectMethod, GetStringUTFChars 等全部 JNI 函数
ObjC (iOS) objc_msgSend, objc_retain, objc_release, NSClassFromString 等
  • Trace UI - 本项目官方指定的 trace 分析工具。高性能 ARM64 执行 trace 可视化分析工具。基于 Tauri 2 + React 构建的桌面应用,专为安全研究员设计,支持千万行或亿行级大规模 trace 的流畅浏览、函数调用树折叠、反向污点追踪、内存/寄存器实时查看等功能。Trace Ul 与 GumTrace 深度适配,是在分析 trace 日志时的得力助手。感谢 @imj01y 的开源贡献!
  • 指令级追踪 — 逐条记录 ARM64 指令的执行,包括模块名、绝对地址、相对偏移、助记符和操作数
  • 寄存器快照 — 记录每条指令执行时的寄存器读写值(通用寄存器 x0-x28、SIMD 寄存器 q/d/s/h/b、SP、FP、LR、NZCV)
  • 内存访问追踪 — 记录内存读写的目标地址(mem_r / mem_w),支持基址 + 索引 + 偏移的复合寻址计算
  • 函数调用拦截 — 自动识别 BL/BLR/BR/B 指令的跳转目标,匹配已知符号后打印函数参数和返回值
  • 系统调用追踪 — 拦截 SVC 指令,根据系统调用号解析函数名(覆盖 Linux aarch64 全部系统调用)
  • Android JNI 追踪 — 自动识别 JNI 函数调用,解析 jclass、jmethodID、jstring 等 JNI 对象
  • iOS ObjC 追踪 — 拦截 objc_msgSend,解析类名、selector,打印 NSDictionary/NSArray/NSString/NSData/NSNumber 等 ObjC 对象

传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!!

最后于 2026-3-19 12:48 被lidongyooo编辑 ,原因:
收藏
点赞 ・213
打赏
分享
最新回复 (139)
雪    币: 6
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2 楼
感谢分享
2026-3-19 13:29
0
雪    币: 4
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3 楼
666
2026-3-19 13:32
0
雪    币: 8
活跃值: (6158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4 楼
感谢大佬,trace的格式和unidbgyi一样吗?
2026-3-19 14:39
0
雪    币: 1901
活跃值: (6053)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
5 楼
老铁666
2026-3-19 15:46
0
雪    币: 1142
活跃值: (1295)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6 楼
学习学习
2026-3-19 15:55
0
雪    币: 9441
活跃值: (6363)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7 楼
666
2026-3-19 16:53
0
雪    币: 341
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
8 楼
666
2026-3-19 16:55
0
雪    币: 4824
活跃值: (8332)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9 楼
感谢分享
2026-3-19 17:06
0
雪    币: 390
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10 楼
看看看看
2026-3-19 17:11
0
雪    币: 7784
活跃值: (25320)
能力值: ( LV12,RANK:550 )
在线值:
发帖
回帖
粉丝
11 楼
看看
2026-3-19 17:39
0
雪    币: 8
活跃值: (6158)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12 楼
有点问题啊,trace后的log用trace ui打开提示:文件格式不正确,未检测到有效的arm64 trace指令行
2026-3-19 20:44
0
雪    币: 2020
活跃值: (4736)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13 楼
6666
2026-3-19 21:28
0
雪    币: 200
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
14 楼
tql
2026-3-19 21:42
0
雪    币: 4
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
15 楼
666
2026-3-19 21:54
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
16 楼
111
2026-3-19 22:04
0
雪    币: 1894
活跃值: (3098)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17 楼
666
2026-3-20 09:27
0
雪    币: 110
活跃值: (9656)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18 楼
tql
2026-3-20 09:27
0
雪    币: 1736
活跃值: (2005)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19 楼
666666
2026-3-20 11:41
0
雪    币: 1303
活跃值: (1413)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20 楼
老铁666
2026-3-20 11:53
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
21 楼
666
2026-3-20 14:16
0
雪    币: 17
活跃值: (1816)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22 楼
老铁666
2026-3-20 14:26
0
雪    币: 292
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
23 楼
6666666666
2026-3-20 15:57
0
雪    币: 131
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
24 楼
感谢分享
2026-3-20 16:02
0
雪    币: 0
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
25 楼
1
2026-3-20 18:02
0
游客
登录 | 注册 方可回帖
返回