Probe observer1 route service lookup

This commit is contained in:
2026-06-20 01:30:56 -05:00
parent ad4907040a
commit 8c8cc784e0
3 changed files with 149 additions and 2 deletions
+123 -2
View File
@@ -138,6 +138,8 @@ constexpr uintptr_t kRouteObserver0DeactivateRva = 0x27B10C0;
constexpr uintptr_t kRouteObserver1DeactivateRva = 0x295D4A0;
constexpr uintptr_t kRouteObserver23DeactivateRva = 0x286A85C;
constexpr uintptr_t kObserver1SystemTypeGlobalRva = 0x342F6A8;
constexpr uintptr_t kObserver1ServiceLookupRva = 0x0287C44;
constexpr uintptr_t kObserver1ServiceRouteLookupSlotOffset = 0x220;
HMODULE gModule = nullptr;
std::mutex gLogMutex;
@@ -190,6 +192,8 @@ uint32_t gRouteObserver23ActivateLogCount = 0;
uint32_t gRouteObserver0DeactivateLogCount = 0;
uint32_t gRouteObserver1DeactivateLogCount = 0;
uint32_t gRouteObserver23DeactivateLogCount = 0;
uint32_t gObserver1ServiceLookupLogCount = 0;
uint32_t gObserver1ServiceRouteLookupLogCount = 0;
uint64_t gLogStartTick = 0;
uint64_t gLogFrequency = 0;
void* gMappinSetTrackedTarget = nullptr;
@@ -200,7 +204,9 @@ void* gMappinPositionQueryTarget = nullptr;
void* gMappinCreateCustomPositionTarget = nullptr;
void* gMappinReleaseQueryTarget = nullptr;
void* gMappinActiveRouteTarget = nullptr;
void* gObserver1ServiceRouteLookupTarget = nullptr;
bool gMappinSlotHookAttachAttempted = false;
bool gObserver1ServiceRouteLookupHookAttachAttempted = false;
using ProbeFunc = void (*)(void* aThis, void* a2, void* a3, void* a4);
using JournalTrackEntryFunc = void (*)(void* aThis, void* aEntryHandle);
@@ -229,6 +235,8 @@ using RouteBuildCandidateFunc = void (*)(void* aThis, uint32_t aRouteId, uint32_
void* aRouteData108, void* aRouteData114, uint8_t aFlag,
uint32_t aMode);
using RouteObserverCallbackFunc = void (*)(void* aObserver, void* aRouteEntry);
using Observer1ServiceLookupFunc = void* (*)(void* aServiceOwner, void* aSystemType);
using Observer1ServiceRouteLookupFunc = void (*)(void* aService, void* aOut, uint32_t aRouteId);
ProbeFunc gOriginalGpsSystemTick = nullptr;
JournalTrackEntryFunc gOriginalJournalTrackEntry = nullptr;
ScriptNativeVoidFunc gOriginalFrameMappinPathWrapper = nullptr;
@@ -272,6 +280,8 @@ RouteObserverCallbackFunc gOriginalRouteObserver23Activate = nullptr;
RouteObserverCallbackFunc gOriginalRouteObserver0Deactivate = nullptr;
RouteObserverCallbackFunc gOriginalRouteObserver1Deactivate = nullptr;
RouteObserverCallbackFunc gOriginalRouteObserver23Deactivate = nullptr;
Observer1ServiceLookupFunc gOriginalObserver1ServiceLookup = nullptr;
Observer1ServiceRouteLookupFunc gOriginalObserver1ServiceRouteLookup = nullptr;
std::filesystem::path GetLogPath()
{
@@ -556,6 +566,11 @@ void* ReadPointerField(void* aObject, uintptr_t aOffset)
return value;
}
void* GetObserver1SystemType()
{
return ReadPointerField(reinterpret_cast<void*>(GetImageBase() + kObserver1SystemTypeGlobalRva), 0x00);
}
void AppendObjectVtableSlots(std::ostringstream& aLine, void* aObject, std::initializer_list<uintptr_t> aSlots)
{
auto* vtable = ReadPointerField(aObject, 0);
@@ -679,8 +694,7 @@ void LogRouteObserverContext(const char* aName, uint32_t aCount, void* aObserver
{
auto* observerInner = ReadPointerField(aObserver, 0x08);
auto* observerInnerServiceOwner = ReadPointerField(observerInner, 0x18);
auto* observer1SystemType =
ReadPointerField(reinterpret_cast<void*>(GetImageBase() + kObserver1SystemTypeGlobalRva), 0x00);
auto* observer1SystemType = GetObserver1SystemType();
auto* routeObject = ReadPointerField(aRouteEntry, 0x00);
std::ostringstream line;
@@ -1801,6 +1815,108 @@ void DetachAbsoluteHook(const char* aName, void* aTarget)
LogRed4ext(line.str());
}
void DetourObserver1ServiceRouteLookup(void* aService, void* aOut, uint32_t aRouteId)
{
const auto shouldLog = gObserver1ServiceRouteLookupLogCount < 96;
const auto callCount = gObserver1ServiceRouteLookupLogCount;
if (shouldLog)
{
std::ostringstream line;
line << "hook Observer1Service::RouteLookup slot220 call=" << callCount << " routeId=" << aRouteId
<< "/0x" << std::hex << aRouteId << std::dec;
AppendPointerWithRva(line, "service", aService);
AppendPointerWithRva(line, "out", aOut);
AppendReturnRva(line, __builtin_return_address(0));
LogRed4ext(line.str());
++gObserver1ServiceRouteLookupLogCount;
}
if (gOriginalObserver1ServiceRouteLookup)
{
gOriginalObserver1ServiceRouteLookup(aService, aOut, aRouteId);
}
if (shouldLog)
{
std::ostringstream line;
line << "hook Observer1Service::RouteLookup slot220 result call=" << callCount;
AppendPointerField(line, "out_f00", aOut, 0x00);
AppendPointerField(line, "out_f08", aOut, 0x08);
AppendPointerField(line, "out_f10", aOut, 0x10);
auto* routeData = ReadPointerField(aOut, 0x00);
if (routeData)
{
AppendPointerWithRva(line, "routeData", routeData);
AppendPointerField(line, "routeData_f40", routeData, 0x40);
AppendPointerField(line, "routeData_f48", routeData, 0x48);
AppendPointerField(line, "routeData_f50", routeData, 0x50);
AppendPointerField(line, "routeData_f58", routeData, 0x58);
}
LogRed4ext(line.str());
}
}
void MaybeAttachObserver1ServiceRouteLookup(void* aService)
{
if (gObserver1ServiceRouteLookupHookAttachAttempted || !aService)
{
return;
}
auto* vtable = ReadPointerField(aService, 0x00);
if (!IsInImage(vtable))
{
return;
}
gObserver1ServiceRouteLookupTarget =
ReadPointerField(vtable, kObserver1ServiceRouteLookupSlotOffset);
if (!gObserver1ServiceRouteLookupTarget)
{
return;
}
gObserver1ServiceRouteLookupHookAttachAttempted = true;
AttachAbsoluteHook("Observer1Service::RouteLookup slot220", gObserver1ServiceRouteLookupTarget,
reinterpret_cast<void*>(&DetourObserver1ServiceRouteLookup),
reinterpret_cast<void**>(&gOriginalObserver1ServiceRouteLookup));
}
void* DetourObserver1ServiceLookup(void* aServiceOwner, void* aSystemType)
{
void* result = nullptr;
if (gOriginalObserver1ServiceLookup)
{
result = gOriginalObserver1ServiceLookup(aServiceOwner, aSystemType);
}
auto* observer1SystemType = GetObserver1SystemType();
if (!observer1SystemType || aSystemType != observer1SystemType)
{
return result;
}
if (gObserver1ServiceLookupLogCount < 96)
{
std::ostringstream line;
line << "hook Observer1ServiceLookup 0x287c44 call=" << gObserver1ServiceLookupLogCount;
AppendPointerWithRva(line, "serviceOwner", aServiceOwner);
AppendPointerWithRva(line, "systemType", aSystemType);
AppendPointerWithRva(line, "result", result);
AppendObjectVtableSlots(line, result, {0x218, 0x220, 0x228, 0x230, 0x238, 0x240});
AppendReturnRva(line, __builtin_return_address(0));
LogRed4ext(line.str());
++gObserver1ServiceLookupLogCount;
}
MaybeAttachObserver1ServiceRouteLookup(result);
return result;
}
void InspectAndHookMappinSystem(void* aThis)
{
auto* resolver = reinterpret_cast<MappinSystemResolverFunc>(GetImageBase() + kMappinSystemResolverRva);
@@ -2001,6 +2117,9 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
AttachProbeHook("RouteObserver23::Deactivate slot50", kRouteObserver23DeactivateRva,
reinterpret_cast<void*>(&DetourRouteObserver23Deactivate),
reinterpret_cast<void**>(&gOriginalRouteObserver23Deactivate));
AttachProbeHook("Observer1ServiceLookup 0x287c44", kObserver1ServiceLookupRva,
reinterpret_cast<void*>(&DetourObserver1ServiceLookup),
reinterpret_cast<void**>(&gOriginalObserver1ServiceLookup));
AttachProbeHook("FrameMappinPathWrapper", kFrameMappinPathWrapperRva,
reinterpret_cast<void*>(&DetourFrameMappinPathWrapper),
reinterpret_cast<void**>(&gOriginalFrameMappinPathWrapper));
@@ -2063,6 +2182,7 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
DetachProbeHook("RouteObserver0::Deactivate slot50", kRouteObserver0DeactivateRva);
DetachProbeHook("RouteObserver1::Deactivate slot50", kRouteObserver1DeactivateRva);
DetachProbeHook("RouteObserver23::Deactivate slot50", kRouteObserver23DeactivateRva);
DetachProbeHook("Observer1ServiceLookup 0x287c44", kObserver1ServiceLookupRva);
DetachProbeHook("FrameMappinPathWrapper", kFrameMappinPathWrapperRva);
DetachProbeHook("FrameMappinPathCore", kFrameMappinPathCoreRva);
DetachProbeHook("SetSelectedMappinWrapper", kSetSelectedMappinWrapperRva);
@@ -2083,6 +2203,7 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
DetachAbsoluteHook("MappinSystem::CreateCustomPosition slot2f0", gMappinCreateCustomPositionTarget);
DetachAbsoluteHook("MappinSystem::ReleaseQuery slot368", gMappinReleaseQueryTarget);
DetachAbsoluteHook("MappinSystem::ActiveRoute slot3a8", gMappinActiveRouteTarget);
DetachAbsoluteHook("Observer1Service::RouteLookup slot220", gObserver1ServiceRouteLookupTarget);
}
return true;