Skip to content

Commit

Permalink
Optimize narrow indirect value searches a bit
Browse files Browse the repository at this point in the history
  • Loading branch information
zorgiepoo committed Dec 21, 2023
1 parent 10fadcd commit 54744e3
Showing 1 changed file with 48 additions and 50 deletions.
98 changes: 48 additions & 50 deletions Bit Slicer/ZGSearchFunctions.mm
Expand Up @@ -2007,7 +2007,7 @@ static void _ZGSearchForIndirectPointerRecursively(const ZGPointerValueEntry *po
}];
}

static bool ZGEvaluateIndirectAddress2(ZGMemoryAddress *outAddress, ZGMemoryMap processTask, const void *indirectResult, ZGMemorySize pointerSize, NSArray<NSNumber *> *headerAddresses, ZGMemoryAddress minPointerAddress, ZGMemoryAddress maxPointerAddress, const ZGRegionValue *regionValuesTable, ZGMemorySize regionValuesTableCount, uint16_t *outNumberOfLevels, uint16_t *outBaseImageIndex, uint16_t *outOffsets, ZGMemoryAddress *outBaseAddresses, ZGMemoryAddress *outNextRecurseSearchAddress)
static bool ZGEvaluateIndirectAddress(ZGMemoryAddress *outAddress, ZGMemoryMap processTask, const void *indirectResult, ZGMemorySize pointerSize, NSArray<NSNumber *> * __unsafe_unretained headerAddresses, ZGMemoryAddress minPointerAddress, ZGMemoryAddress maxPointerAddress, ZGRegionValue *regionValuesTable, ZGMemorySize regionValuesTableCount, uint16_t *outNumberOfLevels, uint16_t *outBaseImageIndex, uint16_t *outOffsets, ZGMemoryAddress *outBaseAddresses, ZGMemoryAddress *outNextRecurseSearchAddress)
{

// Struct {
Expand Down Expand Up @@ -2082,21 +2082,21 @@ static bool ZGEvaluateIndirectAddress2(ZGMemoryAddress *outAddress, ZGMemoryMap
}

NSUInteger targetIndex = 0;
ZGRegionValue regionValueEntry;
ZGRegionValue *regionValueEntry;
{
NSUInteger end = regionValuesTableCount;
NSUInteger start = 0;

while (end > start)
{
targetIndex = start + (end - start) / 2;
regionValueEntry = regionValuesTable[targetIndex];
regionValueEntry = &regionValuesTable[targetIndex];

if (regionValueEntry.address + regionValueEntry.size <= currentAddress)
if (regionValueEntry->address + regionValueEntry->size <= currentAddress)
{
start = targetIndex + 1;
}
else if (regionValueEntry.address >= currentAddress + pointerSize)
else if (regionValueEntry->address >= currentAddress + pointerSize)
{
end = targetIndex;
}
Expand All @@ -2112,23 +2112,23 @@ static bool ZGEvaluateIndirectAddress2(ZGMemoryAddress *outAddress, ZGMemoryMap
break;

EVALUATE_INDIRECT_ADDRESS_FOUND_MATCH:
if (regionValueEntry.bytes == nullptr)
if (regionValueEntry->bytes == nullptr)
{
ZGMemorySize newSize = regionValueEntry.size;
ZGMemorySize newSize = regionValueEntry->size;
void *newBytes = nullptr;
if (!ZGReadBytes(processTask, regionValueEntry.address, &newBytes, &newSize))
if (!ZGReadBytes(processTask, regionValueEntry->address, &newBytes, &newSize))
{
validAddress = false;
break;
}
else
{
regionValueEntry.size = newSize;
regionValueEntry.bytes = newBytes;
regionValueEntry->size = newSize;
regionValueEntry->bytes = newBytes;
}
}

const void *bytesFromMemory = static_cast<const void *>(static_cast<const uint8_t *>(regionValueEntry.bytes) + currentAddress - regionValueEntry.address);
const void *bytesFromMemory = static_cast<const void *>(static_cast<const uint8_t *>(regionValueEntry->bytes) + currentAddress - regionValueEntry->address);

ZGMemoryAddress dereferencedAddressFromMemory;
if (pointerSize == sizeof(ZGMemoryAddress))
Expand Down Expand Up @@ -2303,38 +2303,6 @@ static int _sortPointerMapTable(const void *entry1, const void *entry2)
}
}

static NSArray<ZGRegion *> *ZGBuildPageToRegionTable(ZGMemoryMap processTask, std::unordered_map<ZGMemoryAddress, ZGRegion *> &pageToRegionTable, ZGSearchData *searchData, ZGMemorySize pageSize)
{
NSArray<ZGRegion *> *allRegions = [ZGRegion regionsWithExtendedInfoFromProcessTask:processTask];

NSArray<ZGRegion *> *regions = [ZGRegion regionsFilteredFromRegions:allRegions beginAddress:searchData.beginAddress endAddress:searchData.endAddress protectionMode:searchData.protectionMode includeSharedMemory:searchData.includeSharedMemory filterHeapAndStackData:NO totalStaticSegmentRanges:nil excludeStaticDataFromSystemLibraries:NO filePaths:nil];

for (ZGRegion *region in regions)
{
ZGMemoryAddress regionAddress = region.address;
ZGMemorySize regionSize = region.size;
assert(regionAddress % pageSize == 0);
for (NSUInteger dataIndex = 0; dataIndex < regionSize; dataIndex += pageSize)
{
pageToRegionTable[(dataIndex + regionAddress)] = region;
}
}

return regions;
}

static void ZGFreeRegionBytes(NSArray<ZGRegion *> *regions)
{
for (ZGRegion *region in regions)
{
if (region->_bytes != nullptr)
{
ZGFreeBytes(region->_bytes, region->_size);
region->_bytes = nullptr;
}
}
}

ZGSearchResults *ZGSearchForIndirectPointer(ZGMemoryMap processTask, ZGSearchData *searchData, id <ZGSearchProgressDelegate> delegate, uint16_t indirectMaxLevels, ZGVariableType indirectDataType, ZGSearchResults * _Nullable previousSearchResults)
{
const uint16_t previousIndirectMaxLevels = previousSearchResults.indirectMaxLevels;
Expand Down Expand Up @@ -2530,7 +2498,7 @@ static void ZGFreeRegionBytes(NSArray<ZGRegion *> *regions)
uint16_t baseImageIndex;

NSData *newResultSet;
if (ZGEvaluateIndirectAddress2(&currentAddress, processTask, previousIndirectResult, pointerSize, headerAddresses, minPointerValue, maxPointerValue, narrowRegionsTable, narrowRegionsTableCount, &numberOfLevels, &baseImageIndex, currentOffsets, currentBaseAddresses, &nextRecurseSearchAddress) && currentAddress == searchAddress)
if (ZGEvaluateIndirectAddress(&currentAddress, processTask, previousIndirectResult, pointerSize, headerAddresses, minPointerValue, maxPointerValue, narrowRegionsTable, narrowRegionsTableCount, &numberOfLevels, &baseImageIndex, currentOffsets, currentBaseAddresses, &nextRecurseSearchAddress) && currentAddress == searchAddress)
{
memset(tempBuffer, 0, stride);
memcpy(tempBuffer, previousIndirectResult, previousIndirectResultSetStride);
Expand Down Expand Up @@ -2609,7 +2577,7 @@ static void ZGFreeRegionBytes(NSArray<ZGRegion *> *regions)
if (regionValue.bytes != nullptr)
{
ZGFreeBytes(regionValue.bytes, regionValue.size);
regionValue.bytes = nullptr;
narrowRegionsTable[regionIndex].bytes = nullptr;
}
}
}
Expand Down Expand Up @@ -2880,6 +2848,11 @@ bool ZGNarrowSearchWithFunctionStoredCompare(ZGRegion **lastUsedSavedRegionRefer
{
P variableAddress = *(static_cast<P *>(const_cast<void *>(oldResultSetBytes)) + oldVariableIndex);

if (variableAddress == 0x0)
{
continue;
}

if (lastUsedRegion == nil || (variableAddress < lastUsedRegion->_address || variableAddress + dataSize > lastUsedRegion->_address + lastUsedRegion->_size))
{
if (lastUsedRegion != nil)
Expand Down Expand Up @@ -3636,15 +3609,32 @@ bool ZGByteArrayNotEquals(ZGSearchData *__unsafe_unretained searchData, T * __re
{
NSArray<NSData *> *indirectResultSets = indirectSearchResults.resultSets;

ZGMemorySize pageSize = ZGPageSizeForRegionAlignment(processTask, translated);
NSArray<ZGRegion *> *allRegions = [ZGRegion regionsWithExtendedInfoFromProcessTask:processTask];

std::unordered_map<ZGMemoryAddress, ZGRegion *> pageToRegionTable;
NSArray<ZGRegion *> *regions = ZGBuildPageToRegionTable(processTask, pageToRegionTable, searchData, pageSize);
NSArray<ZGRegion *> *regions = [ZGRegion regionsFilteredFromRegions:allRegions beginAddress:searchData.beginAddress endAddress:searchData.endAddress protectionMode:searchData.protectionMode includeSharedMemory:searchData.includeSharedMemory filterHeapAndStackData:NO totalStaticSegmentRanges:nil excludeStaticDataFromSystemLibraries:NO filePaths:nil];

ZGMemorySize regionValuesCount = regions.count;
ZGRegionValue *regionValues = static_cast<ZGRegionValue *>(calloc(regionValuesCount, sizeof(*regionValues)));

{
NSUInteger regionIndex = 0;
for (ZGRegion *region in regions)
{
ZGRegionValue regionValue;
regionValue.address = region.address;
regionValue.size = region.size;
regionValue.bytes = nullptr;
regionValues[regionIndex++] = regionValue;
}
}

NSMutableArray<NSData *> *directResultSets = [NSMutableArray array];

NSArray<NSNumber *> *headerAddresses = indirectSearchResults.headerAddresses;

ZGMemoryAddress minPointerAddress = searchData.beginAddress;
ZGMemoryAddress maxPointerAddress = searchData.endAddress;

ZGMemorySize pointerSize = searchData.pointerSize;
ZGMemorySize indirectResultsStride = indirectSearchResults.stride;
for (NSData *resultSet in indirectResultSets)
Expand All @@ -3659,7 +3649,7 @@ bool ZGByteArrayNotEquals(ZGSearchData *__unsafe_unretained searchData, T * __re
const uint8_t *resultBytes = resultSetBytes + resultIndex * indirectResultsStride;

ZGMemoryAddress address;
if (!ZGEvaluateIndirectAddress(&address, processTask, resultBytes, pointerSize, headerAddresses, pageToRegionTable, pageSize, nullptr, nullptr, nullptr, nullptr, nullptr))
if (!ZGEvaluateIndirectAddress(&address, processTask, resultBytes, pointerSize, headerAddresses, minPointerAddress, maxPointerAddress, regionValues, regionValuesCount, nullptr, nullptr, nullptr, nullptr, nullptr))
{
address = 0x0;
}
Expand All @@ -3681,7 +3671,15 @@ case sizeof(ZG32BitMemoryAddress):
[directResultSets addObject:newResultSet];
}

ZGFreeRegionBytes(regions);
for (ZGMemorySize regionIndex = 0; regionIndex < regionValuesCount; regionIndex++)
{
ZGRegionValue regionValue = regionValues[regionIndex];
if (regionValue.bytes != nullptr)
{
ZGFreeBytes(regionValue.bytes, regionValue.size);
regionValues[regionIndex].bytes = nullptr;
}
}

ZGSearchResults *directSearchResults = [[ZGSearchResults alloc] initWithResultSets:directResultSets resultType:ZGSearchResultTypeDirect dataType:dataType stride:pointerSize unalignedAccess:indirectSearchResults.unalignedAccess];

Expand Down

0 comments on commit 54744e3

Please sign in to comment.