Probe GPS packed handle resolver
This commit is contained in:
@@ -168,6 +168,7 @@ constexpr uintptr_t kGpsRouteFinishRva = 0x11F5F60;
|
||||
constexpr uintptr_t kGpsRouteJobBuildRva = 0x0818BA8;
|
||||
constexpr uintptr_t kGpsRouteProducerRva = 0x044CC7C;
|
||||
constexpr uintptr_t kGpsSearchRva = 0x044F054;
|
||||
constexpr uintptr_t kGpsResolveHandleRva = 0x044E1A8;
|
||||
constexpr uintptr_t kGpsEdgeCostRva = 0x044F838;
|
||||
constexpr uintptr_t kGpsFilteredProviderFilterRva = 0x044FF68;
|
||||
constexpr uintptr_t kGpsBaseProviderFilterRva = 0x0450B08;
|
||||
@@ -264,6 +265,7 @@ uint32_t gGpsRouteFinishLogCount = 0;
|
||||
uint32_t gGpsRouteJobBuildLogCount = 0;
|
||||
uint32_t gGpsRouteProducerLogCount = 0;
|
||||
uint32_t gGpsSearchLogCount = 0;
|
||||
uint32_t gGpsResolveHandleLogCount = 0;
|
||||
uint32_t gGpsEdgeCostLogCount = 0;
|
||||
uint32_t gGpsAuxMultiplierLogCount = 0;
|
||||
uint32_t gGpsNodeMultiplierLogCount = 0;
|
||||
@@ -413,6 +415,7 @@ using GpsRouteJobBuildFunc = void* (*)(void* aJob, void* aOut, void* aRequest);
|
||||
using GpsRouteProducerFunc = int32_t (*)(void* aGraph, void* aQuery, void* aOutResult);
|
||||
using GpsSearchFunc = int32_t (*)(void* aGraph, uint64_t aStartHandle, uint64_t aTargetHandle, void* aStartPoint,
|
||||
void* aTargetPoint, void* aCostProvider, void* aOutPath, uint32_t* aOutCount);
|
||||
using GpsResolveHandleFunc = int32_t (*)(void* aGraph, uint64_t aHandle, void* aOutSegment, void* aOutPoint);
|
||||
using GpsEdgeCostFunc = float (*)(void* aCostProvider, void* aCurrentState, void* aNeighborState,
|
||||
uint64_t aPreviousHandle, void* aPreviousSegment, void* aPreviousPoint,
|
||||
uint64_t aCurrentHandle, void* aCurrentSegment, void* aCurrentPoint,
|
||||
@@ -478,6 +481,7 @@ GpsRouteFinishFunc gOriginalGpsRouteFinish = nullptr;
|
||||
GpsRouteJobBuildFunc gOriginalGpsRouteJobBuild = nullptr;
|
||||
GpsRouteProducerFunc gOriginalGpsRouteProducer = nullptr;
|
||||
GpsSearchFunc gOriginalGpsSearch = nullptr;
|
||||
GpsResolveHandleFunc gOriginalGpsResolveHandle = nullptr;
|
||||
GpsEdgeCostFunc gOriginalGpsEdgeCost = nullptr;
|
||||
GpsProviderFilterFunc gOriginalGpsFilteredProviderFilter = nullptr;
|
||||
GpsProviderFilterFunc gOriginalGpsBaseProviderFilter = nullptr;
|
||||
@@ -1055,6 +1059,33 @@ void AppendGpsPointSummary(std::ostringstream& aLine, const char* aPrefix, void*
|
||||
aLine << " " << prefix << "_raw13=0x" << std::hex << static_cast<uint32_t>(byte13) << std::dec;
|
||||
}
|
||||
|
||||
void AppendGpsPackedHandleSummary(std::ostringstream& aLine, const char* aPrefix, uint64_t aHandle)
|
||||
{
|
||||
const auto pointIndex = aHandle & 0xFFFFF;
|
||||
const auto segmentIndex = (aHandle >> 20) & 0x0FFFFFFF;
|
||||
const auto generation = aHandle >> 48;
|
||||
|
||||
aLine << " " << aPrefix << "_pointIndex=" << pointIndex;
|
||||
aLine << " " << aPrefix << "_segmentIndex=" << segmentIndex;
|
||||
aLine << " " << aPrefix << "_generation=" << generation;
|
||||
}
|
||||
|
||||
bool IsSelectedGpsResolveReturnRva(uintptr_t aReturnRva)
|
||||
{
|
||||
constexpr std::array<uintptr_t, 7> kSelectedReturnRvas = {
|
||||
0x44D26C,
|
||||
0x44D304,
|
||||
0x44D99F,
|
||||
0x44D9CD,
|
||||
0x44DB50,
|
||||
0x44DB88,
|
||||
0x44DD92,
|
||||
};
|
||||
|
||||
return std::find(kSelectedReturnRvas.begin(), kSelectedReturnRvas.end(), aReturnRva) !=
|
||||
kSelectedReturnRvas.end();
|
||||
}
|
||||
|
||||
void AppendGpsCostProviderSummary(std::ostringstream& aLine, const char* aPrefix, void* aProvider)
|
||||
{
|
||||
const auto prefix = std::string(aPrefix);
|
||||
@@ -3904,6 +3935,64 @@ bool DetourGpsBaseProviderFilter(void* aCostProvider, uint64_t aHandle, void* aS
|
||||
return result;
|
||||
}
|
||||
|
||||
int32_t DetourGpsResolveHandle(void* aGraph, uint64_t aHandle, void* aOutSegment, void* aOutPoint)
|
||||
{
|
||||
const auto returnAddress = __builtin_return_address(0);
|
||||
uintptr_t returnRva = 0;
|
||||
TryGetImageRva(returnAddress, returnRva);
|
||||
|
||||
int32_t result = 0x80000008;
|
||||
if (gOriginalGpsResolveHandle)
|
||||
{
|
||||
result = gOriginalGpsResolveHandle(aGraph, aHandle, aOutSegment, aOutPoint);
|
||||
}
|
||||
|
||||
void* segment = nullptr;
|
||||
void* point = nullptr;
|
||||
const auto hasSegment = aOutSegment && TryReadMemory(aOutSegment, segment);
|
||||
const auto hasPoint = aOutPoint && TryReadMemory(aOutPoint, point);
|
||||
|
||||
uint32_t callCount = 0;
|
||||
bool shouldLog = false;
|
||||
{
|
||||
std::lock_guard lock(gGpsCostLogMutex);
|
||||
callCount = gGpsResolveHandleLogCount++;
|
||||
shouldLog = result >= 0 && hasSegment && hasPoint &&
|
||||
(IsSelectedGpsResolveReturnRva(returnRva) || callCount < 64) && callCount < 512;
|
||||
}
|
||||
|
||||
if (shouldLog)
|
||||
{
|
||||
std::ostringstream line;
|
||||
line << "hook GPSResolveHandle 0x44e1a8 call=" << callCount << " value=0x" << std::hex
|
||||
<< static_cast<uint32_t>(result) << " handle=0x" << aHandle << std::dec;
|
||||
AppendGpsPackedHandleSummary(line, "handle", aHandle);
|
||||
AppendPointerWithRva(line, "graph", aGraph);
|
||||
AppendPointerWithRva(line, "outSegment", aOutSegment);
|
||||
AppendPointerWithRva(line, "outPoint", aOutPoint);
|
||||
AppendPointerWithRva(line, "segment", segment);
|
||||
AppendPointerWithRva(line, "point", point);
|
||||
AppendPointerField(line, "segment_p08", segment, 0x08);
|
||||
AppendPointerField(line, "segment_p10", segment, 0x10);
|
||||
AppendPointerField(line, "segment_p18", segment, 0x18);
|
||||
AppendPointerField(line, "segment_p20", segment, 0x20);
|
||||
AppendPointerField(line, "segment_p28", segment, 0x28);
|
||||
AppendPointerField(line, "segment_p30", segment, 0x30);
|
||||
AppendPointerField(line, "segment_p38", segment, 0x38);
|
||||
AppendGpsPointSummary(line, "pointSummary", point);
|
||||
AppendBytesPointer(line, "segment_raw68", segment, 0x68);
|
||||
AppendBytesPointer(line, "point_raw14", point, 0x14);
|
||||
if (gActiveGpsRouteProducerCall != UINT32_MAX)
|
||||
{
|
||||
line << " routeProducerCall=" << gActiveGpsRouteProducerCall;
|
||||
}
|
||||
AppendReturnRva(line, returnAddress);
|
||||
LogRed4ext(line.str());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
float DetourGpsEdgeCost(void* aCostProvider, void* aCurrentState, void* aNeighborState, uint64_t aPreviousHandle,
|
||||
void* aPreviousSegment, void* aPreviousPoint, uint64_t aCurrentHandle, void* aCurrentSegment,
|
||||
void* aCurrentPoint, uint64_t aNeighborHandle, void* aNeighborSegment, void* aNeighborPoint)
|
||||
@@ -4398,6 +4487,9 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
||||
AttachProbeHook("GPSRouteProducer 0x44cc7c", kGpsRouteProducerRva,
|
||||
reinterpret_cast<void*>(&DetourGpsRouteProducer),
|
||||
reinterpret_cast<void**>(&gOriginalGpsRouteProducer));
|
||||
AttachProbeHook("GPSResolveHandle 0x44e1a8", kGpsResolveHandleRva,
|
||||
reinterpret_cast<void*>(&DetourGpsResolveHandle),
|
||||
reinterpret_cast<void**>(&gOriginalGpsResolveHandle));
|
||||
AttachProbeHook("GPSEdgeCost 0x44f838", kGpsEdgeCostRva, reinterpret_cast<void*>(&DetourGpsEdgeCost),
|
||||
reinterpret_cast<void**>(&gOriginalGpsEdgeCost));
|
||||
AttachProbeHook("GPSFilteredProviderFilter 0x44ff68", kGpsFilteredProviderFilterRva,
|
||||
@@ -4560,6 +4652,7 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
||||
if (kEnableGpsTraceHooks && kEnableGpsLocalSearchHooks)
|
||||
{
|
||||
DetachProbeHook("GPSRouteProducer 0x44cc7c", kGpsRouteProducerRva);
|
||||
DetachProbeHook("GPSResolveHandle 0x44e1a8", kGpsResolveHandleRva);
|
||||
DetachProbeHook("GPSEdgeCost 0x44f838", kGpsEdgeCostRva);
|
||||
DetachProbeHook("GPSFilteredProviderFilter 0x44ff68", kGpsFilteredProviderFilterRva);
|
||||
DetachProbeHook("GPSBaseProviderFilter 0x450b08", kGpsBaseProviderFilterRva);
|
||||
|
||||
Reference in New Issue
Block a user