docs(evidence): confirm live camera global relocation

This commit is contained in:
2026-07-18 13:49:15 +04:00
parent 4ea4be8cad
commit 1bd50662b1
2 changed files with 27 additions and 5 deletions
+17 -5
View File
@@ -1261,13 +1261,13 @@ matrix convention; they must not be treated as a usable renderer ABI yet.
### Buffering-camera projection path from static Terrain analysis ### Buffering-camera projection path from static Terrain analysis
A further headless-IDA review of the same GOG `Terrain.dll` identifies a A further headless-IDA review of the same GOG `Terrain.dll` identifies a
concrete `CBufferingCamera` implementation path without requiring a live game `CBufferingCamera`-related implementation path without requiring a live game
process. Its method at RVA `0x4D740` copies exactly 64 bytes (16 dwords) into process. The procedure at RVA `0x4D740` copies exactly 64 bytes (16 dwords)
the component at offset `+0x10`. Its frame-preparation method at RVA `0x4D9C0` into its receiver at offset `+0x10`. The frame-preparation procedure at RVA
queries a viewport rectangle through a virtual method at `+0x3C`, derives its `0x4D9C0` queries a viewport rectangle through a virtual method at `+0x3C`, derives its
width, height, centre and an aspect ratio from that rectangle, and obtains width, height, centre and an aspect ratio from that rectangle, and obtains
projection data through the camera interface. Projection type `0` uses a projection data through the camera interface. Projection type `0` uses a
component float at offset `+0x234` as an angle passed to `tan(angle / 2)`; receiver float at offset `+0x234` as an angle passed to `tan(angle / 2)`;
projection type `2` obtains a five-float block through a virtual method at projection type `2` obtains a five-float block through a virtual method at
`+0x70`. Any other non-zero type raises `Not supported projection type`. `+0x70`. Any other non-zero type raises `Not supported projection type`.
@@ -1279,6 +1279,18 @@ string-labelled `ICamera::SetTransformMatrix` (RVA `0x4F830`) and
`ICamera::GetTransformMatrix` (RVA `0x4F850`) are both obsolete-call stubs, so `ICamera::GetTransformMatrix` (RVA `0x4F850`) are both obsolete-call stubs, so
they are not a usable method ABI. they are not a usable method ABI.
Live read-only evidence now confirms the relocation-aware global contract. In
one elevated GOG run, `Terrain.dll` loaded at `0x02510000`; its global at
`base + 0x7355C` held non-null `0x0B37DF08`, whose first dword was
`0x025765B4` — exactly the relocated `off_100665B4` vtable from the
`LoadCamera` construction path. This proves the global is a live camera object
with that outer vtable. It also corrects an overreach: raw reads at global
offsets `+0x10` and `+0x234` did not yield a finite 4×4 matrix and a projection
angle in this sample. The static procedures' receiver and the exported global
pointer are therefore not yet proven to have the same adjustment/layout; those
offsets must remain unassigned until the selector/interface relationship is
recovered.
A fresh no-input launch of the canonical `iron_3d.exe` did create a responsive A fresh no-input launch of the canonical `iron_3d.exe` did create a responsive
window titled `Parkan. Железная Стратегия`. A read-only probe then requested window titled `Parkan. Железная Стратегия`. A read-only probe then requested
`PROCESS_QUERY_INFORMATION | PROCESS_VM_READ` and attempted to read the known `PROCESS_QUERY_INFORMATION | PROCESS_VM_READ` and attempted to read the known
+10
View File
@@ -268,6 +268,16 @@ near/far mapping, handedness или initial camera selection. Важно, что
`ICamera::GetTransformMatrix` (RVA `0x4F850`) ведут только в obsolete-call `ICamera::GetTransformMatrix` (RVA `0x4F850`) ведут только в obsolete-call
stubs и не дают usable ABI. stubs и не дают usable ABI.
Live elevated read-only probe впервые подтвердил relocation-aware runtime связь:
`Terrain.dll` был загружен по `0x02510000`, global `base + 0x7355C` содержал
non-null `0x0B37DF08`, а первый dword этого объекта был `0x025765B4` — ровно
relocated `off_100665B4` из `LoadCamera` construction path. Это доказывает
live camera object с outer vtable, но одновременно исправляет прежнее слишком
сильное сопоставление offsets: raw read `global + 0x10` не дал finite 4x4 matrix,
а `+0x234` был zero в данном sample. Receiver static procedures `0x4D740`/
`0x4D9C0` и exported global ещё не доказаны как один layout без interface
adjustment; их offsets остаются unassigned до recovery selector relationship.
Локальная IDA-база уточняет адреса этой связи: `stdGetCurrentCamera2` — это Локальная IDA-база уточняет адреса этой связи: `stdGetCurrentCamera2` — это
шестибайтный getter по RVA `0x4FD80`, который возвращает `dword` по RVA шестибайтный getter по RVA `0x4FD80`, который возвращает `dword` по RVA
`0x7355C`. Единственный найденный initializer этого global — функция Terrain `0x7355C`. Единственный найденный initializer этого global — функция Terrain