def properties(debugger, command, exe_ctx, result, internal_dict): """ Syntax: properties <className/classInstance> Examples: (lldb) properties UIViewController (lldb) properties [NSObject new] (lldb) expression -l objc -O -- [NSObject new] <NSObject: 0x60000372f760> (lldb) properties 0x60000372f760 This command is implemented in HMClassInfoCommands.py """ if len(command) == 0: HM.DPrint( "Requires a argument, Please enter \"help properties\" for help.") return value = HM.evaluateExpressionValue( expression= f'(NSString *)[{command} performSelector:NSSelectorFromString(@"_propertyDescription")]', printErrors=False) if HM.successOfSBError(value.GetError()): HM.DPrint(value.GetObjectDescription()) return clsPrefixesValue = HM.getClassPrefixes()[1] command_script = f''' Class inputClass = objc_lookUpClass("{command}"); if (inputClass == nil) {{ // Find prefixed class for (NSString *prefix in (NSMutableArray *){clsPrefixesValue.GetValue()}) {{ NSString *clsName = [prefix stringByAppendingString:@".{command}"]; inputClass = objc_lookUpClass((char *)[clsName UTF8String]); if (inputClass) {{ break; }} }} }} NSMutableString *result = [[NSMutableString alloc] init]; if (inputClass == nil) {{ [result appendString:@"Unable to resolve {command} or find {command} class, maybe {command} is not a subclass of NSObject\\n"]; }} else {{ if ((BOOL)[(Class)inputClass respondsToSelector:(SEL)NSSelectorFromString(@"_propertyDescription")]) {{ [result appendString:(NSString *)[inputClass performSelector:NSSelectorFromString(@"_propertyDescription")]]; }} else {{ [result appendString:@"{command} is not a subclass of NSObject"]; }} }} result; ''' result = HM.evaluateExpressionValue(command_script).GetObjectDescription() HM.DPrint(result)
def methods(debugger, command, exe_ctx, result, internal_dict): """ Syntax: methods [--short] <className/classInstance> Examples: (lldb) methods UIViewController (lldb) methods -s UIViewController (lldb) methods [UIView new] (lldb) expression -l objc -O -- [NSObject new] <NSObject: 0x60000375f9a0> (lldb) methods 0x60000375f9a0 Options: --short/-s; Use [inputClass _shortMethodDescription] instead of [inputClass _methodDescription] This command is implemented in HMClassInfoCommands.py """ command_args = shlex.split(command) parser = generate_methods_option_parser() try: # options: optparse.Values # args: list (options, args) = parser.parse_args(command_args) except: result.SetError(parser.usage) return inputStr: str = "" for string in args: inputStr += string + " " inputStr = inputStr.rstrip() if len(inputStr) == 0: HM.DPrint( "Requires a argument, Please enter \"help methods\" for help.") return if options.short: selName = "_shortMethodDescription" else: selName = "_methodDescription" value = HM.evaluateExpressionValue( expression= f'(NSString *)[{inputStr} performSelector:NSSelectorFromString(@"{selName}")]', printErrors=False) if HM.successOfSBError(value.GetError()): HM.DPrint(value.GetObjectDescription()) return clsPrefixesValue = HM.getClassPrefixes()[1] command_script = f''' Class inputClass = objc_lookUpClass("{inputStr}"); if (inputClass == nil) {{ // Find prefixed class for (NSString *prefix in (NSMutableArray *){clsPrefixesValue.GetValue()}) {{ NSString *clsName = [prefix stringByAppendingString:@".{inputStr}"]; inputClass = objc_lookUpClass((char *)[clsName UTF8String]); if (inputClass) {{ break; }} }} }} NSMutableString *result = [[NSMutableString alloc] init]; if (inputClass == nil) {{ [result appendString:@"Unable to resolve {inputStr} or find {inputStr} class, maybe {inputStr} is not a subclass of NSObject\\n"]; }} else {{ if ((BOOL)[(Class)inputClass respondsToSelector:(SEL)NSSelectorFromString(@"{selName}")]) {{ [result appendString:(NSString *)[inputClass performSelector:NSSelectorFromString(@"{selName}")]]; }} else {{ [result appendString:@"{inputStr} is not a subclass of NSObject"]; }} }} result; ''' result = HM.evaluateExpressionValue(command_script).GetObjectDescription() HM.DPrint(result)