#!/usr/bin/env python3 """ verify_framing.py -- static check that the SHIPPED FLYK.EXE frames the VelociRender protocol exactly the way vrboard.py assumes (framing derived from VR_COMMS.C source). Confirms, inside the real binary's code object: * the length-word broadcast mask (0xff<<16) = 0x00FF0000 (velocirender_transmit) * the iserver control bit 0x80000000 (send_link_protocol) * the packetize chunk size 512-4 = 508 = 0x1FC (velocirender_packetize) * C012 link-adapter port I/O IN/OUT via DX (LINKIO.C) * the default link base 0x150 (getXputer) Usage: python verify_framing.py /path/to/FLYK.EXE """ import sys from leimage import LE try: from capstone import Cs, CS_ARCH_X86, CS_MODE_32 except ImportError: Cs = None def le32(v): return bytes([v & 0xff, (v>>8)&0xff, (v>>16)&0xff, (v>>24)&0xff]) def scan(img, needle): hits, i = [], img.find(needle) while i != -1: hits.append(i); i = img.find(needle, i+1) return hits def main(path): le = LE(path) base, img = le.image(1) # code object print(f"code object: base={base:#x} size={len(img):#x} ({len(img)} bytes)\n") checks = { "length-word mask 0x00FF0000 (broadcast id | count)": le32(0x00FF0000), "iserver control bit 0x80000000": le32(0x80000000), "packetize chunk 0x000001FC (512-4)": le32(0x000001FC), "default link base 0x00000150 (getXputer)": le32(0x00000150), } results = {} for label, needle in checks.items(): hits = scan(img, needle) results[label] = hits mark = "OK " if hits else "-- " where = ("VA " + ", ".join(f"{base+h:#x}" for h in hits[:4]) + (" ..." if len(hits) > 4 else "")) if hits else "not found as literal" print(f"[{mark}] {label:52} {len(hits):3} hit(s) {where}") # x86 port I/O: IN/OUT with DX (EC in AL,DX / ED in eAX,DX / EE out DX,AL / EF out DX,eAX) portio = {op: img.count(bytes([op])) for op in (0xEC,0xED,0xEE,0xEF)} print(f"\nport-I/O opcodes (raw byte freq, upper bound): " f"IN AL,DX={portio[0xEC]} IN eAX,DX={portio[0xED]} " f"OUT DX,AL={portio[0xEE]} OUT DX,eAX={portio[0xEF]}") # Disassemble a window around the first length-word-mask hit to show the OR that builds it. if Cs and results[next(iter(results))]: h = results["length-word mask 0x00FF0000 (broadcast id | count)"][0] md = Cs(CS_ARCH_X86, CS_MODE_32) lo = max(0, h-24) print(f"\n--- disasm around length-word construction (VA {base+lo:#x}) ---") for ins in md.disasm(img[lo:h+16], base+lo): print(f" {ins.address:#010x} {ins.mnemonic:6} {ins.op_str}") elif not Cs: print("\n(capstone not available -- byte-literal scan only)") print("\nVERDICT:", "framing constants present -> shipped FLYK matches the source-derived protocol" if results["iserver control bit 0x80000000"] and results["length-word mask 0x00FF0000 (broadcast id | count)"] else "framing constants NOT all found as literals -- inspect (may be computed)") if __name__ == '__main__': main(sys.argv[1])