import frida, time, subprocess
ADB="/opt/android-sdk/platform-tools/adb"
JS=r"""
function rd(p){ try{if(p.isNull())return null;var l=p.add(8).readS32();if(l<0||l>128)return null;return p.add(0xc).readUtf16String(l);}catch(e){return null;} }
function ins(){ var m=Process.findModuleByName("libil2cpp.so"); if(!m) return false;
 var b=m.base; var seen={};
 // LoadInventoryItem fires per owned item
 Interceptor.attach(b.add(0xd8c232),{onEnter:function(a){ send("LoadInventoryItem CALLED"); }});
 // section create: log name + parent for gadget-related
 Interceptor.attach(b.add(0x10ec2e8),{onEnter:function(a){ this.nm=rd(a[1]); },onLeave:function(rv){ try{ var nm=this.nm; if(nm && nm.indexOf("gadget")>=0){ var par=rv.isNull()?null:rd(rv.add(0x10)); send("CreateSection name='"+nm+"' parent='"+(rv.isNull()?"?":rd(rv.add(0x10)))+"' leaf='"+(rv.isNull()?"?":rd(rv.add(0xc)))+"'"); } }catch(e){} }});
 // equipped getters
 function G(a,n){ Interceptor.attach(b.add(a),{onLeave:function(rv){ var k=n+"="+(rv.isNull()?"NULL":"obj"); if(!seen[k]){seen[k]=1; send(k);} }}); }
 G(0xd91f2b,"get_mask");
 // set_mask fired => equip worked
 Interceptor.attach(b.add(0xd91f36),{onEnter:function(a){ send("set_mask CALLED"); }});
 Interceptor.attach(b.add(0xd9086e),{onEnter:function(){send(">LinkInventory");}});
 Interceptor.attach(b.add(0xe1890d),{onEnter:function(){send(">VaultThief.Initialise");},onLeave:function(){send("VaultThief.Initialise LEAVE-OK");}});
 // abort backtrace
 function bt(ctx){ try{ var a=Thread.backtrace(ctx,Backtracer.ACCURATE),o=[]; for(var i=0;i<a.length&&i<14;i++){var ad=a[i],mm=Process.findModuleByAddress(ad);o.push(mm?mm.name+"+0x"+ad.sub(mm.base).toString(16):ad.toString());} return o.join("\n    ");}catch(e){return"bt-err";} }
 try{ var e=Process.findModuleByName("libc.so").findExportByName("abort"); Interceptor.attach(e,{onEnter:function(){send("*** abort\n    "+bt(this.context));}}); }catch(_){}
 send("__ready"); return true; }
if(!ins()){ var iv=setInterval(function(){ if(ins()) clearInterval(iv); },120); }
"""
subprocess.run([ADB,"shell","am","force-stop","se.foglo.svt"])
dev=frida.get_usb_device(timeout=10); pid=dev.spawn(["se.foglo.svt"])
s=dev.attach(pid); sc=s.create_script(JS); t0=time.time()
s.on("detached", lambda r,c=None: print("DETACH @%.1f %s"%(time.time()-t0,r),flush=True))
sc.on("message",lambda m,d: print("[%5.1f] %s"%(time.time()-t0,m.get("payload",m)),flush=True))
sc.load(); dev.resume(pid)
time.sleep(45)
