"""Pinned offline proof of the original trade parent/leaf saved namespaces. No game access/writes."""
import hashlib
import json
import struct
from pathlib import Path
import pefile
from capstone import Cs,CS_ARCH_X86,CS_MODE_64
image=Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe');body=image.read_bytes()
sha='6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93'
if hashlib.sha256(body).hexdigest()!=sha:raise ValueError('Wrong original image')
pe=pefile.PE(data=body,fast_load=True);base=pe.OPTIONAL_HEADER.ImageBase
table=0x52A0960
slots={hex(offset):hex(struct.unpack('<Q',pe.get_data(table+offset,8))[0]-base) for offset in (0,0x1A8,0x1B0,0x1B8,0x1C0)}
if slots!={'0x0':'0x26008e0','0x1a8':'0x2648750','0x1b0':'0x26069a0','0x1b8':'0x2644e50','0x1c0':'0x2600a80'}:raise ValueError('Original settings slot binding changed')
strings={hex(rva):pe.get_data(rva,64).split(b'\0',1)[0].decode('ascii') for rva in (0x5195A88,0x5193840,0x52A17E8)}
if list(strings.values())!=['categories','commodities','VisibilityFlags']:raise ValueError('Original namespace changed')
cs=Cs(CS_ARCH_X86,CS_MODE_64);leaves=[]
for instruction in cs.disasm(pe.get_data(0x26008E0,24),0x26008E0):
leaves.append(dict(rva=hex(instruction.address),bytes=instruction.bytes.hex(),text=instruction.mnemonic+' '+instruction.op_str))
if instruction.mnemonic=='ret':break
if 0x26008E6+struct.unpack_from('<i',pe.get_data(0x26008E0,6),2)[0]!=0x5F05CE0:raise ValueError('Settings owner type differs')
sources=[Path('artifacts/galaxy-query-research/account-sources/decompiled')/name for name in ('3ac9700.c','3b58d00.c','26069a0.c','2648750.c')]
sources+=[Path('artifacts/galaxy-query-research/filter-enums/decompiled')/name for name in ('solo-2631820.c','solo-265ae40.c')]
result=dict(imageSha256=sha,settingsInterfaceVtable=hex(table),settingsTypeGlobal='0x5F05CE0',slots=slots,typeGetter=leaves,strings=strings,
flagsOffset='preset payload +0x138 (active array entry +0x18)',load='2631820: Root/VisibilityFlags -> namespace/leaf bool map',
save='265AE40: the same +138 map -> Root/VisibilityFlags',defaultValue=True,
selectionRule='category flag AND commodity flag, independent namespaces; disabled parent preserves leaf flags',
sourceFiles=[dict(path=str(p),sha256=hashlib.sha256(p.read_bytes()).hexdigest()) for p in sources],gameProcessAccess=False,gameCalls=0)
output=Path('artifacts/galaxy-query-research/current-trade/original-settings-binding.json')
output.write_text(json.dumps(result,indent=2)+'\n',encoding='utf-8');print(output)
"""Pinned offline proof of the original trade parent/leaf saved namespaces. No game access/writes."""
import hashlib
import json
import struct
from pathlib import Path
import pefile
from capstone import Cs,CS_ARCH_X86,CS_MODE_64
image=Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe');body=image.read_bytes()
sha='6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93'
if hashlib.sha256(body).hexdigest()!=sha:raise ValueError('Wrong original image')
pe=pefile.PE(data=body,fast_load=True);base=pe.OPTIONAL_HEADER.ImageBase
table=0x52A0960
slots={hex(offset):hex(struct.unpack('<Q',pe.get_data(table+offset,8))[0]-base) for offset in (0,0x1A8,0x1B0,0x1B8,0x1C0)}
if slots!={'0x0':'0x26008e0','0x1a8':'0x2648750','0x1b0':'0x26069a0','0x1b8':'0x2644e50','0x1c0':'0x2600a80'}:raise ValueError('Original settings slot binding changed')
strings={hex(rva):pe.get_data(rva,64).split(b'\0',1)[0].decode('ascii') for rva in (0x5195A88,0x5193840,0x52A17E8)}
if list(strings.values())!=['categories','commodities','VisibilityFlags']:raise ValueError('Original namespace changed')
cs=Cs(CS_ARCH_X86,CS_MODE_64);leaves=[]
for instruction in cs.disasm(pe.get_data(0x26008E0,24),0x26008E0):
leaves.append(dict(rva=hex(instruction.address),bytes=instruction.bytes.hex(),text=instruction.mnemonic+' '+instruction.op_str))
if instruction.mnemonic=='ret':break
if 0x26008E6+struct.unpack_from('<i',pe.get_data(0x26008E0,6),2)[0]!=0x5F05CE0:raise ValueError('Settings owner type differs')
sources=[Path('artifacts/galaxy-query-research/account-sources/decompiled')/name for name in ('3ac9700.c','3b58d00.c','26069a0.c','2648750.c')]
sources+=[Path('artifacts/galaxy-query-research/filter-enums/decompiled')/name for name in ('solo-2631820.c','solo-265ae40.c')]
result=dict(imageSha256=sha,settingsInterfaceVtable=hex(table),settingsTypeGlobal='0x5F05CE0',slots=slots,typeGetter=leaves,strings=strings,
flagsOffset='preset payload +0x138 (active array entry +0x18)',load='2631820: Root/VisibilityFlags -> namespace/leaf bool map',
save='265AE40: the same +138 map -> Root/VisibilityFlags',defaultValue=True,
selectionRule='category flag AND commodity flag, independent namespaces; disabled parent preserves leaf flags',
sourceFiles=[dict(path=str(p),sha256=hashlib.sha256(p.read_bytes()).hexdigest()) for p in sources],gameProcessAccess=False,gameCalls=0)
output=Path('artifacts/galaxy-query-research/current-trade/original-settings-binding.json')
output.write_text(json.dumps(result,indent=2)+'\n',encoding='utf-8');print(output)