コード例 #1
0
    def STRUCT_DECL_handler(self, current_node_hash):

        with self.driver.session() as session:
            struct_name = session.run("MATCH (binja_struct:STRUCT_DECL {Hash: {current_node_hash}}) "
                                      "RETURN binja_struct.TypeName as struct_name",
                                      current_node_hash=current_node_hash).peek()['struct_name']

            result = session.run("MATCH (binja_struct:STRUCT_DECL {Hash: {current_node_hash}})-[:FieldDef]->"
                                 "(struct_field:StructFieldDecl) "
                                 "RETURN struct_field.Hash as field_hash, "
                                 "       struct_field.TypeDefinition as type_definition,"
                                 "       struct_field.TypeName as type_name ",
                                 current_node_hash=current_node_hash)

            if result.peek():
                # Structs can be recursively defined. In order to avoid such a situation the binja_struct is
                # immediately inserted into the cache instead of waiting for the full definition.
                self.type_definition_cache[current_node_hash] = True

                print(f'struct_name: {struct_name} Hash: {current_node_hash}')

                binja_struct = types.Structure()
                self.bv.define_user_type(struct_name, Type.structure_type(types.Structure()))

                for record in result:
                    if self.insert_type_definition_into_binaryView('StructFieldDecl', record['field_hash']):
                        self.type_definition_cache[record['field_hash']] = True
                    else:
                        print("Failed to insert definition for binja_struct field ", record['field_hash'])
                        return False

                    try:
                        # add binja_struct member
                        print(f'binja_struct def: {record["type_definition"]} , name: {record["type_name"]}')
                        type_string = record['type_definition'] + ' ' + record['type_name']
                        if record['type_definition'].startswith('AnonUnion'):
                            type_string = 'union' + ' ' + type_string
                        elif record['type_definition'].startswith('AnonStruct'):
                            type_string = 'struct' + ' ' + type_string
                        print('type_string: ', type_string)
                        var_type, name = self.bv.parse_type_string(type_string)
                        binja_struct.append(var_type, str(name))
                    except Exception as e:
                        print("STRUCT_DECL_handler: Failed to add a binja_struct member" + str(e))
                        return False
            else:
                print("Struct has no target, current binja_struct hash: ", current_node_hash)
                return False

            try:
                self.bv.define_user_type(struct_name, Type.structure_type(binja_struct))
                return True
            except Exception as e:
                print("STRUCT_DECL_handler: Failed to define Struct. " + str(e))
                return False
コード例 #2
0
    def UNION_DECL_handler(self, current_node_hash):

        with self.driver.session() as session:
            union_name = session.run("MATCH (union:UNION_DECL {Hash: {current_node_hash}}) "
                                     "RETURN union.TypeName as union_name",
                                     current_node_hash=current_node_hash).peek()['union_name']

            result = session.run("MATCH (union:UNION_DECL {Hash: {current_node_hash}})-[:FieldDef]->"
                                 "(union_field) "
                                 "RETURN union_field.Hash as field_hash, "
                                 "       labels(union_field)[0] as field_label, "
                                 "       union_field.TypeDefinition as type_definition,"
                                 "       union_field.TypeName as type_name ",
                                 current_node_hash=current_node_hash)

            if result.peek():
                # Unions can be recursively defined. In order to avoid such a situation the struct is
                # immediately inserted into the cache instead of waiting for the full definition.
                self.type_definition_cache[current_node_hash] = True

                struct = types.Structure()
                # set type to union
                struct.type = types.StructureType.UnionStructureType
                self.bv.define_user_type(union_name, Type.structure_type(types.Structure()))

                for record in result:
                    if self.insert_type_definition_into_binaryView(record['field_label'], record['field_hash']):
                        self.type_definition_cache[record['field_hash']] = True
                    else:
                        print("Failed to insert definition for union field ", record['field_hash'])
                        return False

                    try:
                        # add struct member
                        if record['type_definition'] == 'PointerTo':
                            type_string = record['type_name']
                        else:
                            type_string = record['type_definition'] + ' ' + record['type_name']
                        var_type, name = self.bv.parse_type_string(type_string)
                        struct.append(var_type, str(name))
                    except Exception as e:
                        print("UNION_DECL_handler: Failed to add union member. " + str(e))
                        return False
            else:
                print("Union has no target, current Union hash: ", current_node_hash)
                return False

            try:
                self.bv.define_user_type(union_name, Type.structure_type(struct))
                return True
            except Exception as e:
                print("UNION_DECL_handler: Failed to define union. " + str(e))
                return False
コード例 #3
0
ファイル: types.py プロジェクト: planetminguez/ObjCGraphView
def _lookup_type(type_string: str, view: BinaryView):
    if type_string in basic_types:
        return basic_types[type_string]
    elif type_string == '*':
        return Type.pointer(view.arch, Type.char())
    elif type_string.startswith('@'):
        if type_string[2:-1] in view.types:
            return Type.pointer(
                view.arch,
                Type.named_type_from_type(
                    type_string[2:-1],
                    view.types[type_string[2:-1]]
                )
            )
        elif type_string != '@?' and type_string != '@':
            if type_string[2:-1]:
                new_type = Type.named_type_from_type(
                    type_string[2:-1], Type.structure_type(Structure()))
                view.define_user_type(type_string[2:-1], new_type)
            else:
                new_type = Type.void()
            return Type.pointer(view.arch, new_type)
        else:
            return Type.pointer(view.arch, Type.void())
    elif type_string.startswith('#'):
        return Type.pointer(view.arch, Type.void())
    elif type_string == ':':
        return view.types['SEL']
    else:
        return Type.pointer(view.arch, Type.void())
コード例 #4
0
    def __create_class_name_type(bv: BinaryView, vmt: DelphiVMT, out_struct: types.Structure) -> bool:
        vmt_offsets = vmt.vmt_offsets

        if not vmt.seek_to_vmt_offset(vmt_offsets.cVmtClassName):
            return False

        class_name_ptr = vmt.read_ptr()

        if class_name_ptr is None:
            return False

        if not vmt.seek_to_code(class_name_ptr):
            return False

        class_name_len = vmt.read8()

        if class_name_len is None:
            return False

        class_name_struct = types.Structure()
        class_name_struct.append(Type.int(1, False), 'length')
        class_name_struct.append(Type.array(Type.char(), class_name_len), 'value')
        struct_type = Type.structure_type(class_name_struct)

        bv.define_user_data_var(class_name_ptr, struct_type)
        out_struct.append(Type.pointer(bv.arch, struct_type), 'cVmtClassName')

        # Create Symbole for class name
        class_name_sym = Symbol(SymbolType.DataSymbol, class_name_ptr, f'{vmt.class_name}Name')
        bv.define_user_symbol(class_name_sym)

        return True
コード例 #5
0
    def visit_MLIL_CONST(self, expr):
        view = expr.function.source_function.view
        class_symbol = view.get_symbol_at(expr.constant)

        if class_symbol is None:
            return

        log_debug(class_symbol.name)

        class_match = re.match(
            r'_OBJC_(META)?CLASS_\$_(?P<classname>[_A-Za-z0-9=/]+)(@GOT)?',
            class_symbol.name
        )

        class_name = class_match.group('classname')

        class_type = view.types.get(class_name)

        if class_type is None:
            view.define_user_type(class_name, Type.structure_type(Structure()))
            class_type = view.types.get(class_name)

        return Type.pointer(
            view.arch,
            Type.named_type_from_type(class_name, class_type)
        )
コード例 #6
0
    def update_memory_view(self):
        if self.adapter == None:
            raise Exception('missing adapter')
        if self.memory_view == None:
            raise Exception('missing memory_view')

        for symbol in self.old_symbols:
            # Symbols are immutable so just destroy the old one
            self.memory_view.undefine_auto_symbol(symbol)

        for dv in self.old_dvs:
            self.memory_view.undefine_data_var(dv)

        self.old_symbols = []
        self.old_dvs = set()
        new_dvs = set()

        for (reg, addr) in self.registers:
            bits = self.registers.bits(reg)
            symbol_name = '$' + reg
            self.memory_view.define_auto_symbol(
                Symbol(SymbolType.ExternalSymbol,
                       addr,
                       symbol_name,
                       namespace=symbol_name))
            self.old_symbols.append(
                self.memory_view.get_symbol_by_raw_name(symbol_name,
                                                        namespace=symbol_name))
            self.memory_view.define_data_var(addr,
                                             Type.int(bits // 8, sign=False))
            self.old_dvs.add(addr)

        # Special struct for stack frame
        if self.remote_arch.name == 'x86_64':
            width = self.registers['rbp'] - self.registers[
                'rsp'] + self.remote_arch.address_size
            if width > 0:
                if width > 0x1000:
                    width = 0x1000
                struct = Structure()
                struct.type = StructureType.StructStructureType
                struct.width = width
                for i in range(0, width, self.remote_arch.address_size):
                    var_name = "var_{:x}".format(width - i)
                    struct.insert(i, Type.pointer(self.remote_arch,
                                                  Type.void()), var_name)
                self.memory_view.define_data_var(self.registers['rsp'],
                                                 Type.structure_type(struct))
                self.memory_view.define_auto_symbol(
                    Symbol(SymbolType.ExternalSymbol,
                           self.registers['rsp'],
                           "$stack_frame",
                           raw_name="$stack_frame"))

                self.old_symbols.append(
                    self.memory_view.get_symbol_by_raw_name("$stack_frame"))
                self.old_dvs.add(self.registers['rsp'])
        else:
            pass
コード例 #7
0
ファイル: binjaplug.py プロジェクト: joshwatson/debugger
	def update_memory_view(self):
		if self.adapter == None:
			raise Exception('missing adapter')
		if self.memory_view == None:
			raise Exception('missing memory_view')

		addr_regs = {}
		reg_addrs = {}

		for reg in self.adapter.reg_list():
			addr = self.adapter.reg_read(reg)
			reg_symbol_name = '$' + reg

			if addr not in addr_regs.keys():
				addr_regs[addr] = [reg_symbol_name]
			else:
				addr_regs[addr].append(reg_symbol_name)
			reg_addrs[reg] = addr

		for symbol in self.old_symbols:
			# Symbols are immutable so just destroy the old one
			self.memory_view.undefine_auto_symbol(symbol)

		for dv in self.old_dvs:
			self.memory_view.undefine_data_var(dv)

		self.old_symbols = []
		self.old_dvs = set()
		new_dvs = set()

		for (reg, addr) in reg_addrs.items():
			symbol_name = '$' + reg
			self.memory_view.define_auto_symbol(Symbol(SymbolType.ExternalSymbol, addr, symbol_name, namespace=symbol_name))
			self.old_symbols.append(self.memory_view.get_symbol_by_raw_name(symbol_name, namespace=symbol_name))
			new_dvs.add(addr)

		for new_dv in new_dvs:
			self.memory_view.define_data_var(new_dv, Type.int(8))
			self.old_dvs.add(new_dv)

		# Special struct for stack frame
		if self.bv.arch.name == 'x86_64':
			width = reg_addrs['rbp'] - reg_addrs['rsp'] + self.bv.arch.address_size
			if width > 0:
				if width > 0x1000:
					width = 0x1000
				struct = Structure()
				struct.type = StructureType.StructStructureType
				struct.width = width
				for i in range(0, width, self.bv.arch.address_size):
					var_name = "var_{:x}".format(width - i)
					struct.insert(i, Type.pointer(self.bv.arch, Type.void()), var_name)
				self.memory_view.define_data_var(reg_addrs['rsp'], Type.structure_type(struct))
				self.memory_view.define_auto_symbol(Symbol(SymbolType.ExternalSymbol, reg_addrs['rsp'], "$stack_frame", raw_name="$stack_frame"))

				self.old_symbols.append(self.memory_view.get_symbol_by_raw_name("$stack_frame"))
				self.old_dvs.add(reg_addrs['rsp'])
		else:
			raise NotImplementedError('only x86_64 so far')
コード例 #8
0
ファイル: types.py プロジェクト: planetminguez/ObjCGraphView
def _parse_structure(type_string: str, view: BinaryView) -> Type:
    type_name = ''.join(
        takewhile(lambda i: i != '=', type_string)
    )

    type_string = type_string[len(type_name)+1:]

    fields = []
    while type_string:
        if type_string[0] == '{':
            field_type, type_string = _parse_structure(type_string[1:], view)
            fields.append(field_type)

        elif type_string[0] == '}':
            type_string = type_string[1:]
            break

        elif type_string[0] == '[':
            array_size = ''.join(takewhile(str.isdigit, type_string[1:]))
            array_type = ''.join(
                takewhile(lambda i: i != ']', type_string[1:])
            )
            type_string = type_string[len(array_size)+len(array_type)+2:]

            fields.append(
                Type.array(_lookup_type(array_type, view), int(array_size))
            )

        elif type_string[0] == ']':
            type_string = type_string[1:]
            continue

        elif _lookup_type(type_string[0], view):
            fields.append(_lookup_type(type_string[0], view))
            type_string = type_string[1:]

        else:
            log_debug(f"Not sure what is going on with this type: {type_string!r}")
            raise NotImplementedError(f"{type_string!r}")

    parsed_struct = Structure()

    for field in fields:
        parsed_struct.append(field)

    log_debug(f"Created {type_name}={parsed_struct}")
        
    view.define_user_type(type_name, Type.structure_type(parsed_struct))

    return (
        Type.named_type_from_type(
            type_name,
            view.types.get(type_name)
        ),
        type_string
    )
コード例 #9
0
ファイル: method_t.py プロジェクト: trailofbits/ObjCGraphView
    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)
コード例 #10
0
    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
コード例 #11
0
    def create_vmt_struct(bv: BinaryView, vmt: DelphiVMT) -> bool:
        if not vmt.is_valid:
            return False

        vmt_struct = types.Structure()

        if not BNHelpers._add_vmt_fields(bv, vmt, vmt_struct):
            return False

        if not BNHelpers._add_vmt_methods(bv, vmt, vmt_struct):
            return False

        struct_type = Type.structure_type(vmt_struct)
        bv.define_user_data_var(vmt.start, struct_type)
        # bv.define_user_type(f'vmt{vmt.class_name}', struct_type)

        # Create Symbole for VMT
        vmt_sym = Symbol(SymbolType.DataSymbol, vmt.start, f'vmt{vmt.class_name}')
        bv.define_user_symbol(vmt_sym)
        return True
コード例 #12
0
ファイル: binja_import.py プロジェクト: zznop/bnida
    def import_structures(self, structs):
        """
        Import structures into BN database

        :param structs: Dict containing structure/type info
        """

        for struct_name, struct_info in structs.items():
            struct = types.Structure()
            for member_name, member_info in struct_info['members'].items():
                try:
                    typ, _ = self.bv.parse_type_string('{}'.format(
                        member_info['type']))
                except SyntaxError:
                    print('Failed to apply type ({}) to member ({}): ({})'.format(
                        member_info['type'], member_name, struct_name))
                    typ, _ = self.bv.parse_type_string('uint8_t [{}]'.format(
                        member_info['size']))
                struct.insert(int(member_info['offset']), typ, member_name)

            self.bv.define_user_type(struct_name, Type.structure_type(struct))
コード例 #13
0
    def define_type(self):
        structure = Structure()
        structure.type = StructureType.ClassStructureType
        structure.width = self.vtable.instanceSize

        structure.insert(0, Type.pointer(self._view.arch, Type.void()), 'isa')

        classes = [self]
        current_superclass = self.superclass
        while current_superclass:
            classes.append(current_superclass)
            current_superclass = current_superclass.superclass

        while classes:
            current_class = classes.pop()
            if current_class.vtable.ivars is None:
                continue

            ivar_list = current_class.vtable.ivars
            for name, ivar in ivar_list.ivars.items():
                structure.insert(ivar.offset, ivar.type, name)

        self._view.define_user_type(self.vtable.name,
                                    Type.structure_type(structure))
コード例 #14
0
from binaryninja import (
    Architecture,
    FunctionParameter,
    Platform,
    QualifiedName,
    Type,
    TypeLibrary,
    Structure
)

advapi32_x86 = TypeLibrary.new(Architecture["x86"], "advapi32.dll")

advapi32_x86.add_platform(Platform["windows-x86"])

BOOL = Type.int(4, altname="BOOL")
HCRYPTPROV_type = Type.structure_type(Structure())
HCRYPTPROV = Type.named_type_from_type(
    "HCRYPTPROV", HCRYPTPROV_type
)

LPCSTR_type = Type.pointer(Architecture["x86"], Type.char())
LPCSTR = Type.named_type_from_type('LPCSTR', LPCSTR_type)

DWORD = Type.int(4, sign=False, altname="DWORD")

advapi32_x86.add_named_type("HCRYPTPROV", HCRYPTPROV_type)

CryptAcquireContextA = Type.function(
    BOOL,
    [
        FunctionParameter(