Skip to content

Commit

Permalink
Prevent users from adding cycles between variables using labels
Browse files Browse the repository at this point in the history
  • Loading branch information
zorgiepoo committed May 11, 2024
1 parent bcee32e commit 8aaa9f0
Show file tree
Hide file tree
Showing 17 changed files with 316 additions and 33 deletions.
16 changes: 16 additions & 0 deletions Bit Slicer.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
72130FC82BE6836A00691AED /* ZGEditLabelWindowController.m in Sources */ = {isa = PBXBuildFile; fileRef = 72130FC62BE6836A00691AED /* ZGEditLabelWindowController.m */; };
72130FCC2BE83BF400691AED /* Edit Label Dialog.xib in Resources */ = {isa = PBXBuildFile; fileRef = 72130FCB2BE83BF400691AED /* Edit Label Dialog.xib */; };
72130FD52BE84B4B00691AED /* [Code] Edit Variable Label.strings in Resources */ = {isa = PBXBuildFile; fileRef = 72130FD32BE84B4B00691AED /* [Code] Edit Variable Label.strings */; };
72130FF82BF00FAB00691AED /* [Code] Edit Variable Address.strings in Resources */ = {isa = PBXBuildFile; fileRef = 72130FF62BF00FAB00691AED /* [Code] Edit Variable Address.strings */; };
721594FE24DF36360027F600 /* HexFiend.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 721594FD24DF36360027F600 /* HexFiend.framework */; };
7215950024DF36520027F600 /* HexFiend.framework in Copy Frameworks */ = {isa = PBXBuildFile; fileRef = 721594FD24DF36360027F600 /* HexFiend.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
721B3C4D2AED913200F85660 /* ZGSearchProtectionMode.m in Sources */ = {isa = PBXBuildFile; fileRef = 720C192B271B4F9700740C8E /* ZGSearchProtectionMode.m */; };
Expand Down Expand Up @@ -331,6 +332,9 @@
72130FD42BE84B4B00691AED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = "Bit Slicer/en.lproj/[Code] Edit Variable Label.strings"; sourceTree = "<group>"; };
72130FD62BE84B5B00691AED /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = "Bit Slicer/es.lproj/[Code] Edit Variable Label.strings"; sourceTree = "<group>"; };
72130FD72BE84B6400691AED /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "Bit Slicer/ru.lproj/[Code] Edit Variable Label.strings"; sourceTree = "<group>"; };
72130FF72BF00FAB00691AED /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = "Bit Slicer/en.lproj/[Code] Edit Variable Address.strings"; sourceTree = "<group>"; };
72130FF92BF00FB300691AED /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = "Bit Slicer/es.lproj/[Code] Edit Variable Address.strings"; sourceTree = "<group>"; };
72130FFA2BF00FBD00691AED /* ru */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ru; path = "Bit Slicer/ru.lproj/[Code] Edit Variable Address.strings"; sourceTree = "<group>"; };
721594FD24DF36360027F600 /* HexFiend.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = HexFiend.framework; path = deps/HexFiend/HexFiend.framework; sourceTree = "<group>"; };
721594FF24DF36460027F600 /* HFLineCountingView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = HFLineCountingView.h; path = deps/HexFiend/HFLineCountingView.h; sourceTree = "<group>"; };
722CAA5519AD4AED009C6AAE /* hotkey.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = hotkey.png; path = "Bit Slicer/preficons/hotkey.png"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1039,6 +1043,7 @@
724A9F3719A813D600E72C9D /* [Code] Edit Variable Value.strings */,
724A9F3A19A8173900E72C9D /* [Code] Edit Variable Size.strings */,
72130FD32BE84B4B00691AED /* [Code] Edit Variable Label.strings */,
72130FF62BF00FAB00691AED /* [Code] Edit Variable Address.strings */,
724A9F3D19A823C300E72C9D /* [Code] Search Document.strings */,
724A9F4F19A8F54600E72C9D /* [Code] Search Document.stringsdict */,
724A9F4019A85D3F00E72C9D /* [Code] Search Table.strings */,
Expand Down Expand Up @@ -1600,6 +1605,7 @@
726CA2D719606E3800A6AD40 /* Watch Variable Dialog.xib in Resources */,
722CAA5919AD4AED009C6AAE /* hotkey.png in Resources */,
77F115AE17D2EAE4009E002A /* bitslicerdocicon.iconset in Resources */,
72130FF82BF00FAB00691AED /* [Code] Edit Variable Address.strings in Resources */,
7231440E19C6230F00FBE342 /* [Code] Watch Variable.stringsdict in Resources */,
724A9F2519A1657500E72C9D /* [Code] Memory Viewer Status Bar.strings in Resources */,
77F115AF17D2EAE4009E002A /* bitslicericon.iconset in Resources */,
Expand Down Expand Up @@ -1865,6 +1871,16 @@
name = "[Code] Edit Variable Label.strings";
sourceTree = "<group>";
};
72130FF62BF00FAB00691AED /* [Code] Edit Variable Address.strings */ = {
isa = PBXVariantGroup;
children = (
72130FF72BF00FAB00691AED /* en */,
72130FF92BF00FB300691AED /* es */,
72130FFA2BF00FBD00691AED /* ru */,
);
name = "[Code] Edit Variable Address.strings";
sourceTree = "<group>";
};
7231440C19C6230F00FBE342 /* [Code] Watch Variable.stringsdict */ = {
isa = PBXVariantGroup;
children = (
Expand Down
1 change: 1 addition & 0 deletions Bit Slicer/ZGCalculator.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (BOOL)extractIndirectBaseAddress:(ZGMemoryAddress *)outBaseAddress expression:(NSString *)initialExpression process:(ZGProcess * __unsafe_unretained)process variableController:(nullable ZGVariableController * __unsafe_unretained)variableController failedImages:(NSMutableArray<NSString *> * __unsafe_unretained)failedImages;

+ (nullable NSString *)extractFirstDependentLabelFromExpression:(NSString *)expression;
+ (BOOL)getVariableCycle:(NSArray<NSString *> * _Nullable __autoreleasing *_Nullable)outCycle variable:(ZGVariable *)variable variableController:(ZGVariableController *)variableController;

+ (BOOL)parseLinearExpression:(NSString *)linearExpression andGetAdditiveConstant:(NSString * _Nullable * _Nonnull)additiveConstantString multiplicateConstant:(NSString *_Nullable * _Nonnull)multiplicativeConstantString;

Expand Down
107 changes: 106 additions & 1 deletion Bit Slicer/ZGCalculator.m
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,8 @@ + (nullable NSString *)_extractFirstDependentLabelFromExpression:(DDExpression *
+ (nullable NSString *)extractFirstDependentLabelFromExpression:(NSString *)initialExpression
{
NSError *expressionError = NULL;
DDExpression *expression = [DDExpression expressionFromString:initialExpression error:&expressionError];
NSString *substitutedExpression = [self expressionBySubstitutingCalculatePointerFunctionInExpression:initialExpression];
DDExpression *expression = [DDExpression expressionFromString:substitutedExpression error:&expressionError];
if (expression == nil)
{
return nil;
Expand All @@ -954,6 +955,110 @@ + (nullable NSString *)extractFirstDependentLabelFromExpression:(NSString *)init
return [self _extractFirstDependentLabelFromExpression:expression];
}

+ (BOOL)_expressionIsCyclic:(DDExpression *)expression cycle:(NSArray<NSString *> * __autoreleasing *)outCycle variableController:(ZGVariableController *)variableController visitedLabels:(NSMutableOrderedSet<NSString *> *)visitedLabels
{
switch (expression.expressionType)
{
case DDExpressionTypeFunction:
{
if ([expression.function isEqualToString:ZGFindLabelFunction])
{
if (expression.arguments.count != 1)
{
return NO;
}

DDExpression *argumentExpression1 = expression.arguments[0];
if (argumentExpression1.expressionType != DDExpressionTypeVariable)
{
return NO;
}

NSString *label = argumentExpression1.variable;
if ([visitedLabels containsObject:label])
{
if (outCycle != NULL)
{
*outCycle = [visitedLabels.array arrayByAddingObject:label];
}
return YES;
}

[visitedLabels addObject:label];

ZGVariable *newLabelVariable = [variableController variableForLabel:label];
if (newLabelVariable == nil)
{
return NO;
}

// Recurse into the new variable label
NSString *addressFormula = newLabelVariable.addressFormula;
NSString *substitutedAddressFormulaExpression = [self expressionBySubstitutingCalculatePointerFunctionInExpression:addressFormula];

NSError *expressionError = NULL;
DDExpression *addressFormulaExpression = [DDExpression expressionFromString:substitutedAddressFormulaExpression error:&expressionError];
if (addressFormulaExpression == nil)
{
return NO;
}

return [self _expressionIsCyclic:addressFormulaExpression cycle:outCycle variableController:variableController visitedLabels:visitedLabels];
}

if (expression.arguments.count != 2)
{
return NO;
}

DDExpression *argumentExpression1 = expression.arguments[0];
DDExpression *argumentExpression2 = expression.arguments[1];

BOOL hasCycleInExpression1 = NO;
if (argumentExpression1.expressionType == DDExpressionTypeFunction)
{
// If we have label("A") + label("B") we want to use two different copies of visitedLabels
hasCycleInExpression1 = [self _expressionIsCyclic:argumentExpression1 cycle:outCycle variableController:variableController visitedLabels:[visitedLabels mutableCopy]];
if (hasCycleInExpression1)
{
return YES;
}
}

if (argumentExpression2.expressionType == DDExpressionTypeFunction)
{
return [self _expressionIsCyclic:argumentExpression2 cycle:outCycle variableController:variableController visitedLabels:visitedLabels];
}

return NO;
}
case DDExpressionTypeVariable:
case DDExpressionTypeNumber:
return NO;
}
}

+ (BOOL)getVariableCycle:(NSArray<NSString *> * __autoreleasing *)outCycle variable:(ZGVariable *)variable variableController:(ZGVariableController *)variableController
{
NSString *label = variable.label;
if (label.length == 0 || !variable.usesDynamicLabelAddress)
{
return NO;
}

NSString *initialExpression = [self expressionBySubstitutingCalculatePointerFunctionInExpression:variable.addressFormula];

NSError *expressionError = NULL;
DDExpression *expression = [DDExpression expressionFromString:initialExpression error:&expressionError];
if (expression == nil)
{
return NO;
}

NSMutableOrderedSet<NSString *> *visitedLabels = [NSMutableOrderedSet orderedSetWithObject:label];
return [self _expressionIsCyclic:expression cycle:outCycle variableController:variableController visitedLabels:visitedLabels];
}

+ (BOOL)isValidExpression:(NSString *)expression
{
return [[expression stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]] length] > 0;
Expand Down
13 changes: 11 additions & 2 deletions Bit Slicer/ZGEditAddressWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@
#import "ZGVariableController.h"
#import "ZGVariable.h"
#import "ZGNullability.h"
#import "ZGRunAlertPanel.h"

#define ZGEditAddressLocalizableTable @"[Code] Edit Variable Address"

@implementation ZGEditAddressWindowController
{
Expand Down Expand Up @@ -73,12 +76,18 @@ - (void)requestEditingAddressFromVariable:(ZGVariable *)variable attachedToWindo

- (IBAction)editAddress:(id)__unused sender
{
NSString *newAddressFormula = _addressTextField.stringValue;
NSString *cycleInfo = nil;
if (![_variableController editVariables:@[ZGUnwrapNullableObject(_variable)] addressFormulas:@[newAddressFormula] cycleInfo:&cycleInfo])
{
ZGRunAlertPanelWithOKButton(NSLocalizedStringFromTable(@"addressCycleAlertTitle", ZGEditAddressLocalizableTable, nil), [NSString stringWithFormat:NSLocalizedStringFromTable(@"addressCycleAlertMessageFormat", ZGEditAddressLocalizableTable, nil), newAddressFormula, cycleInfo]);
return;
}

NSWindow *window = ZGUnwrapNullableObject([self window]);
[NSApp endSheet:window];
[window close];

[_variableController editVariables:@[ZGUnwrapNullableObject(_variable)] addressFormulas:@[_addressTextField.stringValue]];

_variable = nil;
}

Expand Down
9 changes: 7 additions & 2 deletions Bit Slicer/ZGEditLabelWindowController.m
Original file line number Diff line number Diff line change
Expand Up @@ -280,12 +280,17 @@ - (IBAction)editVariablesLabels:(id)__unused sender
return;
}

NSString *cycleInfo = nil;
if (![_variableController editVariables:ZGUnwrapNullableObject(_variables) requestedLabels:requestedLabels cycleInfo:&cycleInfo])
{
ZGRunAlertPanelWithOKButton(NSLocalizedStringFromTable(@"labelCycleAlertTitle", ZGEditLabelLocalizableTable, nil), [NSString stringWithFormat:NSLocalizedStringFromTable(@"labelCycleAlertMessageFormat", ZGEditLabelLocalizableTable, nil), cycleInfo]);
return;
}

NSWindow *window = ZGUnwrapNullableObject(self.window);
[NSApp endSheet:window];
[window close];

[_variableController editVariables:ZGUnwrapNullableObject(_variables) requestedLabels:requestedLabels];

_variables = nil;
}

Expand Down
15 changes: 13 additions & 2 deletions Bit Slicer/ZGPyDebugger.m
Original file line number Diff line number Diff line change
Expand Up @@ -1507,10 +1507,21 @@ static BOOL writeRegister(NSDictionary<NSString *, NSValue *> *registerOffsetsDi

ZGVariableController *variableController = self->objcSelf->_variableController;

ZGPyDebugger *debugger = self->objcSelf;
dispatch_async(dispatch_get_main_queue(), ^{
ZGVariable *variable = [variableController variableForLabel:labelString];

[variableController editVariables:@[variable] addressFormulas:@[addressString]];
if (variable == nil)
{
[debugger->_loggerWindowController writeLine:[NSString stringWithFormat:@"Error: updateVariable() failed to identify variable with label '%@'", labelString]];
}
else
{
NSString *cycleInfo = nil;
if (![variableController editVariables:@[variable] addressFormulas:@[addressString] cycleInfo:&cycleInfo])
{
[debugger->_loggerWindowController writeLine:[NSString stringWithFormat:@"Error: updateVariable() failed to update label '%@' with address '%@' due to cycle '%@'", labelString, addressString, cycleInfo]];
}
}
});

return Py_BuildValue("");
Expand Down
4 changes: 2 additions & 2 deletions Bit Slicer/ZGVariableController.h
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,9 @@ typedef struct
+ (void)annotateVariables:(NSArray<ZGVariable *> *)variables process:(ZGProcess *)process variableController:(nullable ZGVariableController *)variableController symbols:(BOOL)requiresSymbols async:(BOOL)async completionHandler:(void (^)(void))completionHandler;

- (void)editVariables:(NSArray<ZGVariable *> *)variables newValues:(NSArray<NSString *> *)newValues;
- (void)editVariables:(NSArray<ZGVariable *> *)variables addressFormulas:(NSArray<NSString *> *)newAddressFormulas;
- (BOOL)editVariables:(NSArray<ZGVariable *> *)variables addressFormulas:(NSArray<NSString *> *)newAddressFormulas cycleInfo:(NSString * _Nullable __autoreleasing *_Nullable)outCycleInfo;
- (void)editVariables:(NSArray<ZGVariable *> *)variables requestedSizes:(NSArray<NSNumber *> *)requestedSizes;
- (void)editVariables:(NSArray<ZGVariable *> *)variables requestedLabels:(NSArray<NSString *> *)requestedLabels;
- (BOOL)editVariables:(NSArray<ZGVariable *> *)variables requestedLabels:(NSArray<NSString *> *)requestedLabels cycleInfo:(NSString * _Nullable __autoreleasing *_Nullable)outCycleInfo;

- (nullable ZGVariable *)variableForLabel:(NSString *)label;

Expand Down
Loading

0 comments on commit 8aaa9f0

Please sign in to comment.