Files
WeirdUtils/docs/HOOK_ADDRESS_FIXES.md
T
MarcelineVQ 2cca8f4b53 Add assetfix, transmogfix, minimapicons modules; fix assetfix disk-vs-MPQ priority
Assetfix: hook CheckFileExistence to serve loose Data\ files. The original
flags|1 approach failed because game paths contain backslashes, causing
CheckFileExistence to skip BuildFilePath and check the raw path (no Data\
prefix). Fix: write the correct Data\-prefixed disk path to the output buffer
directly and return 1, bypassing the original function for hash map hits.
This preserves hook chaining (filename argument is never transformed).

Also adds transmogfix (transmog update coalescing), minimapicons (stub),
new build options for all three modules, mutex-based multi-DLL safety,
embed .skin data into .m2 models, and various module improvements.
2026-02-28 14:07:53 -08:00

4.1 KiB

Hook Address Analysis and Fixes

Date: 2025-12-10 Tool: Ghidra MCP + Code Executor

Critical Address Fixes

❌ ProcessWorldWithFrustum

  • Old Address: 0x00683000 (WRONG - no function at this address)
  • Correct Address: 0x00682fa0
  • Ghidra Signature: undefined __fastcall ProcessWorldWithFrustum(float * frustumBounds)
  • First Byte: 0x57 (PUSH EDI)
  • Stolen Bytes: 9 bytes
  • Status: ✅ FIXED in discovery_hooks.cpp

❌ RenderObjectsWithLOD

  • Old Address: 0x00684600 (WRONG - no function at this address)
  • Correct Address: 0x00684510
  • Ghidra Signature: undefined __stdcall RenderObjectsWithLOD(void)
  • First Byte: 0x55 (PUSH EBP)
  • Stolen Bytes: 8 bytes
  • Status: ✅ FIXED in discovery_hooks.cpp

Verified Correct Addresses

✅ ScenePresent

  • Address: 0x0059a870
  • Ghidra Signature: void __fastcall CGxDeviceD3d::ScenePresent(CGxDeviceD3d * device)
  • First Byte: 0x55 (PUSH EBP)
  • Stolen Bytes: 6 bytes
  • Calling Convention: __fastcall (saves ECX+EDX) ✅ Correct in code

✅ CullAndProcessWorldChunks

  • Address: 0x00683040
  • Ghidra Signature: undefined __stdcall CullAndProcessWorldChunks(void)
  • First Byte: 0x55 (PUSH EBP)
  • Stolen Bytes: 8 bytes
  • Calling Convention: __stdcall (no register saves) ✅ Correct in code

✅ ProcessStaticObjectsCulling

  • Address: 0x00683bf0
  • Ghidra Signature: undefined __fastcall ProcessStaticObjectsCulling(int staticObjectManager)
  • First Byte: 0x55 (PUSH EBP)
  • Stolen Bytes: 9 bytes
  • Calling Convention: __fastcall (saves ECX+EDX) ✅ Correct in code

✅ CM2Scene_DrawModelBatch

  • Address: 0x0070cf70
  • Ghidra Signature: undefined __fastcall CM2Scene_DrawModelBatch(void * renderContext)
  • First Byte: 0x55 (PUSH EBP)
  • Stolen Bytes: 8 bytes
  • Calling Convention: __fastcall (saves ECX+EDX) ✅ Correct in code

Calling Convention Summary

Function Ghidra Convention Code Implementation Status
ScenePresent __fastcall __fastcall (ECX+EDX) ✅ Correct
ProcessWorldWithFrustum __fastcall __fastcall (ECX+EDX) ✅ Correct
CullAndProcessWorldChunks __stdcall __cdecl (no saves) ✅ OK (both no reg saves)
ProcessStaticObjectsCulling __fastcall __fastcall (ECX+EDX) ✅ Correct
RenderObjectsWithLOD __stdcall __cdecl (no saves) ✅ OK (both no reg saves)
CM2Scene_DrawModelBatch __fastcall __fastcall (ECX+EDX) ✅ Correct

Prologue Byte Analysis

All functions follow standard x86 calling conventions:

Common patterns:

  • 0x55 = PUSH EBP (saves base pointer)
  • 0x57 = PUSH EDI (saves EDI register)
  • Followed by MOV EBP, ESP and SUB ESP, n

Stolen byte counts:

  • 6 bytes: Minimal prologue (PUSH EBP + MOV EBP,ESP + SUB ESP,small)
  • 8 bytes: Standard prologue with one register save
  • 9 bytes: Extended prologue with multiple saves or larger stack allocation

Limitations Encountered

The Ghidra MCP get_bytes tool only returns 1 byte regardless of the length parameter. This prevented detailed byte-by-byte prologue verification. However:

  1. Function signatures were verified via get_function_by_address
  2. Decompiled code confirmed function structure
  3. First byte at each address was confirmed
  4. Calling conventions were verified

Recommendations

  1. ✅ Address fixes have been applied to discovery_hooks.cpp
  2. ⚠️ Test the DLL after recompilation to verify hooks work correctly
  3. ⚠️ Monitor for crashes that could indicate incorrect stolen byte counts
  4. If crashes occur after address fix, use Ghidra GUI to manually count instruction bytes in prologues

Next Steps

  1. Rebuild discovery DLL with corrected addresses
  2. Test in WoW to verify hooks execute without crashes
  3. If issues persist, manually verify stolen byte counts in Ghidra GUI using:
    • Right-click function → "Listing: Function"
    • Count bytes of first N instructions until reaching or exceeding stolen byte count
    • Ensure no instruction is partially stolen (causes invalid opcode crashes)