import frida, time, subprocess
ADB="/opt/android-sdk/platform-tools/adb"
JS=r"""
var m=Process.findModuleByName("libil2cpp.so"), B=m.base;
function rdstr(p){try{if(p.isNull()||p.compare(ptr(0x10000))<0)return null;var n=p.add(8).readS32();if(n<0||n>200)return null;return p.add(0xc).readUtf16String(n);}catch(e){return null;}}
var gPID=new NativeFunction(B.add(0xfe0160),'pointer',['pointer']);
var gName=new NativeFunction(B.add(0xfe0171),'pointer',['pointer']);
var gType=new NativeFunction(B.add(0xfe0179),'int',['pointer']);
var gRank=new NativeFunction(B.add(0xfe0187),'int',['pointer']);
var gAvail=new NativeFunction(B.add(0xfe0168),'int',['pointer']);
var seen={};
function main(){
 // hook ThiefAvatar.Load onLeave -> dump the avatar's fields
 try{Interceptor.attach(B.add(0xfe01aa),{onEnter:function(){this.self=this.context.esp.add(4).readPointer();},onLeave:function(){
   try{var a=this.self; var pid=rdstr(gPID(a)); if(pid&&!seen[pid]){seen[pid]=1;
     send({g:"AVATAR pid='"+pid+"' name='"+rdstr(gName(a))+"' type="+gType(a)+" minRank="+gRank(a)+" avail="+gAvail(a)});}
   }catch(e){send({g:"dump err "+e});}
 }});}catch(e){send({g:"hook err "+e});}
 send({g:"__ready"});
}
main();
"""
def sh(*a): return subprocess.run([ADB]+list(a),capture_output=True,text=True)
sh("shell","am","force-stop","se.foglo.svt"); time.sleep(1)
sh("shell","monkey","-p","se.foglo.svt","-c","android.intent.category.LAUNCHER","1")
time.sleep(11)
dev=frida.get_usb_device(timeout=10)
pid=int(sh("shell","pidof","se.foglo.svt").stdout.split()[0]); print("pid",pid,flush=True)
s=dev.attach(pid); sc=s.create_script(JS)
sc.on("message",lambda mm,d: print(mm.get("payload",{}).get("g",""),flush=True) if isinstance(mm.get("payload"),dict) else None)
sc.load(); time.sleep(40); print("done",flush=True)
