Probe observer1 route service lookup
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user