From 79b45e40f847ef51779e603f6401cf1e87f03a4d Mon Sep 17 00:00:00 2001 From: Jacob Babor Date: Fri, 19 Jun 2026 23:20:15 -0500 Subject: [PATCH] Probe mappin route slots --- red4ext/EdgeWeightGPS/src/Main.cpp | 126 +++++++++++++++++++++++++++-- 1 file changed, 121 insertions(+), 5 deletions(-) diff --git a/red4ext/EdgeWeightGPS/src/Main.cpp b/red4ext/EdgeWeightGPS/src/Main.cpp index 1ab8085..9f69316 100644 --- a/red4ext/EdgeWeightGPS/src/Main.cpp +++ b/red4ext/EdgeWeightGPS/src/Main.cpp @@ -97,6 +97,9 @@ constexpr uintptr_t kTrackMappinCoreRva = 0x27C11D0; constexpr uintptr_t kSetMappinTrackingAlternativeWrapperRva = 0x1246794; constexpr uintptr_t kMappinSetTrackedSlotOffset = 0x220; constexpr uintptr_t kMappinClearTrackedSlotOffset = 0x228; +constexpr uintptr_t kMappinPositionQuerySlotOffset = 0x2E0; +constexpr uintptr_t kMappinReleaseQuerySlotOffset = 0x368; +constexpr uintptr_t kMappinActiveRouteSlotOffset = 0x3A8; HMODULE gModule = nullptr; std::mutex gLogMutex; @@ -111,10 +114,16 @@ uint32_t gSetMappinTrackingAlternativeLogCount = 0; uint32_t gMappinSystemSlotLogCount = 0; uint32_t gMappinSetTrackedLogCount = 0; uint32_t gMappinClearTrackedLogCount = 0; +uint32_t gMappinPositionQueryLogCount = 0; +uint32_t gMappinReleaseQueryLogCount = 0; +uint32_t gMappinActiveRouteLogCount = 0; uint64_t gLogStartTick = 0; uint64_t gLogFrequency = 0; void* gMappinSetTrackedTarget = nullptr; void* gMappinClearTrackedTarget = nullptr; +void* gMappinPositionQueryTarget = nullptr; +void* gMappinReleaseQueryTarget = nullptr; +void* gMappinActiveRouteTarget = nullptr; bool gMappinSlotHookAttachAttempted = false; using ProbeFunc = void (*)(void* aThis, void* a2, void* a3, void* a4); @@ -123,12 +132,18 @@ using MappinSystemResolverFunc = void* (*)(void* aThis); using TrackMappinCoreFunc = void (*)(void* aThis, void* aMappinHandle); using MappinSetTrackedFunc = void (*)(void* aSystem, void* aMappinId); using MappinClearTrackedFunc = void (*)(void* aSystem); +using MappinPositionQueryFunc = void* (*)(void* aSystem, void* a2, void* a3, void* a4, void* a5); +using MappinReleaseQueryFunc = void (*)(void* aSystem, void* aHandle); +using MappinActiveRouteFunc = void* (*)(void* aSystem); ProbeFunc gOriginalGpsSystemTick = nullptr; ScriptNativeVoidFunc gOriginalTrackMappinWrapper = nullptr; TrackMappinCoreFunc gOriginalTrackMappinCore = nullptr; ScriptNativeVoidFunc gOriginalSetMappinTrackingAlternativeWrapper = nullptr; MappinSetTrackedFunc gOriginalMappinSetTracked = nullptr; MappinClearTrackedFunc gOriginalMappinClearTracked = nullptr; +MappinPositionQueryFunc gOriginalMappinPositionQuery = nullptr; +MappinReleaseQueryFunc gOriginalMappinReleaseQuery = nullptr; +MappinActiveRouteFunc gOriginalMappinActiveRoute = nullptr; std::filesystem::path GetLogPath() { @@ -278,12 +293,12 @@ void LogMappinSystemSlots(uint32_t aCount, void* aSystem, void* aVtable) line << "mappin-system slots call=" << aCount; AppendPointerWithRva(line, "system", aSystem); AppendPointerWithRva(line, "vtable", aVtable); - AppendPointerWithRva(line, "slot220", readSlot(0x220)); - AppendPointerWithRva(line, "slot228", readSlot(0x228)); + AppendPointerWithRva(line, "slot220", readSlot(kMappinSetTrackedSlotOffset)); + AppendPointerWithRva(line, "slot228", readSlot(kMappinClearTrackedSlotOffset)); AppendPointerWithRva(line, "slot250", readSlot(0x250)); - AppendPointerWithRva(line, "slot2e0", readSlot(0x2E0)); - AppendPointerWithRva(line, "slot368", readSlot(0x368)); - AppendPointerWithRva(line, "slot3a8", readSlot(0x3A8)); + AppendPointerWithRva(line, "slot2e0", readSlot(kMappinPositionQuerySlotOffset)); + AppendPointerWithRva(line, "slot368", readSlot(kMappinReleaseQuerySlotOffset)); + AppendPointerWithRva(line, "slot3a8", readSlot(kMappinActiveRouteSlotOffset)); LogRed4ext(line.str()); } @@ -543,6 +558,89 @@ void DetourMappinClearTracked(void* aSystem) } } +void* DetourMappinPositionQuery(void* aSystem, void* a2, void* a3, void* a4, void* a5) +{ + const auto shouldLog = gMappinPositionQueryLogCount < 32; + if (shouldLog) + { + std::ostringstream line; + line << "hook MappinSystem::PositionQuery slot2e0 call=" << gMappinPositionQueryLogCount; + AppendPointerWithRva(line, "system", aSystem); + AppendPointerWithRva(line, "a2", a2); + AppendPointerWithRva(line, "a3", a3); + AppendPointerWithRva(line, "a4", a4); + AppendPointerWithRva(line, "a5", a5); + AppendReturnRva(line, __builtin_return_address(0)); + LogRed4ext(line.str()); + ++gMappinPositionQueryLogCount; + } + + void* result = nullptr; + if (gOriginalMappinPositionQuery) + { + result = gOriginalMappinPositionQuery(aSystem, a2, a3, a4, a5); + } + + if (shouldLog) + { + std::ostringstream line; + line << "hook MappinSystem::PositionQuery slot2e0 result"; + AppendPointerWithRva(line, "value", result); + LogRed4ext(line.str()); + } + + return result; +} + +void DetourMappinReleaseQuery(void* aSystem, void* aHandle) +{ + if (gMappinReleaseQueryLogCount < 32) + { + std::ostringstream line; + line << "hook MappinSystem::ReleaseQuery slot368 call=" << gMappinReleaseQueryLogCount; + AppendPointerWithRva(line, "system", aSystem); + AppendPointerWithRva(line, "handle", aHandle); + AppendReturnRva(line, __builtin_return_address(0)); + LogRed4ext(line.str()); + ++gMappinReleaseQueryLogCount; + } + + if (gOriginalMappinReleaseQuery) + { + gOriginalMappinReleaseQuery(aSystem, aHandle); + } +} + +void* DetourMappinActiveRoute(void* aSystem) +{ + const auto shouldLog = gMappinActiveRouteLogCount < 32; + if (shouldLog) + { + std::ostringstream line; + line << "hook MappinSystem::ActiveRoute slot3a8 call=" << gMappinActiveRouteLogCount; + AppendPointerWithRva(line, "system", aSystem); + AppendReturnRva(line, __builtin_return_address(0)); + LogRed4ext(line.str()); + ++gMappinActiveRouteLogCount; + } + + void* result = nullptr; + if (gOriginalMappinActiveRoute) + { + result = gOriginalMappinActiveRoute(aSystem); + } + + if (shouldLog) + { + std::ostringstream line; + line << "hook MappinSystem::ActiveRoute slot3a8 result"; + AppendPointerWithRva(line, "value", result); + LogRed4ext(line.str()); + } + + return result; +} + void AttachProbeHook(const char* aName, uintptr_t aRva, void* aDetour, void** aOriginal) { if (!gSdk || !gSdk->hooking || !gSdk->hooking->Attach) @@ -639,6 +737,12 @@ void InspectAndHookMappinSystem(void* aThis) *reinterpret_cast(reinterpret_cast(vtable) + kMappinSetTrackedSlotOffset); gMappinClearTrackedTarget = *reinterpret_cast(reinterpret_cast(vtable) + kMappinClearTrackedSlotOffset); + gMappinPositionQueryTarget = + *reinterpret_cast(reinterpret_cast(vtable) + kMappinPositionQuerySlotOffset); + gMappinReleaseQueryTarget = + *reinterpret_cast(reinterpret_cast(vtable) + kMappinReleaseQuerySlotOffset); + gMappinActiveRouteTarget = + *reinterpret_cast(reinterpret_cast(vtable) + kMappinActiveRouteSlotOffset); AttachAbsoluteHook("MappinSystem::SetTracked slot220", gMappinSetTrackedTarget, reinterpret_cast(&DetourMappinSetTracked), @@ -646,6 +750,15 @@ void InspectAndHookMappinSystem(void* aThis) AttachAbsoluteHook("MappinSystem::ClearTracked slot228", gMappinClearTrackedTarget, reinterpret_cast(&DetourMappinClearTracked), reinterpret_cast(&gOriginalMappinClearTracked)); + AttachAbsoluteHook("MappinSystem::PositionQuery slot2e0", gMappinPositionQueryTarget, + reinterpret_cast(&DetourMappinPositionQuery), + reinterpret_cast(&gOriginalMappinPositionQuery)); + AttachAbsoluteHook("MappinSystem::ReleaseQuery slot368", gMappinReleaseQueryTarget, + reinterpret_cast(&DetourMappinReleaseQuery), + reinterpret_cast(&gOriginalMappinReleaseQuery)); + AttachAbsoluteHook("MappinSystem::ActiveRoute slot3a8", gMappinActiveRouteTarget, + reinterpret_cast(&DetourMappinActiveRoute), + reinterpret_cast(&gOriginalMappinActiveRoute)); } bool OnRunningEnter(void* aApp) @@ -739,6 +852,9 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e DetachProbeHook("SetMappinTrackingAlternativeWrapper", kSetMappinTrackingAlternativeWrapperRva); DetachAbsoluteHook("MappinSystem::SetTracked slot220", gMappinSetTrackedTarget); DetachAbsoluteHook("MappinSystem::ClearTracked slot228", gMappinClearTrackedTarget); + DetachAbsoluteHook("MappinSystem::PositionQuery slot2e0", gMappinPositionQueryTarget); + DetachAbsoluteHook("MappinSystem::ReleaseQuery slot368", gMappinReleaseQueryTarget); + DetachAbsoluteHook("MappinSystem::ActiveRoute slot3a8", gMappinActiveRouteTarget); } return true;