"""Bounded, build-pinned native telemetry; optionally select original eligible SOLO actions."""
import argparse
import hashlib
import json
import pathlib
import time
import frida
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--pid',type=int,required=True)
parser.add_argument('--profile',type=pathlib.Path,required=True)
parser.add_argument('--output',type=pathlib.Path,required=True)
parser.add_argument('--seconds',type=int,default=30,choices=range(5,181))
parser.add_argument('--enter-solo',action='store_true')
args=parser.parse_args()
profile=json.loads(args.profile.read_text(encoding='utf-8-sig'))
if hashlib.sha256(pathlib.Path(profile['image']).read_bytes()).hexdigest()!=profile['sha256']:
raise SystemExit('The selected game build does not match the inspected native profile')
source='const PROFILE='+json.dumps(profile)+'; const ENTER_SOLO='+json.dumps(args.enter_solo)+';\n'+pathlib.Path(__file__).with_name('navigation-probe.js').read_text(encoding='utf-8')
args.output.parent.mkdir(parents=True,exist_ok=True)
counts={}
errors=set()
with args.output.open('x',encoding='utf-8') as output:
session=frida.attach(args.pid)
try:
script=session.create_script(source)
def on_message(message,data):
row=message.get('payload') if message.get('type')=='send' else {'kind':'script-error','error':message}
output.write(json.dumps(row)+'\n');output.flush()
kind=row.get('kind','unknown');counts[kind]=counts.get(kind,0)+1
if kind=='script-error':
key=json.dumps(row)
if key in errors:return
errors.add(key)
if kind not in ('native-flight-sample',):print(json.dumps(row),flush=True)
script.on('message',on_message)
script.load()
deadline=time.monotonic()+args.seconds
while time.monotonic()<deadline and not errors:time.sleep(.1)
script.unload()
finally:
session.detach()
print(json.dumps({'counts':counts,'screenUse':False,'flightInputsSent':0}),flush=True)
"""Bounded, build-pinned native telemetry; optionally select original eligible SOLO actions."""
import argparse
import hashlib
import json
import pathlib
import time
import frida
parser=argparse.ArgumentParser(description=__doc__)
parser.add_argument('--pid',type=int,required=True)
parser.add_argument('--profile',type=pathlib.Path,required=True)
parser.add_argument('--output',type=pathlib.Path,required=True)
parser.add_argument('--seconds',type=int,default=30,choices=range(5,181))
parser.add_argument('--enter-solo',action='store_true')
args=parser.parse_args()
profile=json.loads(args.profile.read_text(encoding='utf-8-sig'))
if hashlib.sha256(pathlib.Path(profile['image']).read_bytes()).hexdigest()!=profile['sha256']:
raise SystemExit('The selected game build does not match the inspected native profile')
source='const PROFILE='+json.dumps(profile)+'; const ENTER_SOLO='+json.dumps(args.enter_solo)+';\n'+pathlib.Path(__file__).with_name('navigation-probe.js').read_text(encoding='utf-8')
args.output.parent.mkdir(parents=True,exist_ok=True)
counts={}
errors=set()
with args.output.open('x',encoding='utf-8') as output:
session=frida.attach(args.pid)
try:
script=session.create_script(source)
def on_message(message,data):
row=message.get('payload') if message.get('type')=='send' else {'kind':'script-error','error':message}
output.write(json.dumps(row)+'\n');output.flush()
kind=row.get('kind','unknown');counts[kind]=counts.get(kind,0)+1
if kind=='script-error':
key=json.dumps(row)
if key in errors:return
errors.add(key)
if kind not in ('native-flight-sample',):print(json.dumps(row),flush=True)
script.on('message',on_message)
script.load()
deadline=time.monotonic()+args.seconds
while time.monotonic()<deadline and not errors:time.sleep(.1)
script.unload()
finally:
session.detach()
print(json.dumps({'counts':counts,'screenUse':False,'flightInputsSent':0}),flush=True)