import frida, subprocess, time
ADB="/opt/android-sdk/platform-tools/adb"
pid=int(subprocess.run([ADB,"shell","pidof","se.foglo.svt"],capture_output=True,text=True).stdout.split()[0])
print("attaching to pid",pid,flush=True)
JS=r"""
var B=Process.findModuleByName("libil2cpp.so").base;
var EBX=B.add(0x1df6b7c);
var singleton_field=EBX.add(0x4d650);   // B+0x1e441cc
var inSP=false, iters=0, sniper=0, thief=0, logged=0;
Interceptor.attach(B.add(0xe4bd6a),{
  onEnter:function(){ inSP=true; iters=0;
    try{
      var singleton=singleton_field.readPointer();
      var coll=singleton.isNull()?ptr(0):singleton.add(0x50).readPointer();
      if(logged<3){
        var cnt = coll.isNull()?-1:coll.add(0xc).readS32();
        var items = coll.isNull()?ptr(0):coll.add(0x8).readPointer();
        send({g:"SpawnPlayers: singleton="+singleton+" coll(@+0x50)="+coll+" count(@+0xc)="+cnt+" items="+items});
        logged++;
      }
    }catch(e){ if(logged<3){send({g:"read err "+e}); logged++;} }
  },
  onLeave:function(){ inSP=false; }
});
Interceptor.attach(B.add(0x118d46d),{onEnter:function(){ if(inSP)iters++; }});  // get_Current
Interceptor.attach(B.add(0xe4bfd8),{onEnter:function(){ sniper++; }});
Interceptor.attach(B.add(0xe4c511),{onEnter:function(){ thief++; }});
setTimeout(function(){ send({g:"5s totals: loopIters(getCurrent)="+iters+" SpawnSniper="+sniper+" SpawnThief="+thief}); },5000);
send({g:"probe live"});
"""
dev=frida.get_usb_device(timeout=10)
s=dev.attach(pid); sc=s.create_script(JS)
sc.on("message",lambda m,d: print(m.get("payload",{}).get("g",""),flush=True) if isinstance(m.get("payload"),dict) else print("MSG",m,flush=True))
sc.load(); time.sleep(7)
print("done",flush=True)
