示例#1
0
def preprocess_source(source, filename=None, include_dirs=[]):
    """
	``preprocess_source`` run the C preprocessor on the given source or source filename.

	:param str source: source to pre-process
	:param str filename: optional filename to pre-process
	:param list(str) include_dirs: list of string directories to use as include directories.
	:return: returns a tuple of (preprocessed_source, error_string)
	:rtype: tuple(str,str)
	:Example:

		>>> source = "#define TEN 10\\nint x[TEN];\\n"
		>>> preprocess_source(source)
		('#line 1 "input"\\n\\n#line 2 "input"\\n int x [ 10 ] ;\\n', '')
		>>>
	"""
    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')
    output = ctypes.c_char_p()
    errors = ctypes.c_char_p()
    result = core.BNPreprocessSource(source, filename, output, errors, dir_buf,
                                     len(include_dirs))
    output_str = output.value
    error_str = errors.value
    core.BNFreeString(ctypes.cast(output, ctypes.POINTER(ctypes.c_byte)))
    core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
    if result:
        return (output_str, error_str)
    return (None, error_str)
示例#2
0
def get_open_filename_input(prompt, ext=""):
    """
	``get_open_filename_input`` prompts the user for a file name to open

	Note: This API function differently on the command-line vs the UI. In the UI a pop-up is used. On the command-line
	a simple text prompt is used. The UI uses the native window pop-up for file selection.

	Multiple file selection groups can be included if separated by two semicolons. Multiple file wildcards may be specified by using a space within the parenthesis.

	Also, a simple selector of "*.extension" by itself may also be used instead of specifying the description.

	:param str prompt: Prompt to display.
	:param str ext: Optional, file extension
	:Example:
		>>> get_open_filename_input("filename:", "Executables (*.exe *.com);;Python Files (*.py);;All Files (*)")
		b'foo.exe'
		>>> get_open_filename_input("filename:", "*.py")
		b'test.py'
	"""
    value = ctypes.c_char_p()
    if not core.BNGetOpenFileNameInput(value, prompt, ext):
        return None
    result = value.value
    core.BNFreeString(ctypes.cast(value, ctypes.POINTER(ctypes.c_byte)))
    return result
示例#3
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)
示例#4
0
	def update(self, progress = None):
		cb = UpdateProgressCallback(progress)
		errors = ctypes.c_char_p()
		result = core.BNUpdateToVersion(self.channel.name, self.version, errors, cb.cb, None)
		if errors:
			error_str = errors.value
			core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
			raise IOError(error_str)
		return UpdateResult(result)
示例#5
0
	def updates_available(self):
		"""Whether updates are available (read-only)"""
		errors = ctypes.c_char_p()
		result = core.BNAreUpdatesAvailable(self.name, None, None, errors)
		if errors:
			error_str = errors.value
			core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
			raise IOError(error_str)
		return result
示例#6
0
def install_pending_update():
	"""
	``install_pending_update`` installs any pending updates

	:rtype: None
	"""
	errors = ctypes.c_char_p()
	core.BNInstallPendingUpdate(errors)
	if errors:
		error_str = errors.value
		core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
		raise IOError(error_str)
示例#7
0
	def __iter__(self):
		binaryninja._init_plugins()
		count = ctypes.c_ulonglong()
		errors = ctypes.c_char_p()
		channels = core.BNGetUpdateChannels(count, errors)
		if errors:
			error_str = errors.value
			core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
			raise IOError(error_str)
		try:
			for i in range(0, count.value):
				yield UpdateChannel(channels[i].name, channels[i].description, channels[i].latestVersion)
		finally:
			core.BNFreeUpdateChannelList(channels, count.value)
示例#8
0
	def list(self):
		binaryninja._init_plugins()
		count = ctypes.c_ulonglong()
		errors = ctypes.c_char_p()
		channels = core.BNGetUpdateChannels(count, errors)
		if errors:
			error_str = errors.value
			core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
			raise IOError(error_str)
		result = []
		for i in range(0, count.value):
			result.append(UpdateChannel(channels[i].name, channels[i].description, channels[i].latestVersion))
		core.BNFreeUpdateChannelList(channels, count.value)
		return result
示例#9
0
	def versions(self):
		"""List of versions (read-only)"""
		count = ctypes.c_ulonglong()
		errors = ctypes.c_char_p()
		versions = core.BNGetUpdateChannelVersions(self.name, count, errors)
		if errors:
			error_str = errors.value
			core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
			raise IOError(error_str)
		result = []
		for i in range(0, count.value):
			result.append(UpdateVersion(self, versions[i].version, versions[i].notes, versions[i].time))
		core.BNFreeUpdateChannelVersionList(versions, count.value)
		return result
示例#10
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)
示例#11
0
	def latest_version(self):
		"""Latest version (read-only)"""
		count = ctypes.c_ulonglong()
		errors = ctypes.c_char_p()
		versions = core.BNGetUpdateChannelVersions(self.name, count, errors)
		if errors:
			error_str = errors.value
			core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
			raise IOError(error_str)
		result = None
		for i in range(0, count.value):
			if versions[i].version == self.latest_version_num:
				result = UpdateVersion(self, versions[i].version, versions[i].notes, versions[i].time)
				break
		core.BNFreeUpdateChannelVersionList(versions, count.value)
		return result
示例#12
0
	def __getitem__(cls, name):
		binaryninja._init_plugins()
		count = ctypes.c_ulonglong()
		errors = ctypes.c_char_p()
		channels = core.BNGetUpdateChannels(count, errors)
		if errors:
			error_str = errors.value
			core.BNFreeString(ctypes.cast(errors, ctypes.POINTER(ctypes.c_byte)))
			raise IOError(error_str)
		result = None
		for i in range(0, count.value):
			if channels[i].name == str(name):
				result = UpdateChannel(channels[i].name, channels[i].description, channels[i].latestVersion)
				break
		core.BNFreeUpdateChannelList(channels, count.value)
		if result is None:
			raise KeyError("'%s' is not a valid channel" % str(name))
		return result
示例#13
0
def get_directory_name_input(prompt, default_name=""):
    """
	``get_directory_name_input`` prompts the user for a directory name to save as, optionally providing a default_name

	Note: This API function differently on the command-line vs the UI. In the UI a pop-up is used. On the command-line a simple text prompt is used. The UI uses the native window pop-up for file selection.

	:param str prompt: Prompt to display.
	:param str default_name: Optional, default directory name.
	:rtype: str
	:Example:
		>>> get_directory_name_input("prompt")
		prompt dirname
		'dirname'
	"""
    value = ctypes.c_char_p()
    if not core.BNGetDirectoryNameInput(value, prompt, default_name):
        return None
    result = value.value
    core.BNFreeString(ctypes.cast(value, ctypes.POINTER(ctypes.c_byte)))
    return result
示例#14
0
def get_open_filename_input(prompt, ext=""):
    """
	``get_open_filename_input`` prompts the user for a file name to open

	Note: This API function differently on the command-line vs the UI. In the UI a pop-up is used. On the command-line
	a simple text prompt is used. The UI uses the native window pop-up for file selection.

	:param str prompt: Prompt to display.
	:param str ext: Optional, file extension
	:Example:
		>>> get_open_filename_input("filename:", "exe")
		filename: foo.exe
		'foo.exe'
	"""
    value = ctypes.c_char_p()
    if not core.BNGetOpenFileNameInput(value, prompt, ext):
        return None
    result = value.value
    core.BNFreeString(ctypes.cast(value, ctypes.POINTER(ctypes.c_byte)))
    return result
示例#15
0
def get_text_line_input(prompt, title):
    """
	``get_text_line_input`` prompts the user to input a string with the given prompt and title

	Note: This API function differently on the command-line vs the UI. In the UI a pop-up is used. On the command-line
	a simple text prompt is used.

	:param str prompt: String to prompt with.
	:param str title: Title of the window when executed in the UI.
	:rtype: str containing the input without trailing newline character.
	:Example:
		>>> get_text_line_input("PROMPT>", "getinfo")
		PROMPT> Input!
		'Input!'
	"""
    value = ctypes.c_char_p()
    if not core.BNGetTextLineInput(value, prompt, title):
        return None
    result = value.value
    core.BNFreeString(ctypes.cast(value, ctypes.POINTER(ctypes.c_byte)))
    return result
示例#16
0
def get_save_filename_input(prompt, ext="", default_name=""):
    """
	``get_save_filename_input`` prompts the user for a file name to save as, optionally providing a file extension and
	default_name.

	Note: This API function differently on the command line vs. the UI. In the UI a popup is used. On the commandline
	      a simple text prompt is used. The ui uses the native window popup for file selection.

	:param str prompt: Prompt to display.
	:param str ext: Optional, file extension
	:param str default_name: Optional, default file name.
	:Example:
		>>> get_save_filename_input("filename:", "exe", "foo.exe")
		filename: foo.exe
		'foo.exe'
	"""
    value = ctypes.c_char_p()
    if not core.BNGetSaveFileNameInput(value, prompt, ext, default_name):
        return None
    result = value.value
    core.BNFreeString(ctypes.cast(value, ctypes.POINTER(ctypes.c_byte)))
    return result