#!/usr/bin/env python3 """Sylpheed static-analysis helper over DuckDB `sylpheed.db`. Hides the gotchas: DECIMAL bounds (DuckDB rejects 0x literals), read-only connect, and the fact that the engine vtable / rdata is NOT in the DB (read it from guest memory with `xenia-rs exec ... --dump-addr=0x` instead). Usage: zq.py dis # disassemble [lo,hi) zq.py fn # function containing pc (address,name,end) zq.py xref # xrefs whose target == addr (callers) zq.py callers # call-sites of vtable slot at byte offset N # (finds `lwz r11, N(r11)` + reports the fn) zq.py grep # instructions whose operands LIKE %substr% zq.py find # instructions whose raw word == value (e.g. a ptr) """ import duckdb, sys DB = '/home/fabi/RE - Project Sylpheed/xenia-rs/sylpheed.db' c = duckdb.connect(DB, read_only=True) H = lambda x: '0x%08x' % x def _fn(pc): r = c.execute('SELECT address,name,end_address FROM functions WHERE address<=? AND end_address>? ' 'ORDER BY address DESC LIMIT 1', [pc, pc]).fetchall() return f'{r[0][1]}({H(r[0][0])})' if r else '?' def main(): if len(sys.argv) < 2: print(__doc__); return cmd = sys.argv[1] if cmd == 'dis': lo, hi = int(sys.argv[2], 16), int(sys.argv[3], 16) for a, m, o in c.execute('SELECT address,mnemonic,operands FROM instructions ' 'WHERE address>=? AND address