示例#1
0
    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)
示例#2
0
def add_objects_to_library(lib: TypeLibrary, view: BinaryView):
    for address, var in view.data_vars.items():
        symbol = view.get_symbol_at(address)

        if symbol is None:
            continue

        symbol_type = Symbol.type

        if symbol_type != SymbolType.DataSymbol:
            continue

        lib.add_named_object(symbol.raw_name, var.type)
示例#3
0
    def perform_get_lines_for_data(self, ctxt, view: BinaryView, addr: int,
                                   type_: Type, prefix: list, width: int,
                                   context):
        from_bytes = _get_from_bytes(view)

        symbol: Symbol = view.get_symbol_at(addr)

        cfstring = view.types.get('CFString')

        if cfstring is None:
            log_debug('CFString is not defined; how did we even get here?')
            return [DisassemblyTextLine(prefix, addr)]

        cfstring = cfstring.structure

        buffer = from_bytes(
            view.read(addr + cfstring['buffer'].offset, view.address_size))

        info = from_bytes(
            view.read(addr + cfstring['info'].offset,
                      cfstring['info'].type.width))

        length = from_bytes(
            view.read(addr + cfstring['length'].offset,
                      cfstring['length'].type.width))

        if info & 0xff == 0xc8:
            info_string = 'noinline,default,nofree,NI'
        elif info & 0xff == 0xd0:
            info_string = 'noinline,default,nofree,EUI'
        else:
            info_string = (
                f'{_cfstring_allocator_properties[(info >> 5) & 0x3]},'
                f'{"U" if info & 16 else ""}'
                f'{"N" if info & 8 else ""}'
                f'{"L" if info & 4 else ""}'
                f'{"I" if info & 1 else ""}')

        if 'U' not in info_string:
            string = view.get_ascii_string_at(buffer, 0)

            if string is None:
                log_debug('string returned None; how did we even get here?')
                return [DisassemblyTextLine(prefix, addr)]

            string = string.value
        else:
            string = view.read(buffer, length * 2)

        if symbol is None:
            name = f'data_{addr:x}'
        else:
            name = symbol.short_name

        prefix = [
            InstructionTextToken(InstructionTextTokenType.TypeNameToken,
                                 'CFString'),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' '),
            InstructionTextToken(InstructionTextTokenType.AnnotationToken,
                                 f'{{{info_string}}}'),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' '),
            InstructionTextToken(InstructionTextTokenType.DataSymbolToken,
                                 name, addr),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' = '),
            InstructionTextToken(InstructionTextTokenType.StringToken,
                                 f'{string!r}', buffer),
            InstructionTextToken(InstructionTextTokenType.TextToken, ' ')
        ]
        return [DisassemblyTextLine(prefix, addr)]