Beispiel #1
0
    def parse_types_from_source(self,
                                source,
                                filename=None,
                                include_dirs=[],
                                auto_type_source=None):
        """
		``parse_types_from_source`` parses the source string and any needed headers searching for them in
		the optional list of directories provided in ``include_dirs``.

		:param str source: source string to be parsed
		:param str filename: optional source filename
		:param list(str) include_dirs: optional list of string filename include directories
		:param str auto_type_source: optional source of types if used for automatically generated types
		:return: :py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
		:rtype: TypeParserResult
		:Example:

			>>> platform.parse_types_from_source('int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n')
			({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:{'bar':
			<type: int32_t(int32_t x)>}}, '')
			>>>
		"""

        if filename is None:
            filename = "input"
        dir_buf = (ctypes.c_char_p * len(include_dirs))()
        for i in range(0, len(include_dirs)):
            dir_buf[i] = include_dirs[i].encode('charmap')
        parse = core.BNTypeParserResult()
        errors = ctypes.c_char_p()
        result = core.BNParseTypesFromSource(self.handle, source, filename,
                                             parse, errors, dir_buf,
                                             len(include_dirs),
                                             auto_type_source)
        error_str = errors.value
        core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
        if not result:
            raise SyntaxError(error_str)
        type_dict = {}
        variables = {}
        functions = {}
        for i in range(0, parse.typeCount):
            name = types.QualifiedName._from_core_struct(parse.types[i].name)
            type_dict[name] = types.Type(core.BNNewTypeReference(
                parse.types[i].type),
                                         platform=self)
        for i in range(0, parse.variableCount):
            name = types.QualifiedName._from_core_struct(
                parse.variables[i].name)
            variables[name] = types.Type(core.BNNewTypeReference(
                parse.variables[i].type),
                                         platform=self)
        for i in range(0, parse.functionCount):
            name = types.QualifiedName._from_core_struct(
                parse.functions[i].name)
            functions[name] = types.Type(core.BNNewTypeReference(
                parse.functions[i].type),
                                         platform=self)
        core.BNFreeTypeParserResult(parse)
        return types.TypeParserResult(type_dict, variables, functions)
Beispiel #2
0
    def _get_lines_for_data(self, ctxt, view, addr, type, prefix, prefixCount,
                            width, count, typeCtx, ctxCount):
        try:
            file_metadata = filemetadata.FileMetadata(
                handle=core.BNGetFileForView(view))
            view = binaryview.BinaryView(file_metadata=file_metadata,
                                         handle=core.BNNewViewReference(view))
            type = types.Type(handle=core.BNNewTypeReference(type))

            prefixTokens = function.InstructionTextToken.get_instruction_lines(
                prefix, prefixCount)
            pycontext = []
            for i in range(ctxCount):
                pycontext.append(
                    TypeContext(
                        types.Type(core.BNNewTypeReference(typeCtx[i].type)),
                        typeCtx[i].offset))

            result = self.perform_get_lines_for_data(ctxt, view, addr, type,
                                                     prefixTokens, width,
                                                     pycontext)

            count[0] = len(result)
            line_buf = (core.BNDisassemblyTextLine * len(result))()
            for i in range(len(result)):
                line = result[i]
                color = line.highlight
                if not isinstance(
                        color,
                        enums.HighlightStandardColor) and not isinstance(
                            color, highlight.HighlightColor):
                    raise ValueError(
                        "Specified color is not one of HighlightStandardColor, highlight.HighlightColor"
                    )
                if isinstance(color, enums.HighlightStandardColor):
                    color = highlight.HighlightColor(color)
                line_buf[i].highlight = color._get_core_struct()
                if line.address is None:
                    if len(line.tokens) > 0:
                        line_buf[i].addr = line.tokens[0].address
                    else:
                        line_buf[i].addr = 0
                else:
                    line_buf[i].addr = line.address
                if line.il_instruction is not None:
                    line_buf[i].instrIndex = line.il_instruction.instr_index
                else:
                    line_buf[i].instrIndex = 0xffffffffffffffff

                line_buf[i].count = len(line.tokens)
                line_buf[
                    i].tokens = function.InstructionTextToken.get_instruction_lines(
                        line.tokens)

            return ctypes.cast(line_buf, ctypes.c_void_p).value
        except:
            log.log_error(traceback.format_exc())
            return None
Beispiel #3
0
	def parse_types_from_source_file(self, filename, include_dirs=[], auto_type_source=None):
		"""
		``parse_types_from_source_file`` parses the source file ``filename`` and any needed headers searching for them in
		the optional list of directories provided in ``include_dirs``.

		:param str filename: filename of file to be parsed
		:param include_dirs: optional list of string filename include directories
		:type include_dirs: list(str)
		:param str auto_type_source: optional source of types if used for automatically generated types
		:return: :py:class:`TypeParserResult` (a SyntaxError is thrown on parse error)
		:rtype: TypeParserResult
		:Example:

			>>> file = "/Users/binja/tmp.c"
			>>> open(file).read()
			'int foo;\\nint bar(int x);\\nstruct bas{int x,y;};\\n'
			>>> platform.parse_types_from_source_file(file)
			({types: {'bas': <type: struct bas>}, variables: {'foo': <type: int32_t>}, functions:
			{'bar': <type: int32_t(int32_t x)>}}, '')
			>>>
		"""
		if not (isinstance(filename, str) and os.path.isfile(filename) and os.access(filename, os.R_OK)):
			 raise AttributeError("File {} doesn't exist or isn't readable".format(filename))
		dir_buf = (ctypes.c_char_p * len(include_dirs))()
		for i in range(0, len(include_dirs)):
			dir_buf[i] = include_dirs[i].encode('charmap')
		parse = core.BNTypeParserResult()
		errors = ctypes.c_char_p()
		result = core.BNParseTypesFromSourceFile(self.handle, filename, parse, errors, dir_buf,
			len(include_dirs), auto_type_source)
		error_str = errors.value.decode("utf-8")
		core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
		if not result:
			raise SyntaxError(error_str)
		type_dict = {}
		variables = {}
		functions = {}
		for i in range(0, parse.typeCount):
			name = types.QualifiedName._from_core_struct(parse.types[i].name)
			type_dict[name] = types.Type(core.BNNewTypeReference(parse.types[i].type), platform = self)
		for i in range(0, parse.variableCount):
			name = types.QualifiedName._from_core_struct(parse.variables[i].name)
			variables[name] = types.Type(core.BNNewTypeReference(parse.variables[i].type), platform = self)
		for i in range(0, parse.functionCount):
			name = types.QualifiedName._from_core_struct(parse.functions[i].name)
			functions[name] = types.Type(core.BNNewTypeReference(parse.functions[i].type), platform = self)
		core.BNFreeTypeParserResult(parse)
		return types.TypeParserResult(type_dict, variables, functions)
Beispiel #4
0
 def _is_valid_for_data(self, ctxt, view, addr, type, context, ctxCount):
     try:
         file_metadata = filemetadata.FileMetadata(
             handle=core.BNGetFileForView(view))
         view = binaryview.BinaryView(file_metadata=file_metadata,
                                      handle=core.BNNewViewReference(view))
         type = types.Type(handle=core.BNNewTypeReference(type))
         pycontext = []
         for i in range(0, ctxCount):
             pycontext.append(
                 types.Type(core.BNNewTypeReference(context[i])))
         return self.perform_is_valid_for_data(ctxt, view, addr, type,
                                               pycontext)
     except:
         log.log_error(traceback.format_exc())
         return False
def demangle_ms(arch, mangled_name):
    """
	``demangle_ms`` demangles a mangled Microsoft Visual Studio C++ name to a Type object.

	:param Architecture arch: Architecture for the symbol. Required for pointer and integer sizes.
	:param str mangled_name: a mangled Microsoft Visual Studio C++ name
	:return: returns tuple of (Type, demangled_name) or (None, mangled_name) on error
	:rtype: Tuple
	:Example:

		>>> demangle_ms(Architecture["x86_64"], "?testf@Foobar@@SA?AW4foo@1@W421@@Z")
		(<type: public: static enum Foobar::foo __cdecl (enum Foobar::foo)>, ['Foobar', 'testf'])
		>>>
	"""
    handle = ctypes.POINTER(core.BNType)()
    outName = ctypes.POINTER(ctypes.c_char_p)()
    outSize = ctypes.c_ulonglong()
    names = []
    if core.BNDemangleMS(arch.handle, mangled_name, ctypes.byref(handle),
                         ctypes.byref(outName), ctypes.byref(outSize)):
        for i in range(outSize.value):
            names.append(pyNativeStr(outName[i]))
        core.BNFreeDemangledName(ctypes.byref(outName), outSize.value)
        return (types.Type(handle), names)
    return (None, mangled_name)
Beispiel #6
0
def demangle_gnu3(arch, mangled_name, options=None):
    """
	``demangle_gnu3`` demangles a mangled name to a Type object.

	:param Architecture arch: Architecture for the symbol. Required for pointer and integer sizes.
	:param str mangled_name: a mangled GNU3 name
	:param options: (optional) Whether to simplify demangled names : None falls back to user settings, a BinaryView uses that BinaryView's settings, or a boolean to set it directally
	:type options: Tuple[bool, BinaryView, None]
	:return: returns tuple of (Type, demangled_name) or (None, mangled_name) on error
	:rtype: Tuple
	"""
    handle = ctypes.POINTER(core.BNType)()
    outName = ctypes.POINTER(ctypes.c_char_p)()
    outSize = ctypes.c_ulonglong()
    names = []
    if (isinstance(options, BinaryView) and core.BNDemangleGNU3WithOptions(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), options)) or \
     (isinstance(options, bool) and core.BNDemangleGNU3(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), options)) or \
     (options is None and core.BNDemangleGNU3WithOptions(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), None)):
        for i in range(outSize.value):
            names.append(pyNativeStr(outName[i]))
        core.BNFreeDemangledName(ctypes.byref(outName), outSize.value)
        if not handle:
            return (None, names)
        return (types.Type(handle), names)
    return (None, mangled_name)
Beispiel #7
0
def demangle_ms(arch, mangled_name, options=False):
    """
	``demangle_ms`` demangles a mangled Microsoft Visual Studio C++ name to a Type object.

	:param Architecture arch: Architecture for the symbol. Required for pointer and integer sizes.
	:param str mangled_name: a mangled Microsoft Visual Studio C++ name
	:param options: (optional) Whether to simplify demangled names : None falls back to user settings, a BinaryView uses that BinaryView's settings, or a boolean to set it directally
	:type options: Tuple[bool, BinaryView, None]
	:return: returns tuple of (Type, demangled_name) or (None, mangled_name) on error
	:rtype: Tuple
	:Example:

		>>> demangle_ms(Architecture["x86_64"], "?testf@Foobar@@SA?AW4foo@1@W421@@Z")
		(<type: public: static enum Foobar::foo __cdecl (enum Foobar::foo)>, ['Foobar', 'testf'])
		>>>
	"""
    handle = ctypes.POINTER(core.BNType)()
    outName = ctypes.POINTER(ctypes.c_char_p)()
    outSize = ctypes.c_ulonglong()
    names = []
    if (isinstance(options, BinaryView) and core.BNDemangleMSWithOptions(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), options)) or \
     (isinstance(options, bool) and core.BNDemangleMS(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), options)) or \
     (options is None and core.BNDemangleMSWithOptions(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize), None)):
        for i in range(outSize.value):
            names.append(pyNativeStr(outName[i]))
        core.BNFreeDemangledName(ctypes.byref(outName), outSize.value)
        return (types.Type(handle), names)
    return (None, mangled_name)
	def expr_type(self):
		"""Type of expression"""
		result = core.BNGetHighLevelILExprType(self._function.handle, self._expr_index)
		if result.type:
			platform = None
			if self._function.source_function:
				platform = self._function.source_function.platform
			return types.Type(result.type, platform = platform, confidence = result.confidence)
		return None
	def functions(self):
		"""List of platform-specific function definitions (read-only)"""
		count = ctypes.c_ulonglong(0)
		type_list = core.BNGetPlatformFunctions(self.handle, count)
		result = {}
		for i in range(0, count.value):
			name = types.QualifiedName._from_core_struct(type_list[i].name)
			result[name] = types.Type(core.BNNewTypeReference(type_list[i].type), platform = self)
		core.BNFreeTypeList(type_list, count.value)
		return result
Beispiel #10
0
	def system_calls(self):
		"""List of system calls for this platform (read-only)"""
		count = ctypes.c_ulonglong(0)
		call_list = core.BNGetPlatformSystemCalls(self.handle, count)
		result = {}
		for i in range(0, count.value):
			name = types.QualifiedName._from_core_struct(call_list[i].name)
			t = types.Type(core.BNNewTypeReference(call_list[i].type), platform = self)
			result[call_list[i].number] = (name, t)
		core.BNFreeSystemCallList(call_list, count.value)
		return result
Beispiel #11
0
	def named_types(self):
		"""
		A dict containing all named types provided by a type library (read-only)
		"""
		count = ctypes.c_ulonglong(0)
		result = {}
		named_types = core.BNGetTypeLibraryNamedTypes(self.handle, count)
		for i in range(0, count.value):
			name = types.QualifiedName._from_core_struct(named_types[i].name)
			result[name] = types.Type(core.BNNewTypeReference(named_types[i].type))
		core.BNFreeQualifiedNameAndTypeArray(named_types, count.value)
		return result
Beispiel #12
0
def demangle_gnu3(arch, mangled_name):
	handle = ctypes.POINTER(core.BNType)()
	outName = ctypes.POINTER(ctypes.c_char_p)()
	outSize = ctypes.c_ulonglong()
	names = []
	if core.BNDemangleGNU3(arch.handle, mangled_name, ctypes.byref(handle), ctypes.byref(outName), ctypes.byref(outSize)):
		for i in range(outSize.value):
			names.append(pyNativeStr(outName[i]))
		core.BNFreeDemangledName(ctypes.byref(outName), outSize.value)
		if not handle:
			return (None, names)
		return (types.Type(handle), names)
	return (None, mangled_name)
Beispiel #13
0
	def get_named_type(self, name):
		"""
		`get_named_type` direct extracts a reference to a contained type -- when
		attempting to extract types from a library into a BinaryView, consider using
		:py:meth:`import_library_type <binaryninja.binaryview.BinaryView.import_library_type>` instead.

		:param QualifiedName name:
		:rtype: Type
		"""
		if not isinstance(name, types.QualifiedName):
			name = types.QualifiedName(name)
		t = core.BNGetTypeLibraryNamedType(self.handle, name._get_core_struct())
		if t is None:
			return None
		return types.Type(t)
Beispiel #14
0
 def get_system_call_type(self, number):
     obj = core.BNGetPlatformSystemCallType(self.handle, number)
     if not obj:
         return None
     return types.Type(obj, platform=self)
Beispiel #15
0
 def get_function_by_name(self, name, exactMatch=False):
     name = types.QualifiedName(name)._get_core_struct()
     obj = core.BNGetPlatformFunctionByName(self.handle, name, exactMatch)
     if not obj:
         return None
     return types.Type(obj, platform=self)
Beispiel #16
0
 def get_variable_by_name(self, name):
     name = types.QualifiedName(name)._get_core_struct()
     obj = core.BNGetPlatformVariableByName(self.handle, name)
     if not obj:
         return None
     return types.Type(obj, platform=self)