import json, sys, time, subprocess, frida
ADB = "/opt/android-sdk/platform-tools/adb"
A = json.load(open("/root/ants/sid_addr.json"))
JS = r"""
var A=%s;
function ins(){
  var m=Process.findModuleByName("libil2cpp.so"); if(!m) return false;
  var b=m.base;
  var e=null; try{ e=Module.findExportByName("libil2cpp.so","il2cpp_string_new"); }catch(_){}
  if(!e){ try{ e=m.findExportByName("il2cpp_string_new"); }catch(_){} }
  var sn = e ? new NativeFunction(e,'pointer',['pointer']) : null;
  var SID="revived-"+(Date.now()%%1000000);
  function T(fn){ try{ fn(); }catch(e){ send({warn:""+e}); } }
  if(sn) T(function(){ Interceptor.attach(b.add(A["get_sessionId"]),{onLeave:function(rv){
    var em=true; try{ if(!rv.isNull()) em=(rv.add(8).readS32()<=0);}catch(e){}
    if(em) rv.replace(sn(Memory.allocUtf8String(SID)));
  }}); });
  ["get_TermsAccepted","get_FacebookTermsAccepted"].forEach(function(k){
    if(A[k]) T(function(){ Interceptor.attach(b.add(A[k]),{onLeave:function(rv){rv.replace(ptr(1));}}); });
  });
  if(A["Check25RoundsPlayed"]) T(function(){
    Interceptor.replace(b.add(A["Check25RoundsPlayed"]), new NativeCallback(function(s){},'void',['pointer'])); });
  ["OnDeviceLimit","OnPlayingOnAnotherDevice","Core.OnPlayingOnAnotherDevice"].forEach(function(k){
    if(A[k]) T(function(){ Interceptor.replace(b.add(A[k]), new NativeCallback(function(){ return; },'void',['pointer','pointer'])); });
  });
  if(A["FECore.get_ready"]) T(function(){ Interceptor.attach(b.add(A["FECore.get_ready"]),{onLeave:function(rv){rv.replace(ptr(1));}}); });
  // watch the character build + any abort
  function bt(ctx){ try{ var a=Thread.backtrace(ctx,Backtracer.ACCURATE),o=[]; for(var i=0;i<a.length&&i<12;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 ab=Process.findModuleByName("libc.so").findExportByName("abort"); Interceptor.attach(ab,{onEnter:function(){send("*** abort\n    "+bt(this.context));}}); }catch(_){}
  try{ Interceptor.attach(b.add(0xe1890d),{onEnter:function(){send("VaultThief.Initialise ENTER");},onLeave:function(){send("VaultThief.Initialise OK");}}); }catch(_){}
  send({m:"hooks installed, SID="+SID});
  return true;
}
if(!ins()){ var iv=setInterval(function(){ if(ins()) clearInterval(iv); },150); }
""" % json.dumps(A)

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("[%6.1f] %s"%(time.time()-t0,m.get("payload",m)), flush=True))
sc.load(); dev.resume(pid)
time.sleep(int(sys.argv[1]) if len(sys.argv)>1 else 90)
