"""Bounded original point-fade owner and supplemental-submission evidence."""
from pathlib import Path
import hashlib
import json
import struct
import pefile
from capstone import Cs, CS_ARCH_X86, CS_MODE_64
ROOT=Path(__file__).resolve().parents[1]
OUT=ROOT/'artifacts/galaxy-query-research/power-outer-sources/frame-fade-state'
raw=(ROOT/'artifacts/ship-model-reference/client-copy/EliteDangerous64.exe').read_bytes()
sha=hashlib.sha256(raw).hexdigest()
assert sha=='6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93'
pe=pefile.PE(data=raw,fast_load=True)
decoder=Cs(CS_ARCH_X86,CS_MODE_64)
proof=[]
def instruction(rva,expected):
item=next(decoder.disasm(pe.get_data(rva,15),rva))
actual=item.mnemonic+' '+item.op_str
assert actual==expected,(hex(rva),actual,expected)
proof.append(dict(rva=hex(rva),bytes=item.bytes.hex(),instruction=actual))
# Actual caller supplies the renderer's captured frame, supplemental map and
# output buffer. The context's six-qword offset is the frame, not current selection.
instruction(0x3AB834E,'lea r9, [rsi + 0xd78]')
instruction(0x3AB8355,'mov rcx, rsi')
instruction(0x3AB8358,'lea r8, [rsi + 0xd50]')
instruction(0x3AB835F,'lea rdx, [rsi + 0xa00]')
instruction(0x3AB8366,'call 0x3a66600')
instruction(0x3A66646,'mov rsi, rdx')
instruction(0x3A666E1,'mov qword ptr [rsp + 0x50], rdi')
instruction(0x3A666EB,'mov qword ptr [rsp + 0x60], r13')
instruction(0x3A666F0,'mov qword ptr [rsp + 0x78], r15')
instruction(0x3A666F5,'mov qword ptr [rbp - 0x80], rsi')
instruction(0x3A66849,'lea rcx, [rsp + 0x50]')
instruction(0x3A6684E,'call 0x3a15d90')
# Each D50 row starts pending. A normal cell match consumes it; unconsumed
# entries are explicitly submitted after the ordinary-cell loop.
instruction(0x3A15F6F,'movzx r13d, byte ptr [rbx + 8]')
instruction(0x3A15F74,'xor bpl, bpl')
instruction(0x3A15F8F,'mov byte ptr [rbx], bpl')
instruction(0x3A6699F,'cmp byte ptr [rbx + 8], 0')
instruction(0x3A669A3,'lea r8, [rbx + 8]')
instruction(0x3A669A7,'je 0x3a669cc')
instruction(0x3A669C7,'call 0x3a15d90')
for rva in [0x3A2732F,0x3A273F3,0x3A274B2,0x3A2751B,0x3A27589,0x3A275F7,0x3A27665]:
instruction(rva,'call 0x39fcdf0')
# Optional NavRoute membership is a separate minimum-floor exception even
# when no supplemental record exists. This is a real address lookup, not
# permission to equate all StellarForge points with the default branch.
assert struct.unpack('<Q',pe.get_data(0x529E328+0x110,8))[0]==pe.OPTIONAL_HEADER.ImageBase+0x26174B0
instruction(0x26174C2,'imul rdx, rax, 0x2e8')
instruction(0x26174C9,'lea rcx, [rdx + rcx + 0x120]')
instruction(0x26174D6,'call 0x63bd80')
instruction(0x26174DE,'setne al')
source_files=[ROOT/'artifacts/galaxy-query-research/power-outer-sources/decompiled'/('solo-'+name+'.c')
for name in ['3a26260','3a26fa0','3a66600','3a15d90']]
sources=[dict(path=str(path.relative_to(ROOT)),sha256=hashlib.sha256(path.read_bytes()).hexdigest()) for path in source_files]
result=dict(imageSha256=sha,gameProcessAccess=False,gameCalls=0,
owner=dict(worker='3AB8300',frameArgument='renderer+A00',supplementalMap='renderer+D50',output='renderer+D78',
contextBase='stack+50 in3A66600',context5='navigation getter58 current shared object (stack78)',
context6='captured renderer frame (stack80 = rbp-80)',
consumer='3A15D90 uses context6+240 = renderer+A00+240 = rendererC40',
builder='3A26260 ->3ACA010;3A26FA0 copies that exact prepared frame torendererC40'),
supplementalMap=dict(classification='Supplemental forced submissions and per-object overrides, not the ordinary cell collection',
refresh='3A26FA0 clears D50 and rebuilds it from the seven sources below every frame',
recordBytes=24,recordLayout={'0':'compact shared object','8':'pending byte','C':'minimum style value float','10':'farFade byte'},
payloadPointer='3A15D90 receives fullRecord+8, so payload[8] means fullRecord+10',
ordinaryMatch='Clears payload[0], supplies minimum-floor bypass0, uses payload[8] farFade',
afterCells='3A66600 explicitly submits every remaining pending row with opacity1; therefore these are extra submissions',
sources=[
dict(source='active appearance provider supplemental vector:3B32CB0 ->activeProvider+18',farFade=True,minimumStyle=0),
dict(source='renderer180 / dependency5FA0A1C virtual38 object map; exact user-facing identity unconfirmed',farFade=False,minimumStyle=1),
dict(source='navigation interface50 ->base308 Home centre object',farFade=False,minimumStyle=1),
dict(source='navigation interface60 ->base2E8 object; exact user-facing identity unconfirmed',farFade=False,minimumStyle=1),
dict(source='navigation interface68 ->base310 object; exact user-facing identity unconfirmed',farFade=False,minimumStyle=1),
dict(source='navigation interface58 ->base2C0 object, also the context5 identity comparison',farFade=True,minimumStyle=1),
dict(source='renderer198 / active-settings dependency5FDB224 virtual18 object',farFade=True,minimumStyle=1)]),
defaultPoint=dict(bypassMinimum=True,farFade=True,
conditions=['No supplemental map row','Optional local-player NavRoute interface110 does not contain systemAddress for selected smallMode'],
navRoute=dict(typeId='5F05DD0',vtable='529E328',getter='110 /26174B0',
lookup='interface120+smallMode*2E8;63BD80(systemAddress)',
onMembership='bypassMinimum0,farFade1; does not require a D50 row',
scopeLimit='Membership must not be guessed solely from StellarForge source or a planned-route overlay list'),
sizeMultiplied=False),sources=sources,proofs=proof)
OUT.mkdir(parents=True,exist_ok=True)
path=OUT/'original-frame-point-sources.json'
path.write_text(json.dumps(result,indent=2)+'\n',encoding='utf-8')
print(json.dumps(dict(proofCount=len(proof),sourceCount=7,frameOwner='renderer+A00',
supplementalMapNotOrdinaryCells=True,navRouteExceptionRequiresMembership=True,output=str(path))))
"""Bounded original point-fade owner and supplemental-submission evidence."""
from pathlib import Path
import hashlib
import json
import struct
import pefile
from capstone import Cs, CS_ARCH_X86, CS_MODE_64
ROOT=Path(__file__).resolve().parents[1]
OUT=ROOT/'artifacts/galaxy-query-research/power-outer-sources/frame-fade-state'
raw=(ROOT/'artifacts/ship-model-reference/client-copy/EliteDangerous64.exe').read_bytes()
sha=hashlib.sha256(raw).hexdigest()
assert sha=='6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93'
pe=pefile.PE(data=raw,fast_load=True)
decoder=Cs(CS_ARCH_X86,CS_MODE_64)
proof=[]
def instruction(rva,expected):
item=next(decoder.disasm(pe.get_data(rva,15),rva))
actual=item.mnemonic+' '+item.op_str
assert actual==expected,(hex(rva),actual,expected)
proof.append(dict(rva=hex(rva),bytes=item.bytes.hex(),instruction=actual))
# Actual caller supplies the renderer's captured frame, supplemental map and
# output buffer. The context's six-qword offset is the frame, not current selection.
instruction(0x3AB834E,'lea r9, [rsi + 0xd78]')
instruction(0x3AB8355,'mov rcx, rsi')
instruction(0x3AB8358,'lea r8, [rsi + 0xd50]')
instruction(0x3AB835F,'lea rdx, [rsi + 0xa00]')
instruction(0x3AB8366,'call 0x3a66600')
instruction(0x3A66646,'mov rsi, rdx')
instruction(0x3A666E1,'mov qword ptr [rsp + 0x50], rdi')
instruction(0x3A666EB,'mov qword ptr [rsp + 0x60], r13')
instruction(0x3A666F0,'mov qword ptr [rsp + 0x78], r15')
instruction(0x3A666F5,'mov qword ptr [rbp - 0x80], rsi')
instruction(0x3A66849,'lea rcx, [rsp + 0x50]')
instruction(0x3A6684E,'call 0x3a15d90')
# Each D50 row starts pending. A normal cell match consumes it; unconsumed
# entries are explicitly submitted after the ordinary-cell loop.
instruction(0x3A15F6F,'movzx r13d, byte ptr [rbx + 8]')
instruction(0x3A15F74,'xor bpl, bpl')
instruction(0x3A15F8F,'mov byte ptr [rbx], bpl')
instruction(0x3A6699F,'cmp byte ptr [rbx + 8], 0')
instruction(0x3A669A3,'lea r8, [rbx + 8]')
instruction(0x3A669A7,'je 0x3a669cc')
instruction(0x3A669C7,'call 0x3a15d90')
for rva in [0x3A2732F,0x3A273F3,0x3A274B2,0x3A2751B,0x3A27589,0x3A275F7,0x3A27665]:
instruction(rva,'call 0x39fcdf0')
# Optional NavRoute membership is a separate minimum-floor exception even
# when no supplemental record exists. This is a real address lookup, not
# permission to equate all StellarForge points with the default branch.
assert struct.unpack('<Q',pe.get_data(0x529E328+0x110,8))[0]==pe.OPTIONAL_HEADER.ImageBase+0x26174B0
instruction(0x26174C2,'imul rdx, rax, 0x2e8')
instruction(0x26174C9,'lea rcx, [rdx + rcx + 0x120]')
instruction(0x26174D6,'call 0x63bd80')
instruction(0x26174DE,'setne al')
source_files=[ROOT/'artifacts/galaxy-query-research/power-outer-sources/decompiled'/('solo-'+name+'.c')
for name in ['3a26260','3a26fa0','3a66600','3a15d90']]
sources=[dict(path=str(path.relative_to(ROOT)),sha256=hashlib.sha256(path.read_bytes()).hexdigest()) for path in source_files]
result=dict(imageSha256=sha,gameProcessAccess=False,gameCalls=0,
owner=dict(worker='3AB8300',frameArgument='renderer+A00',supplementalMap='renderer+D50',output='renderer+D78',
contextBase='stack+50 in3A66600',context5='navigation getter58 current shared object (stack78)',
context6='captured renderer frame (stack80 = rbp-80)',
consumer='3A15D90 uses context6+240 = renderer+A00+240 = rendererC40',
builder='3A26260 ->3ACA010;3A26FA0 copies that exact prepared frame torendererC40'),
supplementalMap=dict(classification='Supplemental forced submissions and per-object overrides, not the ordinary cell collection',
refresh='3A26FA0 clears D50 and rebuilds it from the seven sources below every frame',
recordBytes=24,recordLayout={'0':'compact shared object','8':'pending byte','C':'minimum style value float','10':'farFade byte'},
payloadPointer='3A15D90 receives fullRecord+8, so payload[8] means fullRecord+10',
ordinaryMatch='Clears payload[0], supplies minimum-floor bypass0, uses payload[8] farFade',
afterCells='3A66600 explicitly submits every remaining pending row with opacity1; therefore these are extra submissions',
sources=[
dict(source='active appearance provider supplemental vector:3B32CB0 ->activeProvider+18',farFade=True,minimumStyle=0),
dict(source='renderer180 / dependency5FA0A1C virtual38 object map; exact user-facing identity unconfirmed',farFade=False,minimumStyle=1),
dict(source='navigation interface50 ->base308 Home centre object',farFade=False,minimumStyle=1),
dict(source='navigation interface60 ->base2E8 object; exact user-facing identity unconfirmed',farFade=False,minimumStyle=1),
dict(source='navigation interface68 ->base310 object; exact user-facing identity unconfirmed',farFade=False,minimumStyle=1),
dict(source='navigation interface58 ->base2C0 object, also the context5 identity comparison',farFade=True,minimumStyle=1),
dict(source='renderer198 / active-settings dependency5FDB224 virtual18 object',farFade=True,minimumStyle=1)]),
defaultPoint=dict(bypassMinimum=True,farFade=True,
conditions=['No supplemental map row','Optional local-player NavRoute interface110 does not contain systemAddress for selected smallMode'],
navRoute=dict(typeId='5F05DD0',vtable='529E328',getter='110 /26174B0',
lookup='interface120+smallMode*2E8;63BD80(systemAddress)',
onMembership='bypassMinimum0,farFade1; does not require a D50 row',
scopeLimit='Membership must not be guessed solely from StellarForge source or a planned-route overlay list'),
sizeMultiplied=False),sources=sources,proofs=proof)
OUT.mkdir(parents=True,exist_ok=True)
path=OUT/'original-frame-point-sources.json'
path.write_text(json.dumps(result,indent=2)+'\n',encoding='utf-8')
print(json.dumps(dict(proofCount=len(proof),sourceCount=7,frameOwner='renderer+A00',
supplementalMapNotOrdinaryCells=True,navRouteExceptionRequiresMembership=True,output=str(path))))