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

XFEEDToolBox

【WinUI】XFE精英危险工具箱

公开
关注 0 Fork 0 Star 0
UTF-8
"""Actual typed-slot/callee bindings for read-only original NavRoute membership."""
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'))
hashes=[hashlib.sha256(im.raw).hexdigest() for im in (old,new)]
if hashes!=['6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93',
            'ed5a8f8cd10f9a80d3bda5badd7ba1d4fcfc15996c8c7e018852cb170e264b63']:
    raise ValueError('NavRoute proof image changed')
slots=[]
for a,b,slot,before,after in [(0x529E328,0x529E2F8,0x110,0x26174B0,0x26173F0),
                            (0x552A9E8,0x552A9B8,0x40,0x15DB9A0,0x15DB8C0)]:
    if [struct.unpack('<Q',im.data(vt+slot,8))[0]-im.base for im,vt in ((old,a),(new,b))]!=[before,after]:
        raise ValueError('Actual NavRoute typed slot changed')
    span=old.function(before);length=span[1]-before if span and span[0]==before else 7
    raw,mask,*_=audit.signature(old,before,length)
    if any(x!=y for x,y,keep in zip(raw,new.data(after,len(raw)),mask) if keep):raise ValueError('Typed NavRoute body changed')
    slots.append(dict(oldVtable=hex(a),newVtable=hex(b),slot=hex(slot),oldRva=hex(before),newRva=hex(after),bytes=length))
if old.data(0x15DB9A0,7)!=bytes.fromhex('8b8168010000c3') or new.data(0x15DB8C0,7)!=old.data(0x15DB9A0,7):
    raise ValueError('Actual NavRoute mode getter is not a pure component+168 copy')

wrapper=audit.match(old,new,0x26174B0,slots[0]['bytes'])
if wrapper['status']!='unique' or wrapper['newRva']!='0x26173f0':raise ValueError('NavRoute wrapper is not uniquely bound')
wrapper['oldRva']='0x26174b0'
calls=[]
for im,start,target in [(old,0x26174B0,0x63BD80),(new,0x26173F0,0x63BD20)]:
    actual=[ins for ins in im.instructions(start,slots[0]['bytes']) if ins.mnemonic=='call' and ins.operands[0].type==audit.X86_OP_IMM]
    if len(actual)!=1 or actual[0].operands[0].imm-im.base!=target:raise ValueError('Actual NavRoute set callee changed')
    calls.append(hex(actual[0].address-im.base))
decoded=old.instructions(0x63BD80,512);boundary=next(i for i,x in enumerate(decoded) if x.mnemonic=='int3')
if decoded[boundary-1].mnemonic!='ret':raise ValueError('Set membership leaf boundary changed')
length=decoded[boundary].address-old.base-0x63BD80;raw=old.data(0x63BD80,length)
if raw!=new.data(0x63BD20,length):raise ValueError('Complete set membership leaf differs')
leaf=dict(oldRva='0x63bd80',newRva='0x63bd20',status='unique',length=length,rawLeafWholeBody=True,
          oldWindowSha256=hashlib.sha256(raw).hexdigest(),newWindowSha256=hashlib.sha256(raw).hexdigest(),
          binding='Actual typed wrapper direct call, not a guessed image delta')
references=audit.references(old,new,0x26174B0,0x26173F0,slots[0]['bytes'])
result=dict(runtimeNeutral=True,runtimeValidated=False,canInstallHooks=False,gameCalls=0,
    oldImageSha256=hashes[0],newImageSha256=hashes[1],functions=[wrapper,leaf],slots=slots,
    callBinding=dict(oldCall=calls[0],newCall=calls[1],oldCallee='0x63bd80',newCallee='0x63bd20'),
    references=[list(map(hex,r)) for r in references],
    tableIdentity='Both vtables already independently paired in the main ledger; these are their actual getter slots.',
    limitations=['Only static source identity; no original getter is invoked and this is not runtime hook approval.'])
path=Path('artifacts/galaxy-query-research/navroute-membership/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(result['functions']),slots=slots),indent=2))