Skip to content

aowlspt_prologue.h

Source: abi/aowlspt_prologue.h — 330 lines, 18 file-scope functions.

What this header owns

Reproduced verbatim from the header's own banner comment — these notes are frequently the only written record of why the subsystem is shaped the way it is.

text
 aowlspt_prologue.h -- ORIGINAL prologue bytes, snapshotted once, before any
detour is installed.

THE BUG THIS EXISTS TO KILL
--------------------------
Every feature in this host verifies its target by comparing 16 prologue
bytes against a signature baked in from the decrypted metadata. That check
is a real safety property -- it is what makes a stale RVA on a different
game build a silent no-op instead of a jump into the middle of an unrelated
function -- and it must keep holding.

But it was reading LIVE memory at bind time. As soon as two features share a
target, that is wrong: the first binder writes its jump over the very bytes
the second binder is about to compare. The second reads the trampoline,
sees a mismatch, and rejects a target that is perfectly correct.

Observed live, twice, on two builds: with `debugUi` and `uxMenuModeText`
both on, the overlay armed and then

    menu mode text: PreloaderUI.Update did not verify on this build
                    (0 target(s) verified, 1 rejected); nothing bound

and the corner label stayed "PVE ZONE". Nothing was wrong with the RVA, the
signature, or the multiplex -- only with WHEN the bytes were read.

This is a whole CLASS of bug, not one feature's mistake: any feature that
prologue-verifies a function another feature already patched will
self-reject, and it will do it with a message that blames the game build.

THE FIX
-------
One RVA-keyed table of original prologue bytes, captured BEFORE anything is
patched, and every later verify compares against the SNAPSHOT rather than
against live memory. The signature check is not weakened in any way -- it is
still an exact 16-byte compare against the baked-in expectation. It is only
fed the bytes the function actually started with.

Capture happens two ways, and both matter:

  * EAGERLY, from `aowl_pro_prime_all` at host startup, before any bind
    runs. This is the real guarantee and the reason the whole class is
    fixed rather than one instance of it.
  * LAZILY, on the first verify of an RVA that has not been primed. This is
    the belt-and-braces path for a target added later whose RVA nobody
    remembered to add to the priming list. It is only correct because the
    FIRST verify of a target still necessarily precedes that target's first
    patch -- a feature cannot patch what it has not yet verified.

A snapshot is written EXACTLY ONCE per RVA and never updated. That is the
entire point: a second capture attempt after a detour landed would record
the trampoline and re-introduce the bug this file removes.

SAFETY
------
Capture is subject to the same discipline as the compare it replaces:
`VirtualQuery` first, insist on MEM_COMMIT and an executable protection,
and only then read. A capture that cannot satisfy that records nothing and
leaves the RVA unprimed, so the verify fails closed (refuses the target)
rather than comparing against a zeroed row.

Constants

  • AOWLSPT_PROLOGUE_H
  • AOWL_PRO_MAX_BYTES
  • AOWL_PRO_MAX_DROPPED
  • AOWL_PRO_MAX_ROWS
  • AOWL_PRO_R_MISMATCH
  • AOWL_PRO_R_NO_MODULE
  • AOWL_PRO_R_OK
  • AOWL_PRO_R_SHORT
  • AOWL_PRO_R_TABLE_FULL
  • AOWL_PRO_R_UNREADABLE

Functions

SignatureLine
AowlProRow aowl_pro_find(uint32_t rva)146
AowlProRow aowl_pro_capture(uint32_t rva)158
int32_t aowl_pro_prime(uint32_t rva)198
int32_t aowl_pro_verify(uint32_t rva, const unsigned char* sig, int32_t siglen)215
int32_t aowl_pro_last_reason(void)238
int32_t aowl_pro_last_was_table_full(void)242
char aowl_pro_reason_text(int32_t code)246
char aowl_pro_last_reason_text(void)260
int32_t aowl_pro_have(uint32_t rva)266
int32_t aowl_pro_rows_used(void)272
int32_t aowl_pro_primed_count(void)273
int32_t aowl_pro_lazy_count(void)274
int32_t aowl_pro_full_count(void)275
int32_t aowl_pro_bad_count(void)276
int32_t aowl_pro_capacity(void)277
int32_t aowl_pro_dropped_count(void)278
uint32_t aowl_pro_dropped_at(int32_t i)279
char aowl_pro_health_line(void)293

aoughwl — self-hosted platform for things n stuff. Contact / Support on Discord for access to the private backends.