def getProperties(klass): tmpString = """ NSMutableArray *result = (id)[NSMutableArray array]; unsigned int count; objc_property_t *props = (objc_property_t *)class_copyPropertyList((Class)$cls, &count); for (int i = 0; i < count; i++) { NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary]; char *name = (char *)property_getName(props[i]); [dict setObject:(id)[NSString stringWithUTF8String:name] forKey:@"name"]; char *attrstr = (char *)property_getAttributes(props[i]); [dict setObject:(id)[NSString stringWithUTF8String:attrstr] forKey:@"attributes_string"]; NSMutableDictionary *attrsDict = (id)[NSMutableDictionary dictionary]; unsigned int pcount; objc_property_attribute_t *attrs = (objc_property_attribute_t *)property_copyAttributeList(props[i], &pcount); for (int i = 0; i < pcount; i++) { NSString *name = (id)[NSString stringWithUTF8String:(char *)attrs[i].name]; NSString *value = (id)[NSString stringWithUTF8String:(char *)attrs[i].value]; [attrsDict setObject:value forKey:name]; } [dict setObject:attrsDict forKey:@"attributes"]; [result addObject:dict]; } RETURN(result); """ command = string.Template(tmpString).substitute(cls=klass) propsJson = fb.evaluate(command) return [Property(m) for m in propsJson]
def get_oc_methods_json(klass): tmpString = """ unsigned int outCount; Method *methods = (Method *)class_copyMethodList((Class)$cls, &outCount); NSMutableArray *result = (id)[NSMutableArray array]; for (int i = 0; i < outCount; i++) { NSMutableDictionary *m = (id)[NSMutableDictionary dictionary]; SEL name = (SEL)method_getName(methods[i]); [m setObject:(id)NSStringFromSelector(name) forKey:@"name"]; char * encoding = (char *)method_getTypeEncoding(methods[i]); [m setObject:(id)[NSString stringWithUTF8String:encoding] forKey:@"type_encoding"]; NSMutableArray *types = (id)[NSMutableArray array]; NSInteger args = (NSInteger)method_getNumberOfArguments(methods[i]); for (int idx = 0; idx < args; idx++) { char *type = (char *)method_copyArgumentType(methods[i], idx); [types addObject:(id)[NSString stringWithUTF8String:type]]; } [m setObject:types forKey:@"parameters_type"]; char *ret_type = (char *)method_copyReturnType(methods[i]); [m setObject:(id)[NSString stringWithUTF8String:ret_type] forKey:@"return_type"]; long imp = (long)method_getImplementation(methods[i]); [m setObject:[NSNumber numberWithLongLong:imp] forKey:@"implementation"]; [result addObject:m]; } RETURN(result); """ command = string.Template(tmpString).substitute(cls=klass) return fb.evaluate(command)
def getIvars(klass, instance=None): tmpString = """ NSMutableArray *result = (id)[NSMutableArray array]; unsigned int count; id object = (id)$obj; Ivar *vars = (Ivar *)class_copyIvarList((Class)$cls, &count); if (vars) { for (int i = 0; i < count; i++) { NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary]; char *name = (char *)ivar_getName(vars[i]); [dict setObject:(id _Nonnull)[NSString stringWithUTF8String:name] forKey:(id _Nonnull)@"name"]; NSString *encoding = [NSString stringWithUTF8String:(char *)ivar_getTypeEncoding(vars[i])]; [dict setObject:(id _Nonnull)encoding forKey:(id _Nonnull)@"encoding"]; NSNumber *offset = [NSNumber numberWithLong:(ptrdiff_t)ivar_getOffset(vars[i])]; [dict setObject:(id _Nonnull)offset forKey:(id _Nonnull)@"offset"]; if (object) { id value = (id)object_getIvar((id)object, vars[i]); [dict setObject:(id _Nonnull)[NSNumber numberWithLong:(long)value] forKey:(id _Nonnull)@"value"]; } [result addObject:dict]; } } RETURN(result); """ if instance is None: instance = 0 command = string.Template(tmpString).substitute(obj=instance, cls=klass) json = fb.evaluate(command) return [Ivar(m) for m in json]
def get_oc_menbers_json(mSelf,klass,ilass): str = """ unsigned int menberCount; NSMutableDictionary *result = (id)[NSMutableDictionary dictionary]; objc_property_t *properties = (objc_property_t *)class_copyPropertyList((Class)$cls, &menberCount); for (int i = 0; i<menberCount; i++) { char *name = (char *)property_getName(properties[i]); NSString *ret_name = (NSString *)[NSString stringWithUTF8String:name]; id value = (id)[(NSObject *)$ils valueForKey:ret_name]?:@"nil"; [result setObject:value forKey:ret_name]; } //free(properties); RETURN(result); """ command = string.Template(str).substitute(cls=klass,ils=ilass) return fb.evaluate(command)
def run(self, arguments, options): file_path = arguments[0].split()[0] if not file_path: print "Error: Missing file" return file = open(file_path, 'r') source = file.read() source = string.Template(source).substitute( arg0=self.getValue(arguments, 1), arg1=self.getValue(arguments, 2), arg2=self.getValue(arguments, 3), arg3=self.getValue(arguments, 4)) ret = fb.evaluate(source) # if ret is not an address then print it directly if ret[0:2] != '0x': print ret else: command = 'po {}'.format(ret) lldb.debugger.HandleCommand(command)
def run(self, arguments, options): file_path = arguments[0].split()[0] if not file_path: print "Error: Missing file" return file = open(file_path, 'r') source = file.read() source = string.Template(source).substitute( arg0=self.getValue(arguments, 1), arg1=self.getValue(arguments, 2), arg2=self.getValue(arguments, 3), arg3=self.getValue(arguments, 4) ) ret = fb.evaluate(source) # if ret is not an address then print it directly if ret[0:2] != '0x': print ret else: command = 'po {}'.format(ret) lldb.debugger.HandleCommand(command)
def run(self, arguments, options): block = arguments[0] # http://clang.llvm.org/docs/Block-ABI-Apple.html tmpString = """ enum { BLOCK_HAS_COPY_DISPOSE = (1 << 25), BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code BLOCK_IS_GLOBAL = (1 << 28), BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE BLOCK_HAS_SIGNATURE = (1 << 30), }; struct Block_literal_1 { void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor_1 { unsigned long int reserved; // NULL unsigned long int size; // sizeof(struct Block_literal_1) // optional helper functions void (*copy_helper)(void *dst, void *src); // IFF (1<<25) void (*dispose_helper)(void *src); // IFF (1<<25) // required ABI.2010.3.16 const char *signature; // IFF (1<<30) } *descriptor; // imported variables }; struct Block_literal_1 real = *((__bridge struct Block_literal_1 *)$block); NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary]; [dict setObject:(id)[NSNumber numberWithLong:(long)real.invoke] forKey:@"invoke"]; if (real.flags & BLOCK_HAS_SIGNATURE) { char *signature; if (real.flags & BLOCK_HAS_COPY_DISPOSE) { signature = (char *)(real.descriptor)->signature; } else { signature = (char *)(real.descriptor)->copy_helper; } NSMethodSignature *sig = [NSMethodSignature signatureWithObjCTypes:signature]; NSMutableArray *types = [NSMutableArray array]; [types addObject:(id)[NSString stringWithUTF8String:(char *)[sig methodReturnType]]]; for (NSUInteger i = 0; i < sig.numberOfArguments; i++) { char *type = (char *)[sig getArgumentTypeAtIndex:i]; [types addObject:(id)[NSString stringWithUTF8String:type]]; } [dict setObject:types forKey:@"signature"]; } RETURN(dict); """ command = string.Template(tmpString).substitute(block=block) json = fb.evaluate(command) signature = json['signature'] if not signature: print('Imp: ' + hex(json['invoke'])) return sigStr = '{} ^('.format(decode(signature[0])) # the block`s implementation always take the block as it`s first argument, so we ignore it sigStr += ', '.join([decode(m) for m in signature[2:]]) sigStr += ');' print('Imp: ' + hex(json['invoke']) + ' Signature: ' + sigStr)
def gpmessage(debugger, command, result, internal_dict): tmp = """ @import ObjectiveC.runtime; Class classA = NSClassFromString(@"$cls"); NSMutableString *result = [NSMutableString string]; if(classA) { GPBDescriptor *descriptor = objc_msgSend(classA,@selector(descriptor)); NSString *firstLine = [NSString stringWithFormat:@"message %@ {\\n", descriptor.name] [result appendString:firstLine]; NSMutableArray *enums = [NSMutableArray array]; for (GPBFieldDescriptor *field in descriptor.fields) { NSMutableString *line = @"\\t".mutableCopy; if(field.fieldType == 1) { [line appendString:@"repeated "]; } switch (field.dataType) { case 0x0:{ [line appendString:@"bool "]; break; } case 0x3: { [line appendString:@"float "]; break; } case 0x6: { [line appendString:@"double "]; break; } case 0x7:{ [line appendString:@"int32 "]; break; } case 0x8:{ [line appendString:@"int64 "]; break; } case 0xb:{ [line appendString:@"uint32 "]; break; } case 0xc:{ [line appendString:@"uint64 "]; break; } case 0xd:{ [line appendString:@"bytes "]; break; } case 0xe:{ [line appendString:@"string "]; break; } case 0xf: { [line appendString:[NSString stringWithFormat:@"%@ ", NSStringFromClass(field.msgClass)]]; break; } case 0x11:{ Ivar ivar = class_getInstanceVariable([GPBEnumDescriptor class], "valueCount_"); uint32_t valueCount = (uint32_t)(uintptr_t)object_getIvar(field.enumDescriptor, ivar); Ivar ivar2 = class_getInstanceVariable([GPBEnumDescriptor class], "values_"); uint32_t* values = (uint32_t*)(uintptr_t)object_getIvar(field.enumDescriptor, ivar2); for(int i = 0; i < valueCount; i++) { } [line appendString:[NSString stringWithFormat:@"%@ ", objc_msgSend(field.enumDescriptor,@selector(name))]]; [enums addObject:field]; break; } default: { [line appendString:[NSString stringWithFormat:@"unk%@ ", @(field.dataType)]]; break; } } [line appendString:[NSString stringWithFormat:@"%@ = %@", field.name, @(field.number)]]; if([field isPackable]) { [line appendString:@"[packed]"]; } [line appendString:@";\\n"]; [result appendString:line]; } [result appendString:@"}\\n"]; //打印所有枚举类型的proto for (GPBFieldDescriptor *field in enums) { [result appendString:@"\\n"]; GPBEnumDescriptor *enumDescriptor = field.enumDescriptor; NSMutableString *enumMessage = [NSMutableString string]; [enumMessage appendString:[NSString stringWithFormat:@"enum %@ {\\n", descriptor.name]]; Ivar ivar = class_getInstanceVariable([GPBEnumDescriptor class], "valueCount_"); uint32_t valueCount = (uint32_t)(uintptr_t)object_getIvar(enumDescriptor, ivar); Ivar ivar2 = class_getInstanceVariable([GPBEnumDescriptor class], "values_"); uint32_t* values = (uint32_t*)(uintptr_t)object_getIvar(enumDescriptor, ivar2); for(uint32_t i = 0; i < valueCount; i++) { uint32_t value = values[i]; NSString *name = [enumDescriptor enumNameForValue:value]; NSString *line = [NSString stringWithFormat:@"\\t%@ = %@;\\n", name, @(value)]; [enumMessage appendString:line]; } [enumMessage appendString:@"}\\n"]; [result appendString:enumMessage]; } } else { result = @"class not exists"; } RETURN(result); """ code = string.Template(tmp).substitute(cls=command) result = fb.evaluate(code) print result
def run(self, arguments, options): block = arguments[0] # http://clang.llvm.org/docs/Block-ABI-Apple.html tmpString = """ enum { BLOCK_HAS_COPY_DISPOSE = (1 << 25), BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code BLOCK_IS_GLOBAL = (1 << 28), BLOCK_HAS_STRET = (1 << 29), // IFF BLOCK_HAS_SIGNATURE BLOCK_HAS_SIGNATURE = (1 << 30), }; struct Block_literal_1 { void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor_1 { unsigned long int reserved; // NULL unsigned long int size; // sizeof(struct Block_literal_1) // optional helper functions void (*copy_helper)(void *dst, void *src); // IFF (1<<25) void (*dispose_helper)(void *src); // IFF (1<<25) // required ABI.2010.3.16 const char *signature; // IFF (1<<30) } *descriptor; // imported variables }; struct Block_literal_1 real = *((__bridge struct Block_literal_1 *)$block); NSMutableDictionary *dict = (id)[NSMutableDictionary dictionary]; [dict setObject:(id)[NSNumber numberWithLong:(long)real.invoke] forKey:@"invoke"]; if (real.flags & BLOCK_HAS_SIGNATURE) { char *signature; if (real.flags & BLOCK_HAS_COPY_DISPOSE) { signature = (char *)(real.descriptor)->signature; } else { signature = (char *)(real.descriptor)->copy_helper; } NSMethodSignature *sig = [NSMethodSignature signatureWithObjCTypes:signature]; NSMutableArray *types = [NSMutableArray array]; [types addObject:(id)[NSString stringWithUTF8String:(char *)[sig methodReturnType]]]; for (NSUInteger i = 0; i < sig.numberOfArguments; i++) { char *type = (char *)[sig getArgumentTypeAtIndex:i]; [types addObject:(id)[NSString stringWithUTF8String:type]]; } [dict setObject:types forKey:@"signature"]; } RETURN(dict); """ command = string.Template(tmpString).substitute(block=block) json = fb.evaluate(command) signature = json['signature'] if not signature: print 'Imp: ' + hex(json['invoke']) return sigStr = '{} ^('.format(decode(signature[0])) # the block`s implementation always take the block as it`s first argument, so we ignore it sigStr += ', '.join([decode(m) for m in signature[2:]]) sigStr += ');' print 'Imp: ' + hex(json['invoke']) + ' Signature: ' + sigStr