From 1bd50662b163872945a8496cdd7200936ce334b3 Mon Sep 17 00:00:00 2001 From: Valentin Popov Date: Sat, 18 Jul 2026 13:49:15 +0400 Subject: [PATCH] docs(evidence): confirm live camera global relocation --- docs/tomes/05-render.md | 22 +++++++++++++++++----- docs/tomes/08-evidence.md | 10 ++++++++++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/docs/tomes/05-render.md b/docs/tomes/05-render.md index 15274cf..7019c24 100644 --- a/docs/tomes/05-render.md +++ b/docs/tomes/05-render.md @@ -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 A further headless-IDA review of the same GOG `Terrain.dll` identifies a -concrete `CBufferingCamera` implementation path without requiring a live game -process. Its method at RVA `0x4D740` copies exactly 64 bytes (16 dwords) into -the component at offset `+0x10`. Its frame-preparation method at RVA `0x4D9C0` -queries a viewport rectangle through a virtual method at `+0x3C`, derives its +`CBufferingCamera`-related implementation path without requiring a live game +process. The procedure at RVA `0x4D740` copies exactly 64 bytes (16 dwords) +into its receiver at offset `+0x10`. The frame-preparation procedure at RVA +`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 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 `+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 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 window titled `Parkan. Железная Стратегия`. A read-only probe then requested `PROCESS_QUERY_INFORMATION | PROCESS_VM_READ` and attempted to read the known diff --git a/docs/tomes/08-evidence.md b/docs/tomes/08-evidence.md index d4555d2..9016efc 100644 --- a/docs/tomes/08-evidence.md +++ b/docs/tomes/08-evidence.md @@ -268,6 +268,16 @@ near/far mapping, handedness или initial camera selection. Важно, что `ICamera::GetTransformMatrix` (RVA `0x4F850`) ведут только в obsolete-call 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` — это шестибайтный getter по RVA `0x4FD80`, который возвращает `dword` по RVA `0x7355C`. Единственный найденный initializer этого global — функция Terrain