Skip to content

aowlspt_iat.h

Source: abi/aowlspt_iat.h — 162 lines, 5 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_iat.h — replacing what one module calls, without touching the code.

Two things this project has to do inside the game happen before anything
else can run: answering BSG's BattlEye service check
(`aowlspt_beguard.h`), and finding out when IL2CPP is actually initialised
(`aowlspt_il2cppready.h`). Both run in the DLL constructor, under the loader
lock, before the game's main thread has executed an instruction -- and both
want to change what one specific module calls, not what the process calls.

An import address table is the right instrument for that, and it is the only
one available in that position.

**It is scoped to one module.** Detouring `QueryServiceStatusEx` or
`GetProcAddress` themselves would change the answer for every caller in the
process, including our own mods and the CRT. Rewriting one pointer in
`UnityPlayer.dll`'s IAT changes it for `UnityPlayer.dll` and nothing else.

**It does not involve the loader.** `GetProcAddress` is not safe under the
loader lock: on modern Windows many exports are *forwarders*
(advapi32's `QueryServiceStatusEx` forwards to sechost.dll), and resolving
one can make the loader map a module while we hold its lock. Reading the PE
headers of a module that is already mapped, and writing a pointer through
`VirtualProtect`, involves the loader not at all.

**It does not involve the detour engine.** `aowlspt_detour.h` writes
instructions, parks threads and allocates trampolines, none of which belongs
in a constructor. It is the right tool the moment there is a running game;
it is the wrong tool before there is one.

The cost of the scoping is that this only catches calls a module makes
*through its import table*. A module that resolves a function by
`GetProcAddress` at runtime is unaffected -- which is exactly why
`aowlspt_il2cppready.h` patches `GetProcAddress` itself and watches what is
asked for, rather than trying to patch `il2cpp_init`, which UnityPlayer
looks up dynamically and never imports.

Constants

  • AOWLSPT_IAT_H

Types

  • struct AowlIatPatch

Functions

SignatureLine
int aowl_iat_eq_ci(const char* s, const char* lit)57
wchar_t aowl_iat_basename_w(const wchar_t* p)70
int aowl_iat_eq_ci_w(const wchar_t* s, const wchar_t* lit)78
int aowl_iat_swap(void** slot, void* repl, void** original)93
int aowl_iat_patch(HMODULE mod, const AowlIatPatch* patches, int n, int* looked)115

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