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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
"""Exact original/current allegiance-definition provider; offline PE only."""
import hashlib,importlib.util,json,struct
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'))
expected=('6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93','ed5a8f8cd10f9a80d3bda5badd7ba1d4fcfc15996c8c7e018852cb170e264b63')
assert tuple(hashlib.sha256(i.raw).hexdigest() for i in (old,new))==expected
functions=[];refs=[]
for before in [0x14018E0,0x140F320,0x140ED40,0x14100E0,0x140FF40,0x3AC56A0]:
    fn=old.function(before)
    if before==0x140F320:
        length=next(i.address-old.base-before for i in old.instructions(before,0x240) if i.mnemonic=='int3')
        raw=old.data(before,length);hits=[];at=0
        while (at:=new.text_bytes.find(raw,at))>=0:hits.append(new.text.VirtualAddress+at);at+=1
        assert len(hits)==1
        row=dict(status='unique',newRva=hex(hits[0]),length=length,rawLeafWholeBody=True,
            oldWindowSha256=hashlib.sha256(raw).hexdigest(),newWindowSha256=hashlib.sha256(new.data(hits[0],length)).hexdigest())
    else:
        assert fn and fn[0]==before,(hex(before),fn)
        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 [0x51BB980,0x51BB9B0,0x51BBAB0,0x51BBBA0]:
    matches={r[1] for r in refs if r[0]==before};assert len(matches)==1
    tables[hex(before)]=hex(matches.pop())
slots=[]
for offset,before in [(0,0x140EB70),(0x18,0x140F320),(0x20,0x140ED40),(0x48,0x14100E0),(0x50,0x140FF40)]:
    after=struct.unpack('<Q',new.data(int(tables['0x51bbab0'],16)+offset,8))[0]-new.base
    assert struct.unpack('<Q',old.data(0x51BBAB0+offset,8))[0]-old.base==before
    fn=old.function(before)
    length=0x202 if before==0x140F320 else fn[1]-before if fn and fn[0]==before else next(i.address+i.size-old.base-before for i in old.instructions(before,64) if i.mnemonic=='ret')
    raw,mask,*_=audit.signature(old,before,length);actual=new.data(after,length)
    assert not any(a!=b for a,b,keep in zip(raw,actual,mask) if keep)
    if before==0x140F320:assert old.data(before,length)==actual
    refs+=audit.references(old,new,before,after,length)
    slots.append(dict(oldRva=hex(before),newRva=hex(after),bytes=length,oldVtable='0x51bbab0',newVtable=tables['0x51bbab0'],slot=hex(offset)))
globals_={}
for before in [0x5F05E6C]:
    matches={r[1] for r in refs if r[0]==before};assert len(matches)==1
    globals_[hex(before)]=hex(matches.pop())
result=dict(runtimeNeutral=True,canInstallHooks=False,runtimeValidated=False,gameProcessAccess=False,gameCalls=0,
    oldImageSha256=expected[0],newImageSha256=expected[1],functions=functions,vtables=tables,slots=slots,globals=globals_,
    references=[list(map(hex,r)) for r in refs],fields=dict(interfaceFromOwner=0x58,
        idMaps=[0x80,0xA8,0xC8,0xE8,0x108],legacy32BitMap=0x128,nodeId=8,nodeWeakControl=0x10,nodeDefinition=0x18,
        weakControlStrongCount=0xC,definitionId=0,definitionKey=8,definitionValid=0x18,
        missing='unknown',noneSentinel='18446744073709551615',noneBasis='3AC56A0 explicitly inserts None under u64Max; 140F320 rejects this sentinel'))
path=Path('artifacts/galaxy-query-research/allegiance-definitions/compatibility.json')
path.write_text(json.dumps(result,indent=2)+'\n',encoding='utf8')
print(json.dumps(dict(path=str(path),vtables=tables,slots=slots,globals=globals_),indent=2))