"""Deep fuzz of hdcp2_process_auth_message_v2 (cmd 0x0F) -- the full 580-byte struct. 0x0F memcpy_aligned's 0x244 bytes of host data into a stack struct then interprets it. Earlier runs only varied subcmd(+0x10) and N(+0x2B); this fuzzes every dword of the struct. Uses cmd 0x11 (close_all_sessions) to recycle slots so the run doesn't die of slot exhaustion (the defect that silently truncated earlier campaigns). """ import ctypes,struct,random,sys,collections from tinygrad import Device from tinygrad.runtime.autogen.am import am from tinygrad.helpers import lo32,hi32 d=Device["AMD"]; adev=d.iface.dev_impl; psp=adev.psp SZ=ctypes.sizeof(am.struct_psp_gfx_cmd_resp); P='/Users/user/dev/amd-psp-re/psp_out/'; S=0x8000; MARK=0x5A RANGES=[(0x00020000,0x00070000,'sOS'),(0x00400000,0x00412000,'HDCP'), (0x00D00000,0x00D50000,'ASD'),(0x00E10000,0x00E80000,'SYSDRV'),(0x0020A000,0x0020C000,'TAstage')] def classify(v): for lo,hi,nm in RANGES: if lo<=v1 else 13) ROUNDS=int(sys.argv[2]) if len(sys.argv)>2 else 6000 EX=[0,1,2,3,4,5,6,7,8,0xff,0x100,0xffff,0x10000,0xffffffff,0x7fffffff,0x80000000,0xfffffffe, 16,24,25,31,32,33,46,47,52,56,63,64,103,128,232,255,256,0x244,0x245,5120,5121] rets=collections.Counter(); leaks={}; hangs=[]; sizes=collections.Counter() for r in range(ROUNDS): if r%64==0: simple(0x11); g,SLOT=open_slot() if g!=0: print(" [r=%d] gate closed after recycle (ret=%s) - stopping"%(r,g)); break b=bytearray(S) for i in range(0x1400,S): b[i]=MARK struct.pack_into('3: break continue rets[struct.unpack_from('40: print(" [r=%d] OUTLIER write %d bytes %#06x..%#06x ret=%s"%(r,len(diff),diff[0],diff[-1],struct.unpack_from('