Hook Types
Osiris uses two primary hooking techniques:- Direct Function Pointer Hooking - Replacing function pointers
- VMT Swapping - Replacing virtual method table pointers
Hooks Structure
All hooks are managed in a central structure:peepEventsHook- Entry point for game thread executionviewRenderHook- Rendering callbacksclientModeVmtSwapper- ClientMode virtual methods
PeepEvents Hook
The PeepEvents hook is the primary entry point into the game’s main thread.Implementation
- Locate the
SDL_PeepEventsfunction pointer via pattern scanning - Save the original pointer
- Replace it with
SDLHook_PeepEvents - Call original from the hook
Hook Handler
- Safe initialization on game thread
- Per-frame execution
- Access to game state
ViewRender Hook
The ViewRender hook intercepts rendering to draw overlays and modify rendering behavior.Implementation
Hook Handler
VMT Swapping
Virtual Method Table (VMT) swapping is used to hook virtual functions.VmtSwapper Class
- Calculate VMT length
- Create a copy of the VMT
- Modify entries in the copy
- Swap the object’s VMT pointer to the copy
- Save original for calling and restoration
VmtLengthCalculator
- Validates each VMT entry points to executable code
- Ensures the entry itself is in the VMT section
- Stops at the first invalid entry
- Prevents buffer overruns when copying
Memory Allocation for VMT Copies
VMT copies are allocated from the custom memory allocator:Hook Safety
Thread Safety
Osiris doesn’t create threads, so there are no threading concerns. All hooks execute on game threads.Exception Safety
All hook handlers arenoexcept. Exceptions are disabled globally.
Calling Conventions
Hooks must match the calling convention of hooked functions:- On Linux: System V AMD64 ABI (default for C++)
- On Windows: Microsoft x64 calling convention (default for C++)
Restore on Unload
All hooks are properly restored:Hook Timing
Installation Order
- PeepEvents - Installed during partial context init
- ViewRender - Installed during full context init
- ClientMode - Installed on-demand when needed
Execution Order
Each frame:- Game calls
SDL_PeepEvents - Our
SDLHook_PeepEventsexecutes - We initialize full context (first frame only)
- We process GUI, features, etc.
- We call original
SDL_PeepEvents - Game rendering begins
- Game calls
CViewRender::OnRenderStart - Our
ViewRenderHook_onRenderStartexecutes - We render overlays and effects
- We call original
OnRenderStart - Game continues rendering
Advanced Techniques
Lazy Hook Installation
Some hooks are only installed when needed:- Minimal footprint when features disabled
- Reduces detection surface
- Better performance
Conditional Hook Execution
Pattern-Based Hook Location
All hooks locations are found via pattern scanning:Debugging Hooks
In debug builds:Hook Limitations
What We Don’t Hook
- Inline functions - Inlined code can’t be hooked
- Static functions - Can’t find without pattern scanning each call site
- Optimized out functions - Don’t exist in release builds
- System calls - Kernel-level hooks are too risky
Hook Stability
Hooks may break when:- Game updates change code patterns
- Compiler optimizations change virtual table layouts
- Game refactors hooked classes
- Multiple pattern candidates
- Graceful degradation when hooks fail
- Version-specific pattern sets
Related Topics
- Architecture - Overall system design
- Memory Patterns - Finding hook locations
- Panorama GUI - GUI hooks and integration