#!/usr/bin/env python3 """真机探针 v2: 抓 libhydeviceid.so 经 RegisterNatives 注册的 native 方法 + getHdid 调用栈. libhydeviceid.so 没有 JNI/生成函数导出(核心方法经 JNI_OnLoad -> RegisterNatives 动态注册)。 本脚本在 spawn 挂起中 hook libart.so 的 RegisterNatives, App 启动早期注册会被捕获, 拿到 libhydeviceid.so 注册的 native 方法指针 -> 基址偏移, 定位 hdid 生成入口。 同时 hook libudbauthunify.so 的 BusinessCfg::getHdid(0x26a484) 抓 hdid 值+调用栈。 用法: /Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0/.venv/bin/python \ scripts/phone_probe_registernatives.py [serial] [remote] 输出: evidence/diag_phone/hdid_registernatives.json """ from __future__ import annotations import json import subprocess import sys import time from pathlib import Path import frida SERIAL = sys.argv[1] if len(sys.argv) > 1 else "5dd8c93f" REMOTE = sys.argv[2] if len(sys.argv) > 2 else "127.0.0.1:31878" PACKAGE = "com.duowan.kiwi" REPO = Path("/Users/yml/codes/douyu_login_py") OUT = REPO / "evidence" / "diag_phone" / "hdid_registernatives.json" RE = Path("/Users/yml/codes/Reverse-Engineering-Agent-Universal-v3.0") ART_CALLSITE = RE / "evidence" / "scripts" / "bypass_msaoaid_maps_art_callsite.js" JS = r""" 'use strict'; function stdstr(p){ try{ if(p.isNull()) return ''; var first = p.readU8(); if((first & 1)===0){ var l=first>>1; return l? p.add(1).readUtf8String(l):''; } else { var d=p.readPointer(); var l=p.add(8).readU64(); return (l&&l<256)? d.readUtf8String(l):''; } }catch(e){ return ''; } } function modOf(a){ try{ var m=Process.findModuleByAddress(a); return m? {n:m.name, off:''+a.sub(m.base)}: {n:'?', off:'?'}; }catch(e){ return {n:'?',off:'?'}; } } // 1) hook libart RegisterNatives (function(){ var RN = Module.findExportByName('libart.so','_ZN3art3JNI15RegisterNativesEP7_JNIEnvP7_jclassPK15JNINativeMethodi'); if(!RN){ send({type:'rn-notfound'}); return; } send({type:'rn-found', a:''+RN}); Interceptor.attach(RN,{ onEnter:function(a){ var count = a[3].toInt32(); if(count<=0||count>500) return; var cls=''; try{ cls = Java.vm.tryGetEnv().getClassName(a[1])||''; }catch(e){ cls='?'; } for(var i=0;i