XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
"""Bind actual Dust runtime input fields and parameter-publisher boundary, PE only."""
import hashlib,importlib.util,json,struct,re
from pathlib import Path
spec=importlib.util.spec_from_file_location('audit',Path(__file__).with_name('Audit-GalaxyClientCompatibility.py'))
audit=importlib.util.module_from_spec(spec);spec.loader.exec_module(audit)
old=audit.Image(Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe'))
new=audit.Image(Path('D:/SteamLibrary/steamapps/common/Elite Dangerous/Products/elite-dangerous-odyssey-64/EliteDangerous64.exe'))
hashes=('6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93','ed5a8f8cd10f9a80d3bda5badd7ba1d4fcfc15996c8c7e018852cb170e264b63')
assert tuple(hashlib.sha256(x.raw).hexdigest() for x in (old,new))==hashes
functions=[];refs=[]
for before in [0x3A08F00,0x3A06740,0x3A21BC0,0x3A469D0,0x3A969E0,0x3A31B20,0x3A09F20,0x3AAC040,0x434C6E0,0x3AB44E0]:
    fn=old.function(before);assert fn and fn[0]==before
    row=audit.match(old,new,before,fn[1]-before);assert row['status']=='unique',(hex(before),row)
    row['oldRva']=hex(before);functions.append(row)
    refs+=audit.references(old,new,before,int(row['newRva'],16),row['length'])
tables={}
for before in [0x5527180,0x55271B0,0x55272B0,0x551F2D8,0x551F308,0x551F408,0x551F548,0x551EF18]:
    candidates={r[1] for r in refs if r[0]==before};assert len(candidates)==1,(hex(before),candidates)
    tables[hex(before)]=hex(candidates.pop())
slots=[]
for slot,before,length in [(0x38,0x3A4E8C0,24),(0x48,0x3D4C90,7)]:
    table=int(tables['0x55272b0'],16)
    assert struct.unpack('<Q',old.data(0x55272B0+slot,8))[0]-old.base==before
    after=struct.unpack('<Q',new.data(table+slot,8))[0]-new.base
    assert old.data(before,length)==new.data(after,length)
    slots.append(dict(oldVtable='0x55272b0',newVtable=hex(table),slot=hex(slot),oldRva=hex(before),newRva=hex(after),bytes=length,rawLeafWholeBody=True))
    refs+=audit.references(old,new,before,after,length)
globals_={}
for before in [0x5FA0A20,0x4DE28B8,0x4E328B0,0x53875E4]:
    candidates={r[1] for r in refs if r[0]==before};assert len(candidates)==1,(hex(before),candidates)
    globals_[hex(before)]=hex(candidates.pop())
for before,after in globals_.items():
    if int(before,16)!=0x5FA0A20:assert old.data(int(before,16),4)==new.data(int(after,16),4)
names=[];source=Path('artifacts/galaxy-query-research/constellations/decompiled/solo-3a09f20.c').read_text()
for match in re.finditer(r'&UNK_14([0-9a-f]+)\);\s*uVar6 =.*?FUN_144348480\(param_1 \+ (0x[0-9a-f]+|[0-9]+),uVar6\);',source,re.S):
    name=old.data(int(match[1],16),96).split(b'\0')[0].decode('ascii');offset=int(match[2],0)*8
    names.append(dict(name=name,parameter=hex(offset),value=hex(offset+0x88)))
assert len(names)==34 and names[:4]==[dict(name=n,parameter=hex(0x10+i*0x90),value=hex(0x98+i*0x90)) for i,n in enumerate(['gAlphaFadeRange','gAlphaFadeRadius','gAlphaFadeRangeFar','gAlphaFadeRadiusFar'])]
assert 'pDustColour' not in {r['name'] for r in names}
result=dict(runtimeNeutral=True,gameProcessAccess=False,gameCalls=0,oldImageSha256=hashes[0],newImageSha256=hashes[1],
    functions=functions,vtables=tables,slots=slots,globals=globals_,references=[list(map(hex,r)) for r in refs],
    genericParameters=names,fields=dict(providerPublishedLayers=0x1E8,layerStride=0xF0,layerCount=3,
        publishedVersion=4,requestedVersion=8,publishedRadius=0x10,publishedCount=0x40,publishedRecords=0x48,publisherLockDepth=0xD8,
        providerDustStep=0x80,providerDustHeight=0x88,rendererLayerAlphaSize=0x990,rendererGlobalAlpha=0x9AC,rendererGlobalSize=0x9BC,
        rendererTransitionPerStep=0x9C0,rendererMinimumDistance=0x9CC),
    frameRule=dict(width='float(dustStep)*pow(.5,ordinal)*transitionPerStep',
        lower='minimumDistance when ordinal1 or final layer or next publishedVersion0; otherwise next publishedRadius-width*.5',
        upper='300000 for ordinal0; otherwise own publishedRadius+width',
        note='Published readiness belongs to that owner cache. Never transfer another game-camera completion state into a tool cache.'),
    tint=dict(status='unknown',boundary='8E0->39F2210->3A09F20->3AAC040 publishes34 generic controls without pDustColour. Effective Dust shader CB2 tint must be read/verified separately; authored zero is insufficient.'),productionDustEnabled=False)
path=Path('artifacts/galaxy-query-research/power-outer-sources/background/dust-runtime/compatibility.json')
path.parent.mkdir(parents=True,exist_ok=True);path.write_text(json.dumps(result,indent=2)+'\n',encoding='utf8')
print(json.dumps(dict(path=str(path),functions=len(functions),vtables=tables,slots=slots,globals=globals_,parameters=len(names),productionDustEnabled=False),indent=2))