Skip to content

Commit

Permalink
Improve relativization/annotations for indirect variables
Browse files Browse the repository at this point in the history
  • Loading branch information
zorgiepoo committed Jan 8, 2024
1 parent d126253 commit 1ca9eda
Showing 1 changed file with 55 additions and 30 deletions.
85 changes: 55 additions & 30 deletions Bit Slicer/ZGVariableController.m
Original file line number Diff line number Diff line change
Expand Up @@ -1023,11 +1023,34 @@ - (void)relativizeVariables:(NSArray<ZGVariable *> *)variables
}];
}

+ (NSString *)relativizeVariable:(ZGVariable * __unsafe_unretained)variable withMachBinaries:(NSArray<ZGMachBinary *> *)machBinaries filePathDictionary:(NSDictionary<NSNumber *, NSString *> *)machFilePathDictionary process:(ZGProcess *)process
+ (NSString *)relativizeVariable:(ZGVariable * __unsafe_unretained)variable withMachBinaries:(NSArray<ZGMachBinary *> *)machBinaries filePathDictionary:(NSDictionary<NSNumber *, NSString *> *)machFilePathDictionary process:(ZGProcess *)process failedImages:(NSMutableArray<NSString *> *)failedImages getAddress:(ZGMemoryAddress *)outVariableAddress
{
ZGMemoryAddress variableAddress;
BOOL isIndirectVariable = variable.usesDynamicPointerAddress;
if (isIndirectVariable)
{
if (![ZGCalculator extractIndirectBaseAddress:&variableAddress expression:variable.addressFormula process:process failedImages:failedImages])
{
if (outVariableAddress != NULL)
{
*outVariableAddress = variable.address;
}
return nil;
}
}
else
{
variableAddress = variable.address;
}

if (outVariableAddress != NULL)
{
*outVariableAddress = variableAddress;
}

NSString *staticVariableDescription = nil;

ZGMachBinary *machBinary = [ZGMachBinary machBinaryNearestToAddress:variable.address fromMachBinaries:machBinaries];
ZGMachBinary *machBinary = [ZGMachBinary machBinaryNearestToAddress:variableAddress fromMachBinaries:machBinaries];

NSString *machFilePath = [machFilePathDictionary objectForKey:@(machBinary.filePathAddress)];

Expand All @@ -1036,11 +1059,10 @@ + (NSString *)relativizeVariable:(ZGVariable * __unsafe_unretained)variable with
ZGMachBinaryInfo *machBinaryInfo = [machBinary machBinaryInfoInProcess:process];
NSRange totalSegmentRange = machBinaryInfo.totalSegmentRange;

if (variable.address >= totalSegmentRange.location && variable.address < totalSegmentRange.location + totalSegmentRange.length)
if (variableAddress >= totalSegmentRange.location && variableAddress < totalSegmentRange.location + totalSegmentRange.length)
{
BOOL isIndirectVariable = NO;
NSString *partialPath = [machFilePath lastPathComponent];
if (!variable.usesDynamicAddress)
if (!variable.usesDynamicBaseAddress)
{
NSString *pathToUse = nil;
NSString *baseArgument = @"";
Expand All @@ -1067,23 +1089,13 @@ + (NSString *)relativizeVariable:(ZGVariable * __unsafe_unretained)variable with
baseArgument = [NSString stringWithFormat:@"\"%@\"", pathToUse];
}

NSString *baseFormula = [NSString stringWithFormat:ZGBaseAddressFunction@"(%@) + 0x%llX", baseArgument, variable.address - machBinary.headerAddress];
NSString *baseFormula = [NSString stringWithFormat:ZGBaseAddressFunction@"(%@) + 0x%llX", baseArgument, variableAddress - machBinary.headerAddress];

// Test if this is a variable that uses a pointer address
// but has not been evaluated to use a dynamic address yet
if (variable.usesDynamicPointerAddress)
if (isIndirectVariable)
{
NSString *pointerReference = [NSString stringWithFormat:@"[0x%llX]", variable.address];
if ([variable.addressFormula containsString:pointerReference])
{
variable.addressFormula = [variable.addressFormula stringByReplacingOccurrencesOfString:pointerReference withString:[NSString stringWithFormat:@"[%@]", baseFormula]];

isIndirectVariable = YES;
}
else
{
variable.addressFormula = baseFormula;
}
NSString *pointerReference = [NSString stringWithFormat:@"[0x%llX]", variableAddress];

variable.addressFormula = [variable.addressFormula stringByReplacingOccurrencesOfString:pointerReference withString:[NSString stringWithFormat:@"[%@]", baseFormula]];
}
else
{
Expand All @@ -1094,7 +1106,7 @@ + (NSString *)relativizeVariable:(ZGVariable * __unsafe_unretained)variable with
variable.finishedEvaluatingDynamicAddress = !isIndirectVariable;
}

NSString *segmentName = [machBinaryInfo segmentNameAtAddress:variable.address];
NSString *segmentName = [machBinaryInfo segmentNameAtAddress:variableAddress];

NSMutableString *newDescription = [[NSMutableString alloc] initWithString:partialPath];
if (segmentName != nil)
Expand All @@ -1109,6 +1121,14 @@ + (NSString *)relativizeVariable:(ZGVariable * __unsafe_unretained)variable with

staticVariableDescription = [newDescription copy];
}
else if (isIndirectVariable)
{
staticVariableDescription = @"Indirect";
}
}
else if (isIndirectVariable)
{
staticVariableDescription = @"Indirect";
}

return staticVariableDescription;
Expand Down Expand Up @@ -1164,15 +1184,18 @@ + (void)annotateVariables:(NSArray<ZGVariable *> *)variables annotationInfo:(ZGM
ZGMemoryMap processTask = process.processTask;
NSUInteger capacity = variables.count;

NSMutableArray<NSString *> *failedImages = [NSMutableArray array];

NSArray<NSNumber *> *(^relativizeVariables)(NSArray<ZGMachBinary *> *, NSDictionary<NSNumber *, NSString *> *, NSArray **) = ^(NSArray<ZGMachBinary *> *machBinaries, NSDictionary<NSNumber *, NSString *> *machFilePathDictionary, NSArray **staticDescriptionsRef) {
NSMutableArray *staticDescriptions = [[NSMutableArray alloc] initWithCapacity:capacity];
NSMutableArray<NSNumber *> *variableAddresses = [[NSMutableArray alloc] initWithCapacity:capacity];

for (ZGVariable *variable in variables)
{
[variableAddresses addObject:@(variable.address)];
ZGMemoryAddress variableAddress;
NSString *staticDescription = [self relativizeVariable:variable withMachBinaries:machBinaries filePathDictionary:machFilePathDictionary process:process failedImages:failedImages getAddress:&variableAddress];

NSString *staticDescription = [self relativizeVariable:variable withMachBinaries:machBinaries filePathDictionary:machFilePathDictionary process:process];
[variableAddresses addObject:@(variableAddress)];

[staticDescriptions addObject:staticDescription != nil ? staticDescription : [NSNull null]];
}
Expand All @@ -1192,7 +1215,7 @@ + (void)annotateVariables:(NSArray<ZGVariable *> *)variables annotationInfo:(ZGM
return symbols;
};

void (^finishAnnotations)(NSArray *, NSArray *) = ^(NSArray * _Nullable symbols, NSArray *staticDescriptions) {
void (^finishAnnotations)(NSArray *, NSArray *, NSArray *) = ^(NSArray * _Nullable symbols, NSArray *staticDescriptions, NSArray<NSNumber *> *variableAddresses) {
__block ZGMemoryAddress cachedRegionAddress = 0;
__block ZGMemorySize cachedRegionSize = 0;
__block ZGMemoryExtendedInfo cachedInfo;
Expand All @@ -1212,9 +1235,11 @@ + (void)annotateVariables:(NSArray<ZGVariable *> *)variables annotationInfo:(ZGM
symbol = nil;
}

if (cachedRegionAddress >= variable.address + variable.size || cachedRegionAddress + cachedRegionSize <= variable.address)
ZGMemoryAddress variableAddress = [variableAddresses[index] unsignedLongLongValue];

if (cachedRegionAddress >= variableAddress || cachedRegionAddress + cachedRegionSize <= variableAddress)
{
cachedRegionAddress = variable.address;
cachedRegionAddress = variableAddress;
if (!ZGRegionExtendedInfo(processTask, &cachedRegionAddress, &cachedRegionSize, &cachedInfo))
{
cachedRegionAddress = 0;
Expand All @@ -1225,7 +1250,7 @@ + (void)annotateVariables:(NSArray<ZGVariable *> *)variables annotationInfo:(ZGM
NSString *userTagDescription = nil;
NSString *protectionDescription = nil;

if (cachedRegionAddress <= variable.address && cachedRegionAddress + cachedRegionSize >= variable.address + variable.size)
if (cachedRegionAddress <= variableAddress && cachedRegionAddress + cachedRegionSize >= variableAddress)
{
userTagDescription = ZGUserTagDescription(cachedInfo.user_tag);
protectionDescription = ZGProtectionDescription(cachedInfo.protection);
Expand Down Expand Up @@ -1265,7 +1290,7 @@ + (void)annotateVariables:(NSArray<ZGVariable *> *)variables annotationInfo:(ZGM
NSArray *symbols = requiresSymbols ? retrieveSymbols(variableAddresses) : nil;

dispatch_async(dispatch_get_main_queue(), ^{
finishAnnotations(symbols, staticDescriptions);
finishAnnotations(symbols, staticDescriptions, variableAddresses);
completionHandler();
});
});
Expand All @@ -1283,7 +1308,7 @@ + (void)annotateVariables:(NSArray<ZGVariable *> *)variables annotationInfo:(ZGM
NSArray *symbols = requiresSymbols ? retrieveSymbols(variableAddresses) : nil;

dispatch_async(dispatch_get_main_queue(), ^{
finishAnnotations(symbols, staticDescriptions);
finishAnnotations(symbols, staticDescriptions, variableAddresses);

completionHandler();
});
Expand Down Expand Up @@ -1315,7 +1340,7 @@ + (void)annotateVariables:(NSArray<ZGVariable *> *)variables annotationInfo:(ZGM
NSArray<NSNumber *> *variableAddresses = relativizeVariables(machBinaries, machFilePathDictionary, &staticDescriptions);

NSArray *symbols = requiresSymbols ? retrieveSymbols(variableAddresses) : nil;
finishAnnotations(symbols, staticDescriptions);
finishAnnotations(symbols, staticDescriptions, variableAddresses);
completionHandler();
}
}
Expand Down

0 comments on commit 1ca9eda

Please sign in to comment.