def add_members(view: BinaryView, structure: StructureBuilder, start: int, length: int): offset = 0 br = BinaryReader(view) if (dv := view.get_data_var_at(start)) is None: dv = view.get_next_data_var_after(start) offset = dv.address - start
def from_address(cls, address: int, self_type: str, view: BinaryView, is_class=False): if address == 0: return None method_list_t_type = view.get_type_by_name('method_list_t') method_list_t = Type.named_type_from_type('method_list_t', method_list_t_type) method_t = view.get_type_by_name('method_t') if view.get_data_var_at(address) is None: view.define_user_data_var(address, method_list_t) members = get_structure_members(address, method_list_t_type, view) methods = dict() start = address + method_list_t_type.width end = start + members['count'] * method_t.width step = method_t.width for method_addr in range(start, end, step): method = Method.from_address(method_addr, self_type, view, is_class) if method is not None: methods[method.name] = method return cls(address, **members, methods=methods)
def from_address(cls, address: int, view: BinaryView): if address == 0: return None from_bytes = get_from_bytes(view) protocol_list_t_type = view.get_type_by_name('protocol_list_t') protocol_list_t = Type.named_type_from_type('protocol_list_t', protocol_list_t_type) protocol_t = view.get_type_by_name('protocol_t') members = get_structure_members(address, protocol_list_t_type, view) view.define_user_data_var(address, protocol_list_t) protocols = {} start = address + protocol_list_t_type.width end = start + members['count'] * view.address_size step = view.address_size for protocol_ptr in range(start, end, step): if not view.get_data_var_at(protocol_ptr): view.define_user_data_var(protocol_ptr, Type.pointer(view.arch, protocol_t)) protocol = Protocol.from_address( from_bytes(view.read(protocol_ptr, view.address_size)), view) protocols[protocol.name] = protocol return cls(address, **members, protocols=protocols)
def from_address(cls, address: int, view: BinaryView): if address == 0: return None property_list_t_type = view.types['property_list_t'] property_list_t = Type.named_type_from_type( 'property_list_t', property_list_t_type ) property_t = view.types['property_t'] if view.get_data_var_at(address) is None: view.define_user_data_var(address, property_list_t) members = get_structure_members(address, property_list_t_type, view) properties = dict() start = address + property_list_t_type.width end = start + members['count'] * property_t.width step = property_t.width for property_addr in range(start, end, step): property_ = Property.from_address(property_addr, view) if property_ is not None: properties[property_.name] = property_ return cls(address, **members, properties=properties)
def from_address(cls, address: int, view: BinaryView): if address == 0: return None property_t_type = view.types['property_t'] property_t = Type.named_type_from_type( 'property_t', property_t_type ) if view.get_data_var_at(address) is None: view.define_user_data_var( address, property_t ) members = get_structure_members(address, property_t_type, view) members['name'] = ( view.get_ascii_string_at(members['name'], 1).value if members['name'] else '' ) members['attributes'] = ( view.get_ascii_string_at(members['attributes'], 1).value if members['attributes'] else '' ) return cls(address, **members)
def from_address(cls, address: int, class_name: str, view: BinaryView): if address == 0: return None from_bytes = get_from_bytes(view) ivar_t_type = view.types['ivar_t'] ivar_t = Type.named_type_from_type( 'ivar_t', ivar_t_type ) members = get_structure_members(address, ivar_t_type, view) member_dict = {m.name: m for m in ivar_t_type.structure.members} # x64 uses uint64_t for offset, but everything else # uses uint32_t ivar_offset_type = ( member_dict['offset'].type.target if view.arch != Architecture['x86_64'] else Type.int(8, False) ) ivar_offset_type.const = True if view.get_data_var_at(address) is None: view.define_user_data_var(address, ivar_t) if members['name'] != 0: name_string = view.get_ascii_string_at(members['name'], 1) if name_string is not None: members['name'] = name_string.value else: members['name'] = '' if members['type']: type_string = view.get_ascii_string_at(members['type'], 1).value members['type'] = _lookup_type(type_string, view) if not members['type']: members['type'] = Type.pointer(view.arch, Type.void()) if members['offset']: view.define_user_data_var(members['offset'], ivar_offset_type) view.define_user_symbol( Symbol( SymbolType.DataSymbol, members['offset'], f'{members["name"]}_offset', namespace=class_name ) ) members['offset'] = from_bytes( view.read(members['offset'], member_dict['offset'].type.target.width) ) else: members['offset'] = None return cls(address, **members)
def from_address(cls, address: int, view: BinaryView) -> Category: if address == 0: return None from .class_t import Class, ClassRO category_t_type = view.types['category_t'] category_t = Type.named_type_from_type('category_t', category_t_type) if view.get_data_var_at(address) is None: view.define_user_data_var(address, category_t) members = get_structure_members(address, category_t_type, view) members['name'] = (view.get_ascii_string_at(members['name'], 1).value if members['name'] else '') members['cls'] = Class.from_address(members['cls'], view) if members['cls'] is None: cls_offset = next(m.offset for m in category_t_type.structure.members if m.name == 'cls') cls_name = view.get_symbol_at(address + cls_offset) cls_name = cls_name.name if cls_name is not None else members[ 'name'] class_match = re.match( r'_OBJC_(META)?CLASS_\$_(?P<classname>[_A-Za-z0-9=/]+)(@GOT)?', cls_name) if class_match is not None: cls_name = class_match.group('classname') cls_ = view.session_data['ClassNames'].get(cls_name) if cls_ is None: cls_ = Class(None, view, None, None, None, {}, {}) cls_.vtable = ClassRO(address, *([None] * 11)) cls_.vtable.name = cls_name view.session_data['ClassNames'][cls_name] = cls_ members['cls'] = cls_ else: cls_name = members['cls'].vtable.name members['instanceMethods'] = MethodList.from_address( members['instanceMethods'], cls_name, view) if members['cls'] is not None and not members['cls'].methods: members['cls']._methods = members['instanceMethods'].methods elif members['cls'] is not None: members['cls']._methods.update(members['instanceMethods'].methods) members['protocols'] = ProtocolList.from_address( members['protocols'], view) return cls(address, **members)
def from_address(cls, address: int, self_type: str, view: BinaryView, is_class=False): if address == 0: return None if self_type not in view.types: view.define_user_type(self_type, Type.structure_type(Structure())) method_t_type = view.get_type_by_name('method_t') method_t = Type.named_type_from_type('method_t', method_t_type) if view.get_data_var_at(address) is None: view.define_user_data_var(address, method_t) members = get_structure_members(address, method_t_type, view) members['name'] = (view.get_ascii_string_at(members['name'], 1).value if members['name'] else '') members['types'] = parse_function_type( view.get_ascii_string_at(members['types'], 1).value if members['types'] else '', self_type, view, is_class) members['imp'] = view.get_function_at(members['imp']) if members['imp'] is not None: if not is_class: method_name = f'-[{self_type} {members["name"]}]' else: method_name = f'+[{self_type} {members["name"]}]' if view.symbols.get(method_name): namespace = f'{members["imp"].start}' else: namespace = None view.define_user_symbol( Symbol(SymbolType.FunctionSymbol, members['imp'].start, method_name, namespace=namespace)) if members['types'] is not None: members['imp'].function_type = members['types'] return cls(address, **members)
def from_address(cls, address: int, view: BinaryView, is_meta=False): from .protocol_t import ProtocolList if address == 0: return None elif address in view.session_data['ClassROList']: return view.session_data['ClassROList'] from_bytes = partial(int.from_bytes, byteorder=("little" if view.endianness == Endianness.LittleEndian else "big")) class_ro_t = Type.named_type_from_type('class_ro_t', view.types['class_ro_t']) if view.get_data_var_at(address) is None: view.define_user_data_var(address, class_ro_t) members = { m.name: from_bytes(view.read(address + m.offset, m.type.width)) for m in view.types['class_ro_t'].structure.members } members['name'] = (view.get_ascii_string_at(members['name'], 1).value if members['name'] != 0 else '') members['ivarLayout'] = (view.get_ascii_string_at( members['ivarLayout'], 1).value if members['ivarLayout'] != 0 else '') members['ivars'] = IvarList.from_address(members['ivars'], members['name'], view) members['baseMethods'] = MethodList.from_address( members['baseMethods'], members['name'], view, is_meta) members['baseProtocols'] = ProtocolList.from_address( members['baseProtocols'], view) members['baseProperties'] = PropertyList.from_address( members['baseProperties'], view) new_class_ro = cls(address, **members) view.session_data['ClassROList'][address] = new_class_ro return new_class_ro
def from_address(cls, address: int, view: BinaryView) -> Protocol: if address == 0: return None from .class_t import Class from_bytes = partial(int.from_bytes, byteorder=("little" if view.endianness == Endianness.LittleEndian else "big")) protocol_t = Type.named_type_from_type( 'protocol_t', view.get_type_by_name('protocol_t')) if not view.get_data_var_at(address): view.define_user_data_var(address, protocol_t) members = { m.name: from_bytes(view.read(address + m.offset, m.type.width)) for m in view.get_type_by_name('protocol_t').structure.members } members['isa'] = Class.from_address(members['isa'], view) members['name'] = (view.get_ascii_string_at(members['name'], 1).value if members['name'] != 0 else '') if members['name'] not in view.types: view.define_user_type(members['name'], Type.structure_type(Structure())) members['protocols'] = ProtocolList.from_address( members['protocols'], view) members['instanceMethods'] = MethodList.from_address( members['instanceMethods'], members['name'], view) members['optionalInstanceMethods'] = MethodList.from_address( members['optionalInstanceMethods'], members['name'], view) new_protocol = cls(address, **members) view.session_data['Protocols'][new_protocol.name] = new_protocol return new_protocol