Track GPS query status lifecycle

This commit is contained in:
2026-06-20 13:00:35 -05:00
parent 50c81b780a
commit 751e2175f7
2 changed files with 283 additions and 79 deletions
+257 -76
View File
@@ -92,6 +92,9 @@ struct Sdk
namespace
{
constexpr uint32_t kGameStateRunning = 2;
constexpr bool kEnableVerboseJournalListenerHooks = false;
constexpr bool kEnableVerboseRouteObserverHooks = false;
constexpr bool kEnableVerboseMappinRouteState = false;
constexpr uintptr_t kGpsSystemTickRva = 0x0E6B62C;
constexpr uintptr_t kJournalTrackEntryImplRva = 0x05944FC;
constexpr uintptr_t kJournalListenerArrayOffset = 0x210;
@@ -146,6 +149,7 @@ constexpr uintptr_t kUpdateGpsQueryBodyRva = 0x29BD254;
constexpr uintptr_t kGpsQuerySubmitRva = 0x070A42C;
constexpr uintptr_t kGpsQueryDispatchRva = 0x070A570;
constexpr uintptr_t kGpsQueryResultFetchRva = 0x07094B8;
constexpr uintptr_t kGpsQueryStatusRva = 0x0AA5704;
HMODULE gModule = nullptr;
std::mutex gLogMutex;
@@ -205,6 +209,7 @@ uint32_t gUpdateGpsQueryBodyLogCount = 0;
uint32_t gGpsQuerySubmitLogCount = 0;
uint32_t gGpsQueryDispatchLogCount = 0;
uint32_t gGpsQueryResultFetchLogCount = 0;
uint32_t gGpsQueryStatusLogCount = 0;
uint64_t gLogStartTick = 0;
uint64_t gLogFrequency = 0;
void* gMappinSetTrackedTarget = nullptr;
@@ -219,6 +224,21 @@ void* gObserver1ServiceRouteLookupTarget = nullptr;
bool gMappinSlotHookAttachAttempted = false;
bool gObserver1ServiceRouteLookupHookAttachAttempted = false;
struct TrackedGpsQuery
{
bool active = false;
uint32_t id = 0;
void* manager = nullptr;
uintptr_t submitReturnRva = 0;
uint32_t submitCall = 0;
uint32_t resultFetchCalls = 0;
uint32_t statusCalls = 0;
};
std::mutex gTrackedGpsQueryMutex;
std::array<TrackedGpsQuery, 32> gTrackedGpsQueries{};
uint32_t gTrackedGpsQueryNext = 0;
using ProbeFunc = void (*)(void* aThis, void* a2, void* a3, void* a4);
using JournalTrackEntryFunc = void (*)(void* aThis, void* aEntryHandle);
using ScriptNativeVoidFunc = void (*)(void* aThis, void* aStack, void* aResult);
@@ -253,6 +273,7 @@ using UpdateGpsQueryBodyFunc = bool (*)(void* aThis, uint32_t aQueryId, void* aO
using GpsQuerySubmitFunc = int32_t (*)(void* aManager, void* aQuery);
using GpsQueryDispatchFunc = void (*)(void* aRuntimeQuery, void* aTargetPosition, void* aArg3, void* aArg4);
using GpsQueryResultFetchFunc = bool (*)(void* aManager, uint32_t aQueryId, void* aOutPath);
using GpsQueryStatusFunc = int32_t (*)(void* aManager, uint32_t aQueryId);
ProbeFunc gOriginalGpsSystemTick = nullptr;
JournalTrackEntryFunc gOriginalJournalTrackEntry = nullptr;
ScriptNativeVoidFunc gOriginalFrameMappinPathWrapper = nullptr;
@@ -303,6 +324,7 @@ UpdateGpsQueryBodyFunc gOriginalUpdateGpsQueryBody = nullptr;
GpsQuerySubmitFunc gOriginalGpsQuerySubmit = nullptr;
GpsQueryDispatchFunc gOriginalGpsQueryDispatch = nullptr;
GpsQueryResultFetchFunc gOriginalGpsQueryResultFetch = nullptr;
GpsQueryStatusFunc gOriginalGpsQueryStatus = nullptr;
std::filesystem::path GetLogPath()
{
@@ -390,6 +412,17 @@ bool IsInImage(const void* aPointer)
return imageBase && imageEnd && address >= imageBase && address < imageEnd;
}
bool TryGetImageRva(const void* aPointer, uintptr_t& aRva)
{
if (!IsInImage(aPointer))
{
return false;
}
aRva = reinterpret_cast<uintptr_t>(aPointer) - GetImageBase();
return true;
}
void AppendPointerWithRva(std::ostringstream& aLine, const char* aLabel, const void* aPointer)
{
aLine << " " << aLabel << "=" << aPointer;
@@ -710,6 +743,81 @@ void AppendPathBufferSummary(std::ostringstream& aLine, const char* aPrefix, voi
}
}
void TrackGpsQuery(uint32_t aQueryId, void* aManager, uintptr_t aSubmitReturnRva, uint32_t aSubmitCall)
{
if (aQueryId == UINT32_MAX)
{
return;
}
std::lock_guard lock(gTrackedGpsQueryMutex);
for (auto& query : gTrackedGpsQueries)
{
if (query.active && query.id == aQueryId && query.manager == aManager)
{
query.submitReturnRva = aSubmitReturnRva;
query.submitCall = aSubmitCall;
return;
}
}
auto& query = gTrackedGpsQueries[gTrackedGpsQueryNext++ % gTrackedGpsQueries.size()];
query.active = true;
query.id = aQueryId;
query.manager = aManager;
query.submitReturnRva = aSubmitReturnRva;
query.submitCall = aSubmitCall;
query.resultFetchCalls = 0;
query.statusCalls = 0;
}
bool NoteTrackedGpsQueryResultFetch(uint32_t aQueryId, void* aManager, TrackedGpsQuery& aSnapshot,
uint32_t& aPerQueryCall)
{
std::lock_guard lock(gTrackedGpsQueryMutex);
for (auto& query : gTrackedGpsQueries)
{
if (!query.active || query.id != aQueryId || query.manager != aManager)
{
continue;
}
aPerQueryCall = query.resultFetchCalls++;
aSnapshot = query;
return true;
}
return false;
}
bool NoteTrackedGpsQueryStatus(uint32_t aQueryId, void* aManager, TrackedGpsQuery& aSnapshot,
uint32_t& aPerQueryCall)
{
std::lock_guard lock(gTrackedGpsQueryMutex);
for (auto& query : gTrackedGpsQueries)
{
if (!query.active || query.id != aQueryId || query.manager != aManager)
{
continue;
}
aPerQueryCall = query.statusCalls++;
aSnapshot = query;
return true;
}
return false;
}
void AppendTrackedGpsQuery(std::ostringstream& aLine, const TrackedGpsQuery& aQuery)
{
aLine << " submitCall=" << aQuery.submitCall << " submitRetRva=0x" << std::hex << aQuery.submitReturnRva
<< std::dec;
}
void AppendRouteRefFields(std::ostringstream& aLine, const char* aPrefix, void* aRouteRef)
{
AppendPointerWithRva(aLine, aPrefix, aRouteRef);
@@ -730,6 +838,11 @@ void AppendRouteRefFields(std::ostringstream& aLine, const char* aPrefix, void*
void LogMappinRouteCollections(const char* aName, uint32_t aCount, void* aSystem)
{
if (!kEnableVerboseMappinRouteState)
{
return;
}
if (!aSystem)
{
return;
@@ -1133,7 +1246,6 @@ void DetourJournalTrackEntry(void* aThis, void* aEntryHandle)
AppendReturnRva(line, __builtin_return_address(0));
LogRed4ext(line.str());
LogJournalListeners(callCount, aThis);
++gJournalTrackEntryLogCount;
}
@@ -1906,6 +2018,10 @@ int32_t DetourGpsQuerySubmit(void* aManager, void* aQuery)
{
constexpr uint32_t kMaxCalls = 128;
const auto returnAddress = __builtin_return_address(0);
uintptr_t returnRva = 0;
TryGetImageRva(returnAddress, returnRva);
const auto callCount = gGpsQuerySubmitLogCount;
const auto shouldLog = callCount < kMaxCalls;
if (shouldLog)
@@ -1920,7 +2036,7 @@ int32_t DetourGpsQuerySubmit(void* aManager, void* aQuery)
AppendUint32Field(line, "query_f0c", aQuery, 0x0C);
AppendUint32Field(line, "query_fcc", aQuery, 0xCC);
AppendVector4Field(line, "query_pos58", aQuery, 0x58);
AppendReturnRva(line, __builtin_return_address(0));
AppendReturnRva(line, returnAddress);
LogRed4ext(line.str());
++gGpsQuerySubmitLogCount;
}
@@ -1931,6 +2047,11 @@ int32_t DetourGpsQuerySubmit(void* aManager, void* aQuery)
result = gOriginalGpsQuerySubmit(aManager, aQuery);
}
if (result >= 0)
{
TrackGpsQuery(static_cast<uint32_t>(result), aManager, returnRva, callCount);
}
if (shouldLog)
{
std::ostringstream line;
@@ -1969,20 +2090,11 @@ void DetourGpsQueryDispatch(void* aRuntimeQuery, void* aTargetPosition, void* aA
bool DetourGpsQueryResultFetch(void* aManager, uint32_t aQueryId, void* aOutPath)
{
constexpr uint32_t kMaxCalls = 128;
constexpr uint32_t kMaxUntrackedSamples = 32;
constexpr uint32_t kMaxTrackedSamplesPerQuery = 24;
const auto callCount = gGpsQueryResultFetchLogCount;
const auto shouldLog = callCount < kMaxCalls;
if (shouldLog)
{
std::ostringstream line;
line << "hook GPSQueryResultFetch 0x7094b8 call=" << callCount << " queryId=" << aQueryId;
AppendPointerWithRva(line, "manager", aManager);
AppendPointerWithRva(line, "outPath", aOutPath);
AppendReturnRva(line, __builtin_return_address(0));
LogRed4ext(line.str());
++gGpsQueryResultFetchLogCount;
}
const auto callCount = gGpsQueryResultFetchLogCount++;
const auto returnAddress = __builtin_return_address(0);
bool result = false;
if (gOriginalGpsQueryResultFetch)
@@ -1990,10 +2102,25 @@ bool DetourGpsQueryResultFetch(void* aManager, uint32_t aQueryId, void* aOutPath
result = gOriginalGpsQueryResultFetch(aManager, aQueryId, aOutPath);
}
TrackedGpsQuery trackedQuery{};
uint32_t perQueryCall = 0;
const auto isTracked = NoteTrackedGpsQueryResultFetch(aQueryId, aManager, trackedQuery, perQueryCall);
const auto shouldLog = (isTracked && (perQueryCall < kMaxTrackedSamplesPerQuery || result)) ||
(!isTracked && callCount < kMaxUntrackedSamples && aQueryId < 2);
if (shouldLog)
{
std::ostringstream line;
line << "hook GPSQueryResultFetch result call=" << callCount << " value=" << static_cast<uint32_t>(result);
line << "hook GPSQueryResultFetch 0x7094b8 call=" << callCount << " queryId=" << aQueryId
<< " tracked=" << static_cast<uint32_t>(isTracked) << " perQueryCall=" << perQueryCall
<< " value=" << static_cast<uint32_t>(result);
if (isTracked)
{
AppendTrackedGpsQuery(line, trackedQuery);
}
AppendPointerWithRva(line, "manager", aManager);
AppendPointerWithRva(line, "outPath", aOutPath);
AppendReturnRva(line, returnAddress);
AppendPathBufferSummary(line, "outPath", aOutPath);
LogRed4ext(line.str());
}
@@ -2001,6 +2128,44 @@ bool DetourGpsQueryResultFetch(void* aManager, uint32_t aQueryId, void* aOutPath
return result;
}
int32_t DetourGpsQueryStatus(void* aManager, uint32_t aQueryId)
{
constexpr uint32_t kMaxUntrackedSamples = 32;
constexpr uint32_t kMaxTrackedSamplesPerQuery = 24;
const auto callCount = gGpsQueryStatusLogCount++;
const auto returnAddress = __builtin_return_address(0);
int32_t result = 0;
if (gOriginalGpsQueryStatus)
{
result = gOriginalGpsQueryStatus(aManager, aQueryId);
}
TrackedGpsQuery trackedQuery{};
uint32_t perQueryCall = 0;
const auto isTracked = NoteTrackedGpsQueryStatus(aQueryId, aManager, trackedQuery, perQueryCall);
const auto shouldLog = (isTracked && (perQueryCall < kMaxTrackedSamplesPerQuery || result != 0)) ||
(!isTracked && callCount < kMaxUntrackedSamples && aQueryId < 2);
if (shouldLog)
{
std::ostringstream line;
line << "hook GPSQueryStatus 0xaa5704 call=" << callCount << " queryId=" << aQueryId
<< " tracked=" << static_cast<uint32_t>(isTracked) << " perQueryCall=" << perQueryCall
<< " value=" << result;
if (isTracked)
{
AppendTrackedGpsQuery(line, trackedQuery);
}
AppendPointerWithRva(line, "manager", aManager);
AppendReturnRva(line, returnAddress);
LogRed4ext(line.str());
}
return result;
}
void AttachProbeHook(const char* aName, uintptr_t aRva, void* aDetour, void** aOriginal)
{
if (!gSdk || !gSdk->hooking || !gSdk->hooking->Attach)
@@ -2324,38 +2489,44 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
AttachProbeHook("GPSQueryResultFetch 0x7094b8", kGpsQueryResultFetchRva,
reinterpret_cast<void*>(&DetourGpsQueryResultFetch),
reinterpret_cast<void**>(&gOriginalGpsQueryResultFetch));
AttachProbeHook("GPSQueryStatus 0xaa5704", kGpsQueryStatusRva,
reinterpret_cast<void*>(&DetourGpsQueryStatus),
reinterpret_cast<void**>(&gOriginalGpsQueryStatus));
AttachProbeHook("GPSSystem/Tick", kGpsSystemTickRva, reinterpret_cast<void*>(&DetourGpsSystemTick),
reinterpret_cast<void**>(&gOriginalGpsSystemTick));
AttachProbeHook("JournalManager::TrackEntry impl", kJournalTrackEntryImplRva,
reinterpret_cast<void*>(&DetourJournalTrackEntry),
reinterpret_cast<void**>(&gOriginalJournalTrackEntry));
AttachProbeHook("JournalListener::Objective vt28", kJournalListenerObjectiveVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerObjectiveVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerObjectiveVt28));
AttachProbeHook("JournalListener::Objective vt30", kJournalListenerObjectiveVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerObjectiveVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerObjectiveVt30));
AttachProbeHook("JournalListener::Route vt28", kJournalListenerRouteVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteVt28));
AttachProbeHook("JournalListener::Route vt30", kJournalListenerRouteVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteVt30));
AttachProbeHook("JournalListener::RouteAlt vt28", kJournalListenerRouteAltVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteAltVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteAltVt28));
AttachProbeHook("JournalListener::RouteAlt vt30", kJournalListenerRouteAltVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteAltVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteAltVt30));
AttachProbeHook("JournalListener::UI vt28", kJournalListenerUiVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerUiVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerUiVt28));
AttachProbeHook("JournalListener::UI vt30", kJournalListenerUiVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerUiVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerUiVt30));
AttachProbeHook("JournalListener::Tracker vt28", kJournalListenerTrackerVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerTrackerVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerTrackerVt28));
if (kEnableVerboseJournalListenerHooks)
{
AttachProbeHook("JournalListener::Objective vt28", kJournalListenerObjectiveVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerObjectiveVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerObjectiveVt28));
AttachProbeHook("JournalListener::Objective vt30", kJournalListenerObjectiveVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerObjectiveVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerObjectiveVt30));
AttachProbeHook("JournalListener::Route vt28", kJournalListenerRouteVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteVt28));
AttachProbeHook("JournalListener::Route vt30", kJournalListenerRouteVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteVt30));
AttachProbeHook("JournalListener::RouteAlt vt28", kJournalListenerRouteAltVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteAltVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteAltVt28));
AttachProbeHook("JournalListener::RouteAlt vt30", kJournalListenerRouteAltVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerRouteAltVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerRouteAltVt30));
AttachProbeHook("JournalListener::UI vt28", kJournalListenerUiVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerUiVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerUiVt28));
AttachProbeHook("JournalListener::UI vt30", kJournalListenerUiVt30Rva,
reinterpret_cast<void*>(&DetourJournalListenerUiVt30),
reinterpret_cast<void**>(&gOriginalJournalListenerUiVt30));
AttachProbeHook("JournalListener::Tracker vt28", kJournalListenerTrackerVt28Rva,
reinterpret_cast<void*>(&DetourJournalListenerTrackerVt28),
reinterpret_cast<void**>(&gOriginalJournalListenerTrackerVt28));
}
AttachProbeHook("JournalRouteBridge::Update candidate", kJournalRouteBridgeRva,
reinterpret_cast<void*>(&DetourJournalRouteBridge),
reinterpret_cast<void**>(&gOriginalJournalRouteBridge));
@@ -2374,24 +2545,27 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
AttachProbeHook("RouteBuildCandidate 0x5625a4", kRouteBuildCandidateRva,
reinterpret_cast<void*>(&DetourRouteBuildCandidate),
reinterpret_cast<void**>(&gOriginalRouteBuildCandidate));
AttachProbeHook("RouteObserver0::Activate slot48", kRouteObserver0ActivateRva,
reinterpret_cast<void*>(&DetourRouteObserver0Activate),
reinterpret_cast<void**>(&gOriginalRouteObserver0Activate));
AttachProbeHook("RouteObserver1::Activate slot48", kRouteObserver1ActivateRva,
reinterpret_cast<void*>(&DetourRouteObserver1Activate),
reinterpret_cast<void**>(&gOriginalRouteObserver1Activate));
AttachProbeHook("RouteObserver23::Activate slot48", kRouteObserver23ActivateRva,
reinterpret_cast<void*>(&DetourRouteObserver23Activate),
reinterpret_cast<void**>(&gOriginalRouteObserver23Activate));
AttachProbeHook("RouteObserver0::Deactivate slot50", kRouteObserver0DeactivateRva,
reinterpret_cast<void*>(&DetourRouteObserver0Deactivate),
reinterpret_cast<void**>(&gOriginalRouteObserver0Deactivate));
AttachProbeHook("RouteObserver1::Deactivate slot50", kRouteObserver1DeactivateRva,
reinterpret_cast<void*>(&DetourRouteObserver1Deactivate),
reinterpret_cast<void**>(&gOriginalRouteObserver1Deactivate));
AttachProbeHook("RouteObserver23::Deactivate slot50", kRouteObserver23DeactivateRva,
reinterpret_cast<void*>(&DetourRouteObserver23Deactivate),
reinterpret_cast<void**>(&gOriginalRouteObserver23Deactivate));
if (kEnableVerboseRouteObserverHooks)
{
AttachProbeHook("RouteObserver0::Activate slot48", kRouteObserver0ActivateRva,
reinterpret_cast<void*>(&DetourRouteObserver0Activate),
reinterpret_cast<void**>(&gOriginalRouteObserver0Activate));
AttachProbeHook("RouteObserver1::Activate slot48", kRouteObserver1ActivateRva,
reinterpret_cast<void*>(&DetourRouteObserver1Activate),
reinterpret_cast<void**>(&gOriginalRouteObserver1Activate));
AttachProbeHook("RouteObserver23::Activate slot48", kRouteObserver23ActivateRva,
reinterpret_cast<void*>(&DetourRouteObserver23Activate),
reinterpret_cast<void**>(&gOriginalRouteObserver23Activate));
AttachProbeHook("RouteObserver0::Deactivate slot50", kRouteObserver0DeactivateRva,
reinterpret_cast<void*>(&DetourRouteObserver0Deactivate),
reinterpret_cast<void**>(&gOriginalRouteObserver0Deactivate));
AttachProbeHook("RouteObserver1::Deactivate slot50", kRouteObserver1DeactivateRva,
reinterpret_cast<void*>(&DetourRouteObserver1Deactivate),
reinterpret_cast<void**>(&gOriginalRouteObserver1Deactivate));
AttachProbeHook("RouteObserver23::Deactivate slot50", kRouteObserver23DeactivateRva,
reinterpret_cast<void*>(&DetourRouteObserver23Deactivate),
reinterpret_cast<void**>(&gOriginalRouteObserver23Deactivate));
}
AttachProbeHook("FrameMappinPathWrapper", kFrameMappinPathWrapperRva,
reinterpret_cast<void*>(&DetourFrameMappinPathWrapper),
reinterpret_cast<void**>(&gOriginalFrameMappinPathWrapper));
@@ -2436,29 +2610,36 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
DetachProbeHook("GPSQuerySubmit 0x70a42c", kGpsQuerySubmitRva);
DetachProbeHook("GPSQueryDispatch 0x70a570", kGpsQueryDispatchRva);
DetachProbeHook("GPSQueryResultFetch 0x7094b8", kGpsQueryResultFetchRva);
DetachProbeHook("GPSQueryStatus 0xaa5704", kGpsQueryStatusRva);
DetachProbeHook("GPSSystem/Tick", kGpsSystemTickRva);
DetachProbeHook("JournalManager::TrackEntry impl", kJournalTrackEntryImplRva);
DetachProbeHook("JournalListener::Objective vt28", kJournalListenerObjectiveVt28Rva);
DetachProbeHook("JournalListener::Objective vt30", kJournalListenerObjectiveVt30Rva);
DetachProbeHook("JournalListener::Route vt28", kJournalListenerRouteVt28Rva);
DetachProbeHook("JournalListener::Route vt30", kJournalListenerRouteVt30Rva);
DetachProbeHook("JournalListener::RouteAlt vt28", kJournalListenerRouteAltVt28Rva);
DetachProbeHook("JournalListener::RouteAlt vt30", kJournalListenerRouteAltVt30Rva);
DetachProbeHook("JournalListener::UI vt28", kJournalListenerUiVt28Rva);
DetachProbeHook("JournalListener::UI vt30", kJournalListenerUiVt30Rva);
DetachProbeHook("JournalListener::Tracker vt28", kJournalListenerTrackerVt28Rva);
if (kEnableVerboseJournalListenerHooks)
{
DetachProbeHook("JournalListener::Objective vt28", kJournalListenerObjectiveVt28Rva);
DetachProbeHook("JournalListener::Objective vt30", kJournalListenerObjectiveVt30Rva);
DetachProbeHook("JournalListener::Route vt28", kJournalListenerRouteVt28Rva);
DetachProbeHook("JournalListener::Route vt30", kJournalListenerRouteVt30Rva);
DetachProbeHook("JournalListener::RouteAlt vt28", kJournalListenerRouteAltVt28Rva);
DetachProbeHook("JournalListener::RouteAlt vt30", kJournalListenerRouteAltVt30Rva);
DetachProbeHook("JournalListener::UI vt28", kJournalListenerUiVt28Rva);
DetachProbeHook("JournalListener::UI vt30", kJournalListenerUiVt30Rva);
DetachProbeHook("JournalListener::Tracker vt28", kJournalListenerTrackerVt28Rva);
}
DetachProbeHook("JournalRouteBridge::Update candidate", kJournalRouteBridgeRva);
DetachProbeHook("MappinSystem::RouteEventEnqueue slot240", kMappinRouteEventEnqueueRva);
DetachProbeHook("MappinRouteEvent::Handle", kMappinRouteEventHandlerRva);
DetachProbeHook("MappinSystem::RouteActivate", kMappinRouteActivateRva);
DetachProbeHook("MappinSystem::RouteDeactivate", kMappinRouteDeactivateRva);
DetachProbeHook("RouteBuildCandidate 0x5625a4", kRouteBuildCandidateRva);
DetachProbeHook("RouteObserver0::Activate slot48", kRouteObserver0ActivateRva);
DetachProbeHook("RouteObserver1::Activate slot48", kRouteObserver1ActivateRva);
DetachProbeHook("RouteObserver23::Activate slot48", kRouteObserver23ActivateRva);
DetachProbeHook("RouteObserver0::Deactivate slot50", kRouteObserver0DeactivateRva);
DetachProbeHook("RouteObserver1::Deactivate slot50", kRouteObserver1DeactivateRva);
DetachProbeHook("RouteObserver23::Deactivate slot50", kRouteObserver23DeactivateRva);
if (kEnableVerboseRouteObserverHooks)
{
DetachProbeHook("RouteObserver0::Activate slot48", kRouteObserver0ActivateRva);
DetachProbeHook("RouteObserver1::Activate slot48", kRouteObserver1ActivateRva);
DetachProbeHook("RouteObserver23::Activate slot48", kRouteObserver23ActivateRva);
DetachProbeHook("RouteObserver0::Deactivate slot50", kRouteObserver0DeactivateRva);
DetachProbeHook("RouteObserver1::Deactivate slot50", kRouteObserver1DeactivateRva);
DetachProbeHook("RouteObserver23::Deactivate slot50", kRouteObserver23DeactivateRva);
}
DetachProbeHook("FrameMappinPathWrapper", kFrameMappinPathWrapperRva);
DetachProbeHook("FrameMappinPathCore", kFrameMappinPathCoreRva);
DetachProbeHook("SetSelectedMappinWrapper", kSetSelectedMappinWrapperRva);