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 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;}}
var savedMask=null;
function ins(){var m=Process.findModuleByName("libil2cpp.so");if(!m)return false;var b=m.base;
 function T(f){try{f();}catch(e){send({warn:""+e});}}
 // --- equip crash fixes ---
 T(function(){Interceptor.replace(b.add(0xd99335),new NativeCallback(function(s){return;},"void",["pointer"]));}); // UpdateRifle no-op
 T(function(){Interceptor.replace(b.add(0xd87d14),new NativeCallback(function(s){return;},"void",["pointer"]));}); // UpdateBag no-op
 // capture a valid mask from FindMask('mask_1'); force get_mask non-null
 T(function(){Interceptor.attach(b.add(0x235abe),{onEnter:function(a){this.id=rd(a[1]);},onLeave:function(rv){ if(this.id=="mask_1"&&!rv.isNull()&&!savedMask){savedMask=rv;send({info:"captured mask_1"});} }});});
 var profPtr=null;
 // --- boot forcing (session/terms/pc-ready) ---
 var e=null;try{e=Module.findExportByName("libil2cpp.so","il2cpp_string_new");}catch(_){}
 var sn=e?new NativeFunction(e,'pointer',['pointer']):null;
 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(x){}if(em)rv.replace(sn(Memory.allocUtf8String("rev-1")));}});});
 ["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"]));});
 // --- monitors ---
 T(function(){ // nop the mask-set id-match je at 0xd90d8b so LinkInventory equips the owned mask
   Memory.patchCode(b.add(0xd90d8b), 2, function(code){ code.writeByteArray([0x90,0x90]); });
   send({info:"patched mask je->nop"});
 });
 T(function(){Interceptor.attach(b.add(0xd9086e),{onEnter:function(a){profPtr=a[0];},onLeave:function(){ try{ if(profPtr){ var mk=profPtr.add(0x134).readPointer(); send({info:"after LinkInventory: get_mask=[+0x134]="+(mk.isNull()?"NULL":mk)}); } }catch(e){} send({info:"LinkInventory OK"});}});});
 var gcn=null; try{gcn=new NativeFunction(Module.findExportByName("libil2cpp.so","il2cpp_class_get_name"),'pointer',['pointer']);}catch(e){}
 T(function(){Interceptor.attach(b.add(0xe1890d),{onEnter:function(){ try{ var k=b.add(0x1e442d0).readPointer(); send({info:"mask-iface klass="+k+" name="+(gcn?gcn(k).readUtf8String():"?")}); var kk=b.add(0x1e442d0).readPointer(); var nms=[]; for(var o=4;o<=0x24;o+=4){try{var q=kk.add(o).readPointer(); var str=q.readUtf8String(); if(str&&str.length<40&&/^[A-Za-z_.<]/.test(str)) nms.push("+0x"+o.toString(16)+"='"+str+"'");}catch(e){}} send({info:"iface-klass fields: "+nms.join(" ")});
      var mk=savedMask.readPointer(); var mn=[]; for(var o2=4;o2<=0x24;o2+=4){try{var q2=mk.add(o2).readPointer(); var s2=q2.readUtf8String(); if(s2&&s2.length<40&&/^[A-Za-z_.<]/.test(s2)) mn.push("+0x"+o2.toString(16)+"='"+s2+"'");}catch(e){}} send({info:"savedMask-klass fields: "+mn.join(" ")}); }catch(e){send({warn:"iface "+e});} },onLeave:function(){send({info:"VaultThief OK"});}});});
 T(function(){Interceptor.attach(b.add(0xd437c9),{onLeave:function(){send({info:"ConfigureFromProfile OK"});}});});
 T(function(){var ab=Process.findModuleByName("libc.so").findExportByName("abort");Interceptor.attach(ab,{onEnter:function(){var bt=Thread.backtrace(this.context,Backtracer.ACCURATE).slice(0,14).map(function(a){var mm=Process.findModuleByAddress(a);return mm?mm.name+"+0x"+a.sub(mm.base).toString(16):""+a;}).join(",");send({info:"*** ABORT "+bt});}});});
 send({info:"__ready"});return true;}
if(!ins()){var iv=setInterval(function(){if(ins())clearInterval(iv);},120);}
""" % 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 %s @%.1f"%(r,time.time()-t0),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(int(sys.argv[1]) if len(sys.argv)>1 else 55)
