import frida, time, subprocess
ADB="/opt/android-sdk/platform-tools/adb"
JS=r"""
function il2str(p){ try{ if(p.isNull())return null; var l=p.add(8).readS32(); if(l<0||l>300)return null; return p.add(0xc).readUtf16String(l);}catch(e){return "<e>";} }
var done=false;
function tryread(){ var m=Process.findModuleByName("libil2cpp.so"); if(!m) return;
  var b=m.base; var EBX=b.add(0x1df6b7c);
  var disps=[0x675c8,0x4d5c8,0x68994,0x675cc,0x675c4,0x675d0,0x675d4,0x675bc,0x675c0,0x675b8,0x675dc];
  var got=0, out=[];
  for(var i=0;i<disps.length;i++){ try{var p=EBX.add(disps[i]).readPointer(); var s=il2str(p); out.push("0x"+disps[i].toString(16)+" = "+s); if(s)got++;}catch(e){out.push("0x"+disps[i].toString(16)+" ERR");} }
  if(got>0 && !done){ done=true; send("SLOTS:\n"+out.join("\n")); }
}
// also capture DataSection::Get keys
function hookGet(){ var m=Process.findModuleByName("libil2cpp.so"); if(!m) return false;
  var b=m.base;
  Interceptor.attach(b.add(0x10e7edd),{onEnter:function(a){ var k=il2str(a[1]); if(k) send("Get key="+k); }});
  return true;
}
var iv=setInterval(function(){ tryread(); },200);
if(!hookGet()){ var iv2=setInterval(function(){ if(hookGet())clearInterval(iv2); },150); }
send("__ready");
"""
dev=frida.get_usb_device(timeout=10)
subprocess.run([ADB,"shell","am","force-stop","se.foglo.svt"])
pid=dev.spawn(["se.foglo.svt"]); s=dev.attach(pid); sc=s.create_script(JS)
keys=set()
def om(m,d):
    p=m.get("payload","")
    if isinstance(p,str) and p.startswith("Get key="):
        k=p[8:]
        if k not in keys: keys.add(k); print(p,flush=True)
    else: print(p,flush=True)
sc.on("message",om); sc.load(); dev.resume(pid); time.sleep(20)
import sys; sys.stdout.flush()
print("=== unique Get keys seen ===", sorted(keys))
