0x00 写在前面
本文记录了一次完整的 Hunter 设备指纹与 Hook 检测逆向实践。为避免分析发散,我先把目标拆成三个可验证问题,并围绕它们逐步推进:
- Hunter 具体采集了哪些设备信号与环境特征?
- 这些采集到的信号如何映射到页面展示的指纹字段中?
- 其风险判定逻辑是单点触发,还是多信号融合决策?
0x01 研究对象与初始现象

通过对指纹页面的初步分析,可以看到三个核心区域:
- DeviceBaseInfo(设备基础信息)
- JavaDeviceFingerprint(Java 层设备指纹)
- NativeDeviceFingerprint(Native 层设备指纹)
- 其中 NativeDeviceFingerprint 区域呈现出特征性内容:
oaid_xxx:开放设备标识符(OAID),用于替代 IMEI 的非敏感设备标识ifaa_error_Bind service failed:IFAA(互联网金融身份认证联盟)服务绑定失败,是一个错误日志soter_xxx:腾讯 Soter 安全组件生成的密钥标识- 后面的
a_/b_/c_/e_/f_开头字符串:是 Native 层采集的各类硬件 / 系统特征值,用于生成更稳定的设备指纹
0x02 动态分析迭代路线
0x02.1 第一阶段:定位核心采集入口
根据上面页面字段先做了一轮关键词反推(如 ro.secure、ro.debuggable、ifaa、soter、biometric),可以先确定两类最可能的入口,再进入后续 Hook:
android.os.SystemProperties.get用来验证基础系统属性的读取来源。页面里的构建标签、安全状态、调试开关这类信息,通常都会经过这里。android.app.ContextImpl.getSystemService用来验证系统能力探测入口。像 IFAA、生物识别、指纹、Keyguard 这类能力查询,常见都会从这个 API 往下走。
这样做的目的,是先把“谁在采集什么”这条主线跑通,再决定下一步补 bindService、业务方法还是 JNI 路线,避免一开始就大面积 Hook 导致噪音失控。
点击展开:完整代码(v1)
|
|
这段代码的价值很明确:
- 先做观测,不篡改返回值。
- 先建立“调用来源地图”,再谈下一步。
阶段结果(实测):
- 启动期稳定观测到属性读取(如
ro.miui.notch)。 - 观测到
biometric、keyguard等系统能力查询。 - 首个业务栈帧可回溯到
MainActivity.onCreate,验证入口归因可用。
日志说明:下面这组日志证明了 v1 入口观察已生效,且能看到属性读取与系统能力查询。
点击展开:日志输出
[+] hook SystemProperties.get(String) [+] hook SystemProperties.get(String,String) [+] hook ContextImpl.getSystemService(String) [*] hookhunter v1 installed [HIT] SystemProperties.get(String,String) | key=ro.miui.notch | ret=1 | frame=at com.zhenxi.hunter.MainActivity.onCreate(Unknown Source:203) [HIT_EARLY] Context.getSystemService | key=biometric | ret=android.hardware.biometrics.BiometricManager@245b6fa | frame=
[HIT_EARLY] Context.getSystemService | key=keyguard | ret=android.app.KeyguardManager@bc6e0d6 | frame=
0x02.2 第二阶段:验证 IFAA/Soter 服务绑定链路
新增重点:ContextWrapper.bindService(Intent, ServiceConnection, int)
点击展开:完整代码(v1.2)
|
|
- 关键结论:日志可稳定复现以下结果,且与页面字段高度一致:
- IFAA 服务绑定返回
false→ 对应页面ifaa_error_Bind service failed; - Soter 服务绑定返回
true→ 对应页面soter_xxx标识存在。
- IFAA 服务绑定返回
日志说明:下面这组日志直接坐实了 IFAA 失败、Soter 成功两条分支。
点击展开:日志输出
[+] hook SystemProperties.get(String) [+] hook SystemProperties.get(String,String) [+] hook ContextImpl.getSystemService(String) [+] hook ContextWrapper.bindService(Intent,ServiceConnection,int) [+] hook android.util.Log e/w/i [*] hookhunter v1.2 installed [HIT] SystemProperties.get(String,String) | key=ro.miui.notch | ret=1 | frame=at com.zhenxi.hunter.MainActivity.onCreate(Unknown Source:203) [HIT] ContextWrapper.bindService | key=action=org.ifaa.aidl.manager.IfaaManagerService, pkg=org.ifaa.aidl.manager, comp=null, flags=1 | ret=false | frame=at com.zhenxi.hunter.MainActivity.v(SourceFile:0) [HIT] ContextWrapper.bindService | key=action=null, pkg=null, comp=ComponentInfo{com.tencent.soter.soterserver/com.tencent.soter.soterserver.SoterService}, flags=1 | ret=true | frame=at com.zhenxi.hunter.MainActivity.v(SourceFile:0) [HIT_EARLY] Context.getSystemService | key=biometric | ret=android.hardware.biometrics.BiometricManager@4f78087 | frame=
[HIT_EARLY] Context.getSystemService | key=keyguard | ret=android.app.KeyguardManager@bbc2ee5 | frame=
0x02.3 第三阶段:一次失败的全局热点 Hook
尝试:全局 Hook 高频基础类方法 StringBuilder.toString + ArrayList.add,试图捕获聚合指纹生成过程
点击展开:完整代码(v1.3,失败样本)
|
|
执行结果
- 日志噪音极高,有效信息被海量无效调用淹没;
- 触发应用进程异常中止。
核心经验:
- 高频基础类方法不适合作为全局主路径 Hook 目标;
- 逆向分析应回归“业务方法 + 关键 API”,避免无差别全局 Hook。
日志说明:下面这组日志说明全局热点 Hook 的噪音和性能问题都很严重。
点击展开:日志输出
[+] hook StringBuilder/StringBuffer.toString [+] hook ArrayList.add(Object) [*] hookhunter v1.3 installed [HIT_EARLY] StringBuilder.toString | key=builder | ret=google/rpc/error_details.proto | frame=
Process terminated
0x02.4 第四阶段:回到可控策略
调整:
- 移除高频基础类的全局 Hook;
- 聚焦
MainActivity的核心方法(v/onCreate)。
点击展开:完整代码(v1.3_safe)
|
|
关键发现:
MainActivity.v显示为 Native Method,说明 Hunter 关键逻辑下沉到 JNI/Native 层。
日志说明:下面这组日志把 MainActivity.v 的 Native Method 属性直接打了出来。
点击展开:日志输出
[+] hook MainActivity.v overloads=1 [+] hook MainActivity.onCreate overloads=1 [HIT] ContextWrapper.bindService | key=action=org.ifaa.aidl.manager.IfaaManagerService, pkg=org.ifaa.aidl.manager, comp=null, flags=1 | ret=false | frame=at com.zhenxi.hunter.MainActivity.v(SourceFile:0) [HIT] ContextWrapper.bindService | key=action=null, pkg=null, comp=ComponentInfo{com.tencent.soter.soterserver/com.tencent.soter.soterserver.SoterService}, flags=1 | ret=true | frame=at com.zhenxi.hunter.MainActivity.v(SourceFile:0) [HIT] MainActivity.v | key=a0=
| ret= | frame=at com.zhenxi.hunter.MainActivity.v(Native Method) [HIT] MainActivity.v | key=a0=[object Object] | ret= | frame=at com.zhenxi.hunter.MainActivity.v(Native Method)
0x02.5 第五阶段:动态注册 JNI 路线验证
尝试 Hook RegisterNatives 和 CheckJNI 相关方法,验证动态注册 JNI 路线
点击展开:完整代码(v1.4c)
|
|
执行现象:Hook 可成功安装,但有效命中次数极少。
日志说明:下面这组日志证明 Hook 安装成功,但没有有效 RegisterNatives 命中。
点击展开:日志输出
[+] hook _ZN3art12_GLOBAL__N_18CheckJNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi @ 0x… [+] hook _ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi @ 0x… [*] v1.4c installed, hooked symbols=2 Spawned
com.zhenxi.hunter. Resuming main thread!
关键推断:Hunter 的核心 JNI 逻辑并非以动态注册为主,更可能采用静态 JNI 导出方式。
0x02.6 第六阶段:静态 JNI 路线突破
在 dlopen/android_dlopen_ext 命中目标 so 后,定向扫描导出。
点击展开:完整代码(v1.5_safe)
|
|
关键发现:定位到核心 JNI 入口符号
Java_com_zhenxi_hunter_NativeEngine_getZhenxiInfoMethodCodeJava_com_zhenxi_hunter_NativeEngine_getZhenxiInfoReleaseNative
核心意义:将 JNI 入口从“猜测”转化为“可精准定位的符号”,为后续 Native 层分析奠定基础。
日志说明:下面这组日志是静态 JNI 路线的关键突破证据。
点击展开:日志输出
[dlopen-hit] android_dlopen_ext => …/lib/arm64/libhunter.so [JNI_STATIC_EXPORT] libhunter.so :: Java_com_zhenxi_hunter_NativeEngine_getZhenxiInfoMethodCode @ 0x780ebd1e24 [+] attach static JNI => Java_com_zhenxi_hunter_NativeEngine_getZhenxiInfoMethodCode @ 0x780ebd1e24 (libhunter.so) [JNI_STATIC_EXPORT] libhunter.so :: Java_com_zhenxi_hunter_NativeEngine_getZhenxiInfoReleaseNative @ 0x780ebd1d5c [+] attach static JNI => Java_com_zhenxi_hunter_NativeEngine_getZhenxiInfoReleaseNative @ 0x780ebd1d5c (libhunter.so) [*] module scan done: libhunter.so, hits=2
0x02.7 第七阶段:NativeEngine 全量映射
批量 Hook NativeEngine.getZhenxiInfo* 系列方法,建立 “方法 - 返回值” 映射关系
点击展开:完整代码(v1.6)
|
|
方法调用频次统计:
getZhenxiInfoH高达 21 次getZhenxiInfoZ高达 13 次getZhenxiInfoK6 次
结论:设备属性读取与环境风险探测是 Hunter 的核心主干流量。
日志说明:下面这组日志说明 v1.6 已成功进入 NativeEngine 全量方法映射阶段。
点击展开:日志输出
[-] libhunter.so not loaded yet, skip native attach in this phase [+] hook dlopen @ 0x78ff6f2014 [+] hook android_dlopen_ext @ 0x78ff6f20ac [*] hookhunter v1.6 nativeengine focus installed [+] hook NativeEngine.getZhenxiInfo1 overloads=1 [+] hook NativeEngine.getZhenxiInfo3 overloads=1 [+] hook NativeEngine.getZhenxiInfo4 overloads=1 [+] hook NativeEngine.getZhenxiInfoF overloads=1 [JAVA_NE] getZhenxiInfo1() => a_NSw6KjQ+MS,b_NTA5MUM8RT,c_29048414,e_ehwrEnRaXE,f_MzowNTQxMj
0x02.8 第八阶段:核心方法精准追踪
聚焦 9 个核心方法:
getZhenxiInfo1getZhenxiInfo3getZhenxiInfo4getZhenxiInfoFgetZhenxiInfoHgetZhenxiInfoZgetZhenxiInfoKgetZhenxiInfoOFLIgetZhenxiInfoLLLI
并对超长返回做摘要处理,解决日志爆炸问题。
阶段结果(实测):
getZhenxiInfo1输出a_/b_/c_/e_/f_聚合串。getZhenxiInfo3命中zygisk/su/magisk痕迹。getZhenxiInfo4命中sh进程。getZhenxiInfoF命中 Hook/完整性风险。
点击展开:完整代码(v1.7)
|
|
日志说明:下面这组日志体现了最终高价值方法追踪的核心命中结果。
点击展开:日志输出
[V1.7] getZhenxiInfoH(a0=ro.build.display.id) => QKQ1.190828.002 test-keys | costMs=11 [V1.7] getZhenxiInfo3() => {title=Check Find Root File risk=[com.zhenxi.hunter:hunter_main_process, /system/lib64/libzygisk.so, /sbin/su, /sbin/.magisk]} | costMs=3 [V1.7] getZhenxiInfo1() => a_NSw6KjQ+MS,b_NTA5MUM8RT,c_29048414,e_ehwrEnRaXE,f_MzowNTQxMj | costMs=86 [V1.7] getZhenxiInfoF() => {title=检测到libart.so被修改 risk=[检测当前程序被Hook,当前手机存在hook框架]} | costMs=674
0x03 核心证据(节选)
0x03.1 最终脚本实跑结果
最终版本脚本采用“中文结构化输出”,每次命中都会直接打印方法用途、参数、返回值、耗时和提炼后的关键点。
点击展开:最终脚本完整代码(较长)
|
|
点击展开:完整实跑终端输出(较长)
(venv38) PS E:\code\vscode\venv38> frida -U -f com.zhenxi.hunter -l D:\Desktop\练手\hunter\hookhunter_final.js
/ _ | Frida 17.3.2 - A world-class dynamic instrumentation toolkit | (| | > _ | Commands: // || help -> Displays the help system . . . . object? -> Display information about ‘object’ . . . . exit/quit -> Exit . . . . . . . . More info at https://frida.re/docs/home/ . . . . . . . . Connected to MI 8 (id=6ca0abb6) Spawned
com.zhenxi.hunter. Resuming main thread! [MI 8::com.zhenxi.hunter ]-> ========== Hunter 最终学习脚本启动 ========== 目标类: com.zhenxi.hunter.NativeEngine 策略: 高价值方法追踪 + 中文结构化输出 + 只观测不篡改 已安装 Hook -> getZhenxiInfo1,重载数=1,用途=设备指纹聚合(a/b_/c_/e_/f_) 已安装 Hook -> getZhenxiInfo3,重载数=1,用途=Root 文件/路径风险检测 已安装 Hook -> getZhenxiInfo4,重载数=1,用途=可疑进程检测 已安装 Hook -> getZhenxiInfoF,重载数=1,用途=Hook/完整性检测(libart) 已安装 Hook -> getZhenxiInfoH,重载数=1,用途=系统属性主通道 已安装 Hook -> getZhenxiInfoK,重载数=1,用途=容器环境检测(docker/lxc) 已安装 Hook -> getZhenxiInfoLLLI,重载数=1,用途=加载库枚举 已安装 Hook -> getZhenxiInfoOFLI,重载数=1,用途=文件描述符枚举 已安装 Hook -> getZhenxiInfoZ,重载数=1,用途=系统属性补充通道 已安装 Hook -> ContextWrapper.bindService(轻量观测) ========== Hook 安装完成,等待目标方法触发 ==========【核心命中】getZhenxiInfoH(系统属性主通道) 参数: a0=ro.build.display.id 返回: QKQ1.190828.002 test-keys 耗时: 11 ms 关键点: 属性读取:ro.build.display.id = QKQ1.190828.002 test-keys
【服务绑定】bindService 观测 action=org.ifaa.aidl.manager.IfaaManagerService pkg=org.ifaa.aidl.manager comp=
flags=1, ret=false 【服务绑定】bindService 观测 action=
pkg= comp=ComponentInfo{com.tencent.soter.soterserver/com.tencent.soter.soterserver.SoterService} flags=1, ret=true 【核心命中】getZhenxiInfo3(Root 文件/路径风险检测) 参数: <无参数> 返回: {title=Check Find Root File risk=[com.zhenxi.hunter:hunter_main_process, /system/lib64/libzygisk.so, /sbin/su, /sbin/.magisk] com.zhenxi.hunter:hunter_main_process /system/lib64/libzygisk.so /sbin/su /sbin/.magisk }
耗时: 44 ms 关键点: 命中 zygisk 相关路径 关键点: 命中 su 路径 关键点: 命中 magisk 痕迹
【核心命中】getZhenxiInfo1(设备指纹聚合(a_/b_/c_/e_/f_)) 参数: <无参数> 返回: a_NSw6KjQ+MS,b_NTA5MUM8RT,c_29048414,e_ehwrEnRaXE,f_MzowNTQxMj 耗时: 86 ms 关键点: 命中 a_/b_/c_/e_/f_ 聚合字段,疑似 Native 指纹核心输出
【核心命中】getZhenxiInfo4(可疑进程检测) 参数: a0=YouAreLoser.ug@c56afde 返回: {title=Find Others Processmay be risks main pid (7087) risk=[other pid -> 7427(pid name: ls), other pid -> 7432(pid name: sh)] other pid -> 7427(pid name: ls) other pid -> 7432(pid name: sh) }
耗时: 8 ms 关键点: 命中 sh 进程
【核心命中】getZhenxiInfoLLLI(加载库枚举) 参数: <无参数> 返回: [/system/bin/linker64, /system/bin/app_process64, [vdso], /system/lib64/libandroid_runtime.so, /system/lib64/libbase.so, /system/lib64/libbinder.so, /system/lib64/libcutils.so, /system/lib64/libhidlbase.so, /system/lib64/liblog.so, /apex/com.android.runtime/lib64/libnativeloader.so, /system/lib64/libutils.so, /system/l…<len=10999> 耗时: 2 ms 关键点: 返回 so/oat 列表,可用于识别注入/异常模块 关键点: 列表中出现 frida-agent 相关痕迹
【核心命中】getZhenxiInfoOFLI(文件描述符枚举) 参数: <无参数> 返回: [1//dev/null/character device/8630/1/0/0/0, 2//dev/null/character device/8630/1/0/0/0, 3/socket:[2096764]/socket/49663/1/10277/10277/0, 4//dev/pmsg0/, 5//sys/kernel/debug/tracing/trace_marker/, 6//dev/null/character device/8630/1/0/0/0, 7//dev/null/character device/8630/1/0/0/0, 8//dev/null/character device/8630/1/0/0/…<len=6268> 耗时: 9 ms 关键点: 返回 fd 列表,用于观察可疑句柄/映射关系 关键点: 路径 /proc/mounts 未命中容器关键词
【核心命中】getZhenxiInfoK(容器环境检测(docker/lxc)) 参数: a0=/proc/self/mountstats, a1=docker,lxc_volumns 返回:
耗时: 0 ms 关键点: 路径 /proc/self/mountstats 未命中容器关键词 【核心命中】getZhenxiInfoK(容器环境检测(docker/lxc)) 参数: a0=/proc/self/mountinfo, a1=docker,lxc_volumns 返回:
耗时: 364 ms 关键点: 路径 /proc/self/mountinfo 未命中容器关键词 【核心命中】getZhenxiInfoH(系统属性主通道) 参数: a0=ro.boot.verifiedbootstate 返回: green 耗时: 32 ms 关键点: 属性读取:ro.boot.verifiedbootstate = green [节选说明] 中间存在多轮
getZhenxiInfoH/Z对ro.build.display.id、ro.debuggable、ro.secure的重复轮询日志,这里不再全文贴出。【核心命中】getZhenxiInfoF(Hook/完整性检测(libart)) 参数: <无参数> 返回: {title=检测到libart.so被修改 risk=[检测当前程序被Hook,当前手机存在hook框架]} 耗时: 433 ms 关键点: 命中 libart 完整性风险
getZhenxiInfo1()
日志说明:该返回值用于证明 a_/b_/c_/e_/f_ 聚合字段已经被命中。
点击展开:日志输出
a_NSw6KjQ+MS,b_NTA5MUM8RT,c_29048414,e_ehwrEnRaXE,f_MzowNTQxMj
该返回与 NativeDeviceFingerprint 中的 a_/b_/c_/e_/f_ 聚合字段高度对应。
getZhenxiInfo3()
日志说明:该风险列表用于证明 root/hook 路径检测命中。
点击展开:日志输出
risk=[com.zhenxi.hunter:hunter_main_process, /system/lib64/libzygisk.so, /sbin/su, /sbin/.magisk]
说明 root/hook 相关痕迹可通过文件与路径信号直接采集。
getZhenxiInfo4(...)
日志说明:该输出用于证明存在进程维度的风险画像。
点击展开:日志输出
risk=[other pid -> … (pid name: sh/cat/grep/ls/logcat)…]
说明存在进程维度的实时风险画像能力。
getZhenxiInfoH/Z
日志说明:该组日志用于证明关键系统属性被持续读取并参与判断。
点击展开:日志输出
ro.build.display.id => QKQ1.190828.002 test-keys ro.boot.verifiedbootstate => green ro.debuggable => 0 ro.secure => 1
说明基础系统属性属于高频输入,且存在重复校验行为。
getZhenxiInfoK(...)
日志说明:该结果用于证明当前样本环境未触发容器特征命中。
点击展开:日志输出
/proc/mounts + docker,lxc_volumns =>
/proc/self/mountstats + docker,lxc_volumns => /proc/self/mountinfo + docker,lxc_volumns =>
该样本环境下容器特征未命中。
getZhenxiInfoF()
日志说明:该输出用于证明链路内置了完整性与 Hook 框架检测。
点击展开:日志输出
{title=检测到libart.so被修改 risk=[检测当前程序被Hook,当前手机存在hook框架]}
这是最关键的一条:采集链路内置完整性与 Hook 框架检测。
0x04 最终映射表(方法 -> 字段 -> 风险意义)
| 方法 | 主要输入 | 输出形态 | 对应字段/语义 | 风险意义 |
|---|---|---|---|---|
| getZhenxiInfo1 | 无 | a_/b_/c_/e_/f_ 聚合串 |
NativeDeviceFingerprint 关键聚合值 | 高 |
| getZhenxiInfo3 | 无 | root 风险列表 | root 文件/路径痕迹 | 高 |
| getZhenxiInfo4 | 进程上下文 | 进程风险列表 | 可疑进程态势 | 高 |
| getZhenxiInfoF | 无 | 完整性风险 map | libart/hook 框架检测 | 极高 |
| getZhenxiInfoH/Z | ro.* 属性键 | 属性值 | DeviceBaseInfo 与安全属性 | 中高 |
| getZhenxiInfoK | /proc/* + docker,lxc | null/命中项 | 容器环境检测 | 中 |
| getZhenxiInfoOFLI | 无 | fd 列表 | 打开文件/句柄画像 | 中 |
| getZhenxiInfoLLLI | 无 | so/oat 列表 | 运行时加载画像 | 中 |
0x05 关键结论(经日志支持)
- Hunter 并非单点 root 检测,而是多信号融合判断。
- 指纹采集与安全检测在同一链路并行执行,而非“先采集后检测”的串行模型。
- 仅隐藏单个信号(如
su)意义有限,进程、加载库、完整性校验仍会补充风险证据。 - 从工程实践看,“先宽后窄”的脚本迭代策略显著提升了定位效率与可解释性。
0x06 学习总结
1. 逆向分析方法论
本次 Hunter 设备指纹逆向遵循由浅入深、由 Java 到 Native、由观测到验证的主线:
- 初始阶段:通过页面特征反推关键 API,优先 Hook 系统级 API(
SystemProperties.get/Context.getSystemService)建立观测基线。 - 迭代阶段:逐步收敛 Hook 范围,从全局 Hook 转向业务方法(
MainActivity.v),再下钻到 JNI 层。 - 突破阶段:通过静态 JNI 导出符号扫描定位核心 Native 方法,最终还原指纹生成链路。
2. 关键技术点总结
| 阶段 | 核心技术 | 解决的问题 | 核心经验 |
|---|---|---|---|
| Java 层观测 | Frida Java API Hook | 定位数据采集入口 | 先观测不篡改,建立调用链路地图 |
| 系统服务探测 | bindService Hook/Logcat 监控 | 验证 IFAA/Soter 服务状态 | 结合日志上下文分析错误码含义 |
| JNI 层定位 | dlopen Hook + 导出符号扫描 | 找到 Native 层核心入口 | 静态 JNI 导出比动态注册更常见 |
| Native 层分析 | 指令级 Hook / 系统调用追踪 | 还原指纹生成算法 | 关注哈希函数、字符串拼接操作 |
| 对抗绕过 | Anti-Anti-Debug | 突破调试 / 检测限制 | 优先修复核心校验点而非全量绕过 |
3. 避坑指南
- 避免无差别全局 Hook:高频基础类(
StringBuilder/ArrayList)Hook 会产生海量噪音,甚至导致进程崩溃。 - JNI 层分析优先静态符号:动态注册 JNI 的检测成本更高,很多商业应用更偏向静态导出。
- 日志输出需做摘要:超长返回值(如完整指纹串)应截断,避免日志爆炸。
- 坚持分层分析:Java 层链路未理清前,不要急于深入 Native,避免方向失控。
4. Frida 逆向基础
- Java 层 Hook 核心 API:
Java.use():获取类的引用;overload():指定方法重载版本;implementation:替换方法实现;Java.perform():在 Java 虚拟机上下文执行代码。
- Native 层 Hook 核心 API:
Interceptor.attach():附加到函数地址;Module.findExportByName():查找导出符号;Thread.backtrace():获取调用栈;NativeCallback/NativeFunction:Native 函数封装。
5. Android 设备指纹核心维度
| 维度 | 采集内容 | 技术实现 |
|---|---|---|
| 基础硬件 | CPU / 内存 / 屏幕 / 传感器 | 读取/sys//proc文件、系统属性 |
| 系统信息 | 系统版本 / ROM / 安全补丁 | ro.build.*系列属性 |
| 唯一标识 | OAID/IMEI/ 序列号 | 系统服务调用(TelephonyManager) |
| 环境安全 | Root/Hook/ 调试状态 | 进程扫描、文件检测、指令校验 |
| 服务能力 | IFAA/Soter/ 生物识别 | bindService/getSystemService |
6. Native 层逆向关键技巧
- 符号命名规律:JNI 静态导出符号遵循
Java_包名_类名_方法名规则; - 指令特征:哈希计算(MD5/SHA)会出现固定的指令序列;
- 数据流转:通过
read/write系统调用追踪数据读取与输出; - 对抗检测:关注
ptrace/seccomp/mmap等系统调用的异常使用。