# Galaxy native client compatibility audit The current installed executable is a different client build. Local Steam update records, depot file hashes, version resources and PE structure agree on this; the conclusion does not rely on filesystem modification times. At the initial pass, the native plugin was pinned to the old SHA-256. No hash guard, native source hook, game file or running game was changed by this audit. The closure report separately records a later, independent shared-source migration to the new exact hash without attributing or reverting it. The new build has many matching code bodies, but **a single RVA delta cannot migrate the plugin**. A separate reviewed version profile is feasible from the recorded candidates. This report does not approve that profile or claim live compatibility. **Follow-up:** the bounded chain-aware closure pass is now complete for the Galaxy source addresses, registration/handle/CSM basis and the nine initially unmatched research bodies. See `research/galaxy-client-compatibility-closure.md` and the independently verifiable `artifacts/galaxy-client-compatibility/galaxy-mapping.json`. In particular, HeatTick and the seven data addresses listed below as initial gaps are now resolved. The initial pass and its raw `audit.json` are retained to distinguish new evidence from the earlier state. ## Provenance and versions | Item | Pinned copy | Current installed image | | --- | --- | --- | | Product version | 4.4.2.0 | 4.4.2.1 | | File version | 334473 | 334925 | | File length | 103,482,368 | 103,481,344 | | PE build timestamp, UTC | 2026-10-12 21:29:33 | 2026-10-22 21:29:44 | | SHA-256 | `6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93` | `ed5a8f8cd10f9a80d3bda5badd7ba1d4fcfc15996c8c7e018852cb170e264b63` | | Content SHA-1 | `6056fac2c758eee01273459c22873dff447e3055` | `a272a87e3dd64e0818b605ddde5269451170806a` | The local Steam content log records completed installations of BuildID `25906527` on 2026-10-20 and `26155938` on 2026-10-23. On October 23 it explicitly records a download/stage, a commit from the downloading directory to the installed Elite Dangerous directory, 87 updated files, and successful completion at **21:50:25 local time / 13:50:25 UTC**. The retained depot manifests are: - `I:/steam/depotcache/359326_1091597132551610634.manifest` for the old build. - `I:/steam/depotcache/359326_3767724865074145418.manifest` for the new build. Their `Products\\elite-dangerous-odyssey-64\\EliteDangerous64.exe` rows each match the respective actual file's length **and complete content SHA-1**. The current `appmanifest_359320.acf` also identifies BuildID `26155938` and depot manifest `3767724865074145418`. Together these are positive local Steam update provenance evidence. Neither EXE has an Authenticode certificate; this audit does not independently authenticate Steam's cached manifest signature. Account identifiers and download authorization URLs are excluded from the saved evidence. ## PE comparison Both are x64 PE images with the same section RVAs, image base `140000000` and `SizeOfImage=640C000`. Unchanged section starts do **not** imply unchanged symbols within a section. | Property | Old | New | | --- | --- | --- | | Entry-point RVA | `489BC58` | `489BBB8` | | `.text` virtual size | `4DB4AEE` | `4DB498E` | | `.rdata` virtual size | `10AF60C` | `10AF5EC` | | `.data` virtual size | `1F0AA0` | `1F0AA0` | | `.pdata` virtual size | `2E6BA8` | `2E6B3C` | | `.pdata` function ranges | 253,518 | 253,509 | | Certificate directory size | 0 | 0 | Raw section offsets also changed; a file-offset patch or comparison must resolve each image's own RVA-to-file mapping. Full per-section hashes and all header values are in `artifacts/galaxy-client-compatibility/audit.json`. ## Initial bounded matching method and results `research/Audit-GalaxyClientCompatibility.py` reads both files without loading or executing them. It inventories literal/named image RVAs in the current `Navigation*.cs` sources, adds existing galaxy research function starts, and adds bounded constructor/vtable/global-reference witnesses. This source snapshot includes the new original-appearance adapter. Each initial function signature is at most 384 bytes. Encoded RIP references, relative branch targets, absolute virtual addresses and function-local indexed jump-table RVAs are masked; all remaining bytes must match exactly. The new text section is searched for **every** match. Generic getters and short destructors therefore remain ambiguous rather than being assigned the nearest address. Fingerprint/mask SHA-256 values are retained for reproduction. The final recorded pass contains: - **240 source RVAs:** 123 code addresses and 117 data addresses. - **2,142 function seeds:** 1,713 unique byte-signature candidates, 408 ambiguous, 11 insufficient signatures and 10 unmatched signatures. - Among source code RVAs: 106 unique candidates, 15 ambiguous, one insufficient signature and one unmatched signature. - Among source data RVAs: 110 have consistent code/vtable reference candidates, seven remain unresolved. - 64 of 66 examined vtables have a single candidate preserving **every uniquely matched slot** in the bounded table window. - All 68 source symbols that uniquely match at `.pdata` range entries also match their complete original `.pdata` spans after reference normalization. The other 38 unique source symbols are leaf/thunk/interior symbols and are not promoted to full-function checks. A `.pdata` span can be one part of a function with chained/cold unwind ranges. Even a complete normalized span preserves instruction operands, not the semantics of every masked destination. Caller/callee, table and layout review is still required before using it in a native profile. Unique code candidates exhibit **eight** distinct deltas: `0`, `-30`, `-40`, `-60`, `-A0`, `-C0`, `-E0`, and `-120` (hex). Data candidates include `0`, `-30`, and `-40`. These are observed candidate deltas, not a piecewise remap function; boundaries between samples are unproven. ## Useful candidate addresses All values below are RVAs, written in hex. They are review candidates only. | Existing symbol | Old | New candidate | Evidence | | --- | --- | --- | --- | | Flow update hook | `2157520` | `2157460` | Unique normalized span | | Physics update hook | `2E6EA20` | `2E6E960` | Unique normalized span | | Input evaluator hook | `2E4A8E0` | `2E4A820` | Unique normalized span | | FSD update hook | `2C71500` | `2C71440` | Unique normalized span | | Heat input observer | `38137E0` | `3813740` | Unique normalized span | | Body lookup hook | `3CEB400` | `3CEB360` | Unique normalized span | | Galaxy system-object lookup | `3C331E0` | `3C33140` | Unique normalized span | | Galaxy object load/poll | `3C359A0` | `3C35900` | Unique normalized span | | Name-to-address lookup | `3CEE0A0` | `3CEE000` | Unique normalized span | | Galaxy text search | `3CEB7C0` | `3CEB720` | Unique normalized signature | | Generated system name | `3CF14D0` | `3CF1430` | Unique normalized span | | NavRoute route mutation A | `26479C0` | `2647900` | Unique normalized span | | NavRoute route mutation B | `264BDF0` | `264BD30` | Unique normalized span | | NavRoute read getter | `2604E60` | `2604DA0` | Unique normalized span | | Cached local matchmaking mode | `1D53050` | `1D52F90` | Unique normalized signature; remains a lazy initializer and must not be called by the read-only adapter | | Friend/wing marker producer | `3AFF080` | `3AFEFE0` | Unique bounded signature | | System connector renderer | `3AF2E60` | `3AF2DC0` | Unique bounded signature | | System connector producer | `25FED60` | `25FECA0` | Unique bounded signature | The HeatTick observer at old `3814540` is only a six-byte wrapper with 28 identical matches. Its plausible nearby `38144A0` is **not** an independently resolved hook target. That target needs a verified owner/vtable/caller witness. Several short source functions have a single additional contextual candidate without a unique intrinsic signature. Examples include original allocation leaf `541CD0 -> 541C70`, release `3C44980 -> 3C448E0`, and pose-type getter `8AE6F0 -> 8AE690`. The JSON keeps these in a separate `contextualFunctionCandidates` collection rather than claiming unique matches. The radius getter `3CF04B0` fails the automatic signature because its `.pdata` span includes an inline switch table with absolute image-relative entries. Manual candidate `3CF0410` has the same 217-byte range length and matches after rebasing its four local table RVAs and encoded references. `radius-getter-manual-triage.json` records every such field and zero remaining differences. This is explicit manual triage, not an automatic hook approval. ## Initial review list, with closure tracked separately 1. Revalidate all hook calling conventions, original trampoline/relocation behavior, observer argument registers and owning-thread assumptions. Resolve HeatTick using original context rather than a nearby repeated byte sequence. 2. Verify constructor/interface offsets, vtable order and interface adjustments for Galaxy, Names, NavRoute, registry, input, ship life and FSD. Candidate address equality does not establish lifetime or ownership invariants. 3. Independently check copied account cache layouts: friends published `+220` map; wing slots and local-user gate; cached mode/CSM; bookmarks; visited; exploration/trade; colonisation; power options; appearance palette trees. Keep uninitialised or unresponsive data unknown during that verification. 4. Review unmatched research bodies `1387A80`, `1388680`, `1399990`, `2175ED0`, `3B16B00`, `3B32DD0`, `3C3A1A4`, `3C3F440`, `3C3F5A0`. An unmatched signature can reflect changed logic or embedded address data; it is not evidence that a simple delta is safe. 5. Resolve remaining source data addresses `51DAF4C`, `52406A0`, `5324DA8`, `5324DAC`, `5FDF490`, `5FDF494`, `5FDF498`. The latter three are current appearance globals. Do not infer them solely from neighboring globals. 6. Keep separate exact-hash profiles; run isolated native fixtures for the new profile, then obtain actual read-only runtime evidence when the user next runs that client. This offline audit did not start the game or establish new-version live query coverage. The offline renderer, filters and deterministic test fixtures can continue using verified pinned data while the new profile is reviewed. There is no reason to disable the version guard to continue that work. ## Reproduction The script requires `pefile` and `capstone`; the configured reverse-tool venv already supplies them. Example from the repository root: ```powershell & 'C:/Users/XFEstudio/Desktop/work/AI/skill/game-client-to-server-reverse/.venv/Scripts/python.exe' -X utf8 research/Audit-GalaxyClientCompatibility.py ``` The generated JSON contains local source paths, static code fingerprints, sanitized completed-update log lines, matching depot hashes, vtable slot evidence and unresolved symbols. It contains no account names, user IDs or download authorization tokens. No game build or application build is needed.