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;
 // SetEquippedRifle(this, rifleItem)
 Interceptor.attach(b.add(0xd99193),{onEnter:function(a){
   try{ var self=a[0]; var item=a[1];
     var lst=self.add(0x4c).readPointer();
     var cnt=lst.isNull()?-1:lst.add(0xc).readS32();
     send("SetEquippedRifle: ownedRifles[0x4c]="+lst+" count="+cnt+" rifleItemArg="+(item.isNull()?"NULL":item));
   }catch(e){ send("SER err "+e); }
 }});
 // OwnedRifle.ctor(this, ...) - log the created OwnedRifle ptr + its inventoryItem after ctor
 Interceptor.attach(b.add(0x10287c6),{onEnter:function(a){ this.self=a[0]; },onLeave:function(){ try{ send("OwnedRifle created @"+this.self); }catch(e){} }});
 // LinkInventory: read [profile+0x4c] count at entry
 Interceptor.attach(b.add(0xd9086e),{onEnter:function(a){ try{ var self=a[0]; var lst=self.add(0x4c).readPointer(); var cnt=lst.isNull()?-1:lst.add(0xc).readS32(); send("LinkInventory enter: profile="+self+" ownedRifles[0x4c]="+lst+" count="+cnt); }catch(e){} }});
 var ab=Process.findModuleByName("libc.so").findExportByName("abort");
 Interceptor.attach(ab,{onEnter:function(){send("*** ABORT ***");}});
 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)
s.on("detached", lambda r,c=None: print("DETACH %s"%r,flush=True))
sc.on("message",lambda m,d: print(m.get("payload",m),flush=True))
sc.load(); dev.resume(pid); time.sleep(38)
