Probe GPS search edge costs
This commit is contained in:
@@ -236,6 +236,31 @@ Current static producer lead:
|
|||||||
`0x41be69`; patching there would alter copied/displayed records after route
|
`0x41be69`; patching there would alter copied/displayed records after route
|
||||||
choice. The cost patch needs to happen upstream of the `0x44cc7c` result
|
choice. The cost patch needs to happen upstream of the `0x44cc7c` result
|
||||||
construction path.
|
construction path.
|
||||||
|
- `0x44f054` is the strongest route-planning lead so far. It validates the
|
||||||
|
packed start/target lane handles, initializes a search-state table and open
|
||||||
|
list, pushes the start state, repeatedly pops the best state, checks for the
|
||||||
|
destination handle, traverses adjacency lists, and writes predecessor,
|
||||||
|
accumulated-cost, and priority fields for improved neighbor states. This is
|
||||||
|
the native GPS graph search loop.
|
||||||
|
- The search-state record is 0x20 bytes. Offsets `+0x00/+0x04/+0x08` are a
|
||||||
|
world position, `+0x0c` is accumulated path cost, `+0x10` is priority
|
||||||
|
(`cost + heuristic`), `+0x14` stores open/closed flags and the predecessor
|
||||||
|
index, and `+0x18` stores the packed lane handle.
|
||||||
|
- `0x44f7bc` is the heuristic helper. It returns world-space distance to the
|
||||||
|
target scaled by the constant at `0x1431ef3a0` (`0.9990000129`), unless a
|
||||||
|
route-shape helper supplies a shorter adjusted distance.
|
||||||
|
- The search loop calls a strategy object's vtable slot `+0x08` as an edge
|
||||||
|
admissibility predicate and slot `+0x10` as the edge-cost callback. For the
|
||||||
|
base/class-filter strategies, slot `+0x10` resolves to `0x44f838`.
|
||||||
|
- `0x44f838` computes the geometric edge distance and multiplies it by
|
||||||
|
`provider[0x08 + classId * 4]`, where `classId` is
|
||||||
|
`(*(routePoint + 0x13) & 0x3f)`. The GPS planner is therefore weighted, but
|
||||||
|
by a compact baked road-class table, not by traffic `maxSpeed` or lane
|
||||||
|
connection probabilities.
|
||||||
|
- The active probe now hooks `0x44f054` and `0x44f838` read-only. It logs the
|
||||||
|
live provider vtable, the 64 class multipliers, start/target handles, and a
|
||||||
|
capped sample of edge-cost calls with point class IDs, masks, handles, and
|
||||||
|
returned costs.
|
||||||
|
|
||||||
Autodrive finding:
|
Autodrive finding:
|
||||||
|
|
||||||
|
|||||||
@@ -150,6 +150,8 @@ constexpr uintptr_t kGpsQuerySubmitRva = 0x070A42C;
|
|||||||
constexpr uintptr_t kGpsQueryDispatchRva = 0x070A570;
|
constexpr uintptr_t kGpsQueryDispatchRva = 0x070A570;
|
||||||
constexpr uintptr_t kGpsQueryResultFetchRva = 0x07094B8;
|
constexpr uintptr_t kGpsQueryResultFetchRva = 0x07094B8;
|
||||||
constexpr uintptr_t kGpsQueryStatusRva = 0x0AA5704;
|
constexpr uintptr_t kGpsQueryStatusRva = 0x0AA5704;
|
||||||
|
constexpr uintptr_t kGpsSearchRva = 0x044F054;
|
||||||
|
constexpr uintptr_t kGpsEdgeCostRva = 0x044F838;
|
||||||
|
|
||||||
HMODULE gModule = nullptr;
|
HMODULE gModule = nullptr;
|
||||||
std::mutex gLogMutex;
|
std::mutex gLogMutex;
|
||||||
@@ -210,6 +212,10 @@ uint32_t gGpsQuerySubmitLogCount = 0;
|
|||||||
uint32_t gGpsQueryDispatchLogCount = 0;
|
uint32_t gGpsQueryDispatchLogCount = 0;
|
||||||
uint32_t gGpsQueryResultFetchLogCount = 0;
|
uint32_t gGpsQueryResultFetchLogCount = 0;
|
||||||
uint32_t gGpsQueryStatusLogCount = 0;
|
uint32_t gGpsQueryStatusLogCount = 0;
|
||||||
|
uint32_t gGpsSearchLogCount = 0;
|
||||||
|
uint32_t gGpsEdgeCostLogCount = 0;
|
||||||
|
std::array<uint32_t, 64> gGpsEdgeCostClassLogCounts{};
|
||||||
|
std::mutex gGpsCostLogMutex;
|
||||||
uint64_t gLogStartTick = 0;
|
uint64_t gLogStartTick = 0;
|
||||||
uint64_t gLogFrequency = 0;
|
uint64_t gLogFrequency = 0;
|
||||||
void* gMappinSetTrackedTarget = nullptr;
|
void* gMappinSetTrackedTarget = nullptr;
|
||||||
@@ -274,6 +280,12 @@ using GpsQuerySubmitFunc = int32_t (*)(void* aManager, void* aQuery);
|
|||||||
using GpsQueryDispatchFunc = void (*)(void* aRuntimeQuery, void* aTargetPosition, void* aArg3, void* aArg4);
|
using GpsQueryDispatchFunc = void (*)(void* aRuntimeQuery, void* aTargetPosition, void* aArg3, void* aArg4);
|
||||||
using GpsQueryResultFetchFunc = bool (*)(void* aManager, uint32_t aQueryId, void* aOutPath);
|
using GpsQueryResultFetchFunc = bool (*)(void* aManager, uint32_t aQueryId, void* aOutPath);
|
||||||
using GpsQueryStatusFunc = int32_t (*)(void* aManager, uint32_t aQueryId);
|
using GpsQueryStatusFunc = int32_t (*)(void* aManager, uint32_t aQueryId);
|
||||||
|
using GpsSearchFunc = int32_t (*)(void* aGraph, uint64_t aStartHandle, uint64_t aTargetHandle, void* aStartPoint,
|
||||||
|
void* aTargetPoint, void* aCostProvider, void* aOutPath, uint32_t* aOutCount);
|
||||||
|
using GpsEdgeCostFunc = float (*)(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);
|
||||||
ProbeFunc gOriginalGpsSystemTick = nullptr;
|
ProbeFunc gOriginalGpsSystemTick = nullptr;
|
||||||
JournalTrackEntryFunc gOriginalJournalTrackEntry = nullptr;
|
JournalTrackEntryFunc gOriginalJournalTrackEntry = nullptr;
|
||||||
ScriptNativeVoidFunc gOriginalFrameMappinPathWrapper = nullptr;
|
ScriptNativeVoidFunc gOriginalFrameMappinPathWrapper = nullptr;
|
||||||
@@ -325,6 +337,8 @@ GpsQuerySubmitFunc gOriginalGpsQuerySubmit = nullptr;
|
|||||||
GpsQueryDispatchFunc gOriginalGpsQueryDispatch = nullptr;
|
GpsQueryDispatchFunc gOriginalGpsQueryDispatch = nullptr;
|
||||||
GpsQueryResultFetchFunc gOriginalGpsQueryResultFetch = nullptr;
|
GpsQueryResultFetchFunc gOriginalGpsQueryResultFetch = nullptr;
|
||||||
GpsQueryStatusFunc gOriginalGpsQueryStatus = nullptr;
|
GpsQueryStatusFunc gOriginalGpsQueryStatus = nullptr;
|
||||||
|
GpsSearchFunc gOriginalGpsSearch = nullptr;
|
||||||
|
GpsEdgeCostFunc gOriginalGpsEdgeCost = nullptr;
|
||||||
|
|
||||||
std::filesystem::path GetLogPath()
|
std::filesystem::path GetLogPath()
|
||||||
{
|
{
|
||||||
@@ -817,6 +831,107 @@ void AppendVector4Field(std::ostringstream& aLine, const char* aLabel, void* aOb
|
|||||||
AppendVector4Pointer(aLine, aLabel, reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aObject) + aOffset));
|
AppendVector4Pointer(aLine, aLabel, reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aObject) + aOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool TryReadFloatField(void* aObject, uintptr_t aOffset, float& aValue)
|
||||||
|
{
|
||||||
|
return aObject && TryReadMemory(reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aObject) + aOffset),
|
||||||
|
aValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t ReadGpsPointClass(void* aPoint)
|
||||||
|
{
|
||||||
|
uint8_t value = 0xFF;
|
||||||
|
if (!aPoint || !TryReadMemory(reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aPoint) + 0x13), value))
|
||||||
|
{
|
||||||
|
return 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value & 0x3F;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t ReadGpsPointMask(void* aPoint)
|
||||||
|
{
|
||||||
|
uint16_t value = 0;
|
||||||
|
if (!aPoint)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TryReadMemory(reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aPoint) + 0x10), value);
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppendGpsPointSummary(std::ostringstream& aLine, const char* aPrefix, void* aPoint)
|
||||||
|
{
|
||||||
|
const auto prefix = std::string(aPrefix);
|
||||||
|
AppendPointerWithRva(aLine, prefix.c_str(), aPoint);
|
||||||
|
if (!aPoint)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t adjacency = 0;
|
||||||
|
uint16_t mask = 0;
|
||||||
|
uint8_t byte12 = 0;
|
||||||
|
uint8_t byte13 = 0;
|
||||||
|
TryReadMemory(aPoint, adjacency);
|
||||||
|
TryReadMemory(reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aPoint) + 0x10), mask);
|
||||||
|
TryReadMemory(reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aPoint) + 0x12), byte12);
|
||||||
|
TryReadMemory(reinterpret_cast<const void*>(reinterpret_cast<uintptr_t>(aPoint) + 0x13), byte13);
|
||||||
|
|
||||||
|
aLine << " " << prefix << "_adj=" << adjacency;
|
||||||
|
aLine << " " << prefix << "_mask10=0x" << std::hex << mask << std::dec;
|
||||||
|
aLine << " " << prefix << "_b12=0x" << std::hex << static_cast<uint32_t>(byte12);
|
||||||
|
aLine << " " << prefix << "_class13=" << std::dec << static_cast<uint32_t>(byte13 & 0x3F);
|
||||||
|
aLine << " " << prefix << "_raw13=0x" << std::hex << static_cast<uint32_t>(byte13) << std::dec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppendGpsCostProviderSummary(std::ostringstream& aLine, const char* aPrefix, void* aProvider)
|
||||||
|
{
|
||||||
|
const auto prefix = std::string(aPrefix);
|
||||||
|
AppendPointerWithRva(aLine, prefix.c_str(), aProvider);
|
||||||
|
if (!aProvider)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto* vtable = ReadPointerField(aProvider, 0x00);
|
||||||
|
AppendPointerWithRva(aLine, (prefix + "_vtable").c_str(), vtable);
|
||||||
|
if (IsInImage(vtable))
|
||||||
|
{
|
||||||
|
AppendPointerWithRva(aLine, (prefix + "_slot08").c_str(), ReadPointerField(vtable, 0x08));
|
||||||
|
AppendPointerWithRva(aLine, (prefix + "_slot10").c_str(), ReadPointerField(vtable, 0x10));
|
||||||
|
}
|
||||||
|
|
||||||
|
AppendUint16Field(aLine, (prefix + "_mask108").c_str(), aProvider, 0x108);
|
||||||
|
AppendUint16Field(aLine, (prefix + "_mask10a").c_str(), aProvider, 0x10A);
|
||||||
|
|
||||||
|
const auto flags = aLine.flags();
|
||||||
|
const auto precision = aLine.precision();
|
||||||
|
aLine << " " << prefix << "_mul=[";
|
||||||
|
for (uint32_t index = 0; index < 64; ++index)
|
||||||
|
{
|
||||||
|
float value = 0.0f;
|
||||||
|
const auto hasValue = TryReadFloatField(aProvider, 0x08 + static_cast<uintptr_t>(index) * sizeof(float), value);
|
||||||
|
if (index > 0)
|
||||||
|
{
|
||||||
|
aLine << ",";
|
||||||
|
}
|
||||||
|
|
||||||
|
aLine << index << ":";
|
||||||
|
if (hasValue)
|
||||||
|
{
|
||||||
|
aLine << std::fixed << std::setprecision(3) << value;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
aLine << "?";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
aLine << "]";
|
||||||
|
aLine.flags(flags);
|
||||||
|
aLine.precision(precision);
|
||||||
|
}
|
||||||
|
|
||||||
void AppendVector3ListCandidate(std::ostringstream& aLine, const char* aPrefix, void* aObject, uintptr_t aDataOffset,
|
void AppendVector3ListCandidate(std::ostringstream& aLine, const char* aPrefix, void* aObject, uintptr_t aDataOffset,
|
||||||
uintptr_t aCountOffset, uintptr_t aStride)
|
uintptr_t aCountOffset, uintptr_t aStride)
|
||||||
{
|
{
|
||||||
@@ -2419,6 +2534,126 @@ int32_t DetourGpsQueryStatus(void* aManager, uint32_t aQueryId)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32_t DetourGpsSearch(void* aGraph, uint64_t aStartHandle, uint64_t aTargetHandle, void* aStartPoint,
|
||||||
|
void* aTargetPoint, void* aCostProvider, void* aOutPath, uint32_t* aOutCount)
|
||||||
|
{
|
||||||
|
constexpr uint32_t kMaxCalls = 96;
|
||||||
|
|
||||||
|
uint32_t callCount = 0;
|
||||||
|
bool shouldLog = false;
|
||||||
|
{
|
||||||
|
std::lock_guard lock(gGpsCostLogMutex);
|
||||||
|
callCount = gGpsSearchLogCount++;
|
||||||
|
shouldLog = callCount < kMaxCalls;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldLog)
|
||||||
|
{
|
||||||
|
std::ostringstream line;
|
||||||
|
line << "hook GPSSearch 0x44f054 call=" << callCount << " startHandle=0x" << std::hex << aStartHandle
|
||||||
|
<< " targetHandle=0x" << aTargetHandle << std::dec;
|
||||||
|
AppendPointerWithRva(line, "graph", aGraph);
|
||||||
|
AppendVector3Pointer(line, "startPoint", aStartPoint);
|
||||||
|
AppendVector3Pointer(line, "targetPoint", aTargetPoint);
|
||||||
|
AppendPointerWithRva(line, "outPath", aOutPath);
|
||||||
|
AppendPointerWithRva(line, "outCount", aOutCount);
|
||||||
|
AppendGpsCostProviderSummary(line, "provider", aCostProvider);
|
||||||
|
AppendReturnRva(line, __builtin_return_address(0));
|
||||||
|
LogRed4ext(line.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t result = 0x80000008;
|
||||||
|
if (gOriginalGpsSearch)
|
||||||
|
{
|
||||||
|
result = gOriginalGpsSearch(aGraph, aStartHandle, aTargetHandle, aStartPoint, aTargetPoint, aCostProvider,
|
||||||
|
aOutPath, aOutCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldLog)
|
||||||
|
{
|
||||||
|
uint32_t outCount = 0;
|
||||||
|
const auto hasOutCount = aOutCount && TryReadMemory(aOutCount, outCount);
|
||||||
|
|
||||||
|
std::ostringstream line;
|
||||||
|
line << "hook GPSSearch result call=" << callCount << " value=0x" << std::hex
|
||||||
|
<< static_cast<uint32_t>(result) << std::dec << " hasOutCount=" << static_cast<uint32_t>(hasOutCount);
|
||||||
|
if (hasOutCount)
|
||||||
|
{
|
||||||
|
line << " outCount=" << outCount;
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
float result = 0.0f;
|
||||||
|
if (gOriginalGpsEdgeCost)
|
||||||
|
{
|
||||||
|
result = gOriginalGpsEdgeCost(aCostProvider, aCurrentState, aNeighborState, aPreviousHandle, aPreviousSegment,
|
||||||
|
aPreviousPoint, aCurrentHandle, aCurrentSegment, aCurrentPoint, aNeighborHandle,
|
||||||
|
aNeighborSegment, aNeighborPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto sourceClass = ReadGpsPointClass(aCurrentPoint);
|
||||||
|
const auto neighborClass = ReadGpsPointClass(aNeighborPoint);
|
||||||
|
|
||||||
|
float multiplier = 0.0f;
|
||||||
|
const auto hasMultiplier = sourceClass < 64 &&
|
||||||
|
TryReadFloatField(aCostProvider, 0x08 + static_cast<uintptr_t>(sourceClass) * sizeof(float),
|
||||||
|
multiplier);
|
||||||
|
|
||||||
|
uint32_t callCount = 0;
|
||||||
|
uint32_t classCallCount = 0;
|
||||||
|
bool shouldLog = false;
|
||||||
|
{
|
||||||
|
std::lock_guard lock(gGpsCostLogMutex);
|
||||||
|
callCount = gGpsEdgeCostLogCount++;
|
||||||
|
if (sourceClass < gGpsEdgeCostClassLogCounts.size())
|
||||||
|
{
|
||||||
|
classCallCount = gGpsEdgeCostClassLogCounts[sourceClass]++;
|
||||||
|
}
|
||||||
|
shouldLog = callCount < 256 || (sourceClass < 64 && classCallCount < 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldLog)
|
||||||
|
{
|
||||||
|
const auto baseCost = hasMultiplier && multiplier != 0.0f ? result / multiplier : 0.0f;
|
||||||
|
|
||||||
|
std::ostringstream line;
|
||||||
|
line << "hook GPSEdgeCost 0x44f838 call=" << callCount << " classCall=" << classCallCount
|
||||||
|
<< " sourceClass=" << static_cast<uint32_t>(sourceClass)
|
||||||
|
<< " neighborClass=" << static_cast<uint32_t>(neighborClass) << " value=" << result;
|
||||||
|
if (hasMultiplier)
|
||||||
|
{
|
||||||
|
line << " multiplier=" << multiplier << " baseCost=" << baseCost;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
line << " multiplier=<unreadable>";
|
||||||
|
}
|
||||||
|
line << " previousHandle=0x" << std::hex << aPreviousHandle << " currentHandle=0x" << aCurrentHandle
|
||||||
|
<< " neighborHandle=0x" << aNeighborHandle << std::dec;
|
||||||
|
AppendPointerWithRva(line, "provider", aCostProvider);
|
||||||
|
AppendVector3Pointer(line, "currentState", aCurrentState);
|
||||||
|
AppendVector3Pointer(line, "neighborState", aNeighborState);
|
||||||
|
AppendPointerWithRva(line, "previousSegment", aPreviousSegment);
|
||||||
|
AppendGpsPointSummary(line, "previousPoint", aPreviousPoint);
|
||||||
|
AppendPointerWithRva(line, "currentSegment", aCurrentSegment);
|
||||||
|
AppendGpsPointSummary(line, "currentPoint", aCurrentPoint);
|
||||||
|
AppendPointerWithRva(line, "neighborSegment", aNeighborSegment);
|
||||||
|
AppendGpsPointSummary(line, "neighborPoint", aNeighborPoint);
|
||||||
|
AppendReturnRva(line, __builtin_return_address(0));
|
||||||
|
LogRed4ext(line.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
void AttachProbeHook(const char* aName, uintptr_t aRva, void* aDetour, void** aOriginal)
|
void AttachProbeHook(const char* aName, uintptr_t aRva, void* aDetour, void** aOriginal)
|
||||||
{
|
{
|
||||||
if (!gSdk || !gSdk->hooking || !gSdk->hooking->Attach)
|
if (!gSdk || !gSdk->hooking || !gSdk->hooking->Attach)
|
||||||
@@ -2745,6 +2980,10 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
|||||||
AttachProbeHook("GPSQueryStatus 0xaa5704", kGpsQueryStatusRva,
|
AttachProbeHook("GPSQueryStatus 0xaa5704", kGpsQueryStatusRva,
|
||||||
reinterpret_cast<void*>(&DetourGpsQueryStatus),
|
reinterpret_cast<void*>(&DetourGpsQueryStatus),
|
||||||
reinterpret_cast<void**>(&gOriginalGpsQueryStatus));
|
reinterpret_cast<void**>(&gOriginalGpsQueryStatus));
|
||||||
|
AttachProbeHook("GPSSearch 0x44f054", kGpsSearchRva, reinterpret_cast<void*>(&DetourGpsSearch),
|
||||||
|
reinterpret_cast<void**>(&gOriginalGpsSearch));
|
||||||
|
AttachProbeHook("GPSEdgeCost 0x44f838", kGpsEdgeCostRva, reinterpret_cast<void*>(&DetourGpsEdgeCost),
|
||||||
|
reinterpret_cast<void**>(&gOriginalGpsEdgeCost));
|
||||||
AttachProbeHook("GPSSystem/Tick", kGpsSystemTickRva, reinterpret_cast<void*>(&DetourGpsSystemTick),
|
AttachProbeHook("GPSSystem/Tick", kGpsSystemTickRva, reinterpret_cast<void*>(&DetourGpsSystemTick),
|
||||||
reinterpret_cast<void**>(&gOriginalGpsSystemTick));
|
reinterpret_cast<void**>(&gOriginalGpsSystemTick));
|
||||||
AttachProbeHook("JournalManager::TrackEntry impl", kJournalTrackEntryImplRva,
|
AttachProbeHook("JournalManager::TrackEntry impl", kJournalTrackEntryImplRva,
|
||||||
@@ -2864,6 +3103,8 @@ RED4EXT_C_EXPORT bool RED4EXT_CALL Main(RED4ext::v1::PluginHandle aHandle, RED4e
|
|||||||
DetachProbeHook("GPSQueryDispatch 0x70a570", kGpsQueryDispatchRva);
|
DetachProbeHook("GPSQueryDispatch 0x70a570", kGpsQueryDispatchRva);
|
||||||
DetachProbeHook("GPSQueryResultFetch 0x7094b8", kGpsQueryResultFetchRva);
|
DetachProbeHook("GPSQueryResultFetch 0x7094b8", kGpsQueryResultFetchRva);
|
||||||
DetachProbeHook("GPSQueryStatus 0xaa5704", kGpsQueryStatusRva);
|
DetachProbeHook("GPSQueryStatus 0xaa5704", kGpsQueryStatusRva);
|
||||||
|
DetachProbeHook("GPSSearch 0x44f054", kGpsSearchRva);
|
||||||
|
DetachProbeHook("GPSEdgeCost 0x44f838", kGpsEdgeCostRva);
|
||||||
DetachProbeHook("GPSSystem/Tick", kGpsSystemTickRva);
|
DetachProbeHook("GPSSystem/Tick", kGpsSystemTickRva);
|
||||||
DetachProbeHook("JournalManager::TrackEntry impl", kJournalTrackEntryImplRva);
|
DetachProbeHook("JournalManager::TrackEntry impl", kJournalTrackEntryImplRva);
|
||||||
if (kEnableVerboseJournalListenerHooks)
|
if (kEnableVerboseJournalListenerHooks)
|
||||||
|
|||||||
Reference in New Issue
Block a user