예제 #1
0
    def load_file(self, acting_client):
        self.reset_state(acting_client)

        # Request a file name to load.
        result = acting_client.request_load_file()
        if result is None:
            return
        if type(result) is str:
            self.reset_state(acting_client)
            return result
        load_file, file_path = result

        self.state_id = EditorState.STATE_LOADING
        file_name = os.path.basename(file_path)
        is_saved_project = disassembly_persistence.check_is_project_file(
            load_file)

        for client in self.clients:
            client.event_load_start(client is acting_client, file_path)

        if is_saved_project:
            disassembly_state = self._prolonged_action(
                acting_client, "TITLE_LOADING_PROJECT", "TEXT_GENERIC_LOADING",
                disassembly.load_project_file, load_file, file_name)
        else:
            new_options = disassembly.get_new_project_options()
            identify_result = loaderlib.identify_file(load_file, file_name)
            # Parameters passed in, to help the client make up it's mind.
            if identify_result is not None:
                new_options.is_binary_file = False
                new_options.loader_load_address = loaderlib.get_load_address(
                    identify_result[0])
                new_options.loader_entrypoint_offset = loaderlib.get_entrypoint_address(
                    identify_result[0])
                new_options.loader_filetype = identify_result[1]["filetype"]
                new_options.loader_processor = identify_result[1]["processor"]
            else:
                new_options.is_binary_file = True
                new_options.loader_load_address = 0
                new_options.loader_entrypoint_offset = 0
                new_options.loader_filetype = loaderlib.constants.FILE_FORMAT_UNKNOWN
                new_options.loader_processor = ""
            # Prompt for new project option values.
            new_option_result = acting_client.request_new_project_option_values(
                new_options)
            if new_option_result is None or type(new_option_result) is str:
                self.reset_state(acting_client)
                return new_option_result

            disassembly_state = self._prolonged_action(
                acting_client, "TITLE_LOADING_FILE", "TEXT_GENERIC_LOADING",
                disassembly.load_file, load_file, new_option_result, file_name)

        # Loading was cancelled.
        if disassembly_state is None:
            self.reset_state(acting_client)
            return

        self.state_id = EditorState.STATE_LOADED
        self.disassembly_state = disassembly_state

        # Register our event dispatching callbacks.
        self.disassembly_state.set_uncertain_reference_modification_func(
            self._uncertain_reference_modification_callback)
        self.disassembly_state.set_symbol_insert_func(
            self._symbol_insert_callback)
        self.disassembly_state.set_symbol_delete_func(
            self._symbol_delete_callback)

        line_count = self.disassembly_state.get_file_line_count()
        if line_count == 0:
            self.reset_state(acting_client)
            return ERRMSG_NOT_SUPPORTED_EXECUTABLE_FILE_FORMAT

        is_saved_project = disassembly_persistence.check_is_project_file(
            acting_client.get_load_file())
        if is_saved_project:
            # User may have optionally chosen to not save the input file, as part of the project file.
            if not self.disassembly_state.is_segment_data_cached():
                load_options = disassembly.get_new_project_options()
                # Parameters passed in, to help the client make up it's mind.
                load_options.input_file_filesize = self.disassembly_state.get_file_size(
                )
                load_options.input_file_filename = self.disassembly_state.get_file_name(
                )
                load_options.input_file_checksum = self.disassembly_state.get_file_checksum(
                )
                # Parameters received out, our "return values".
                load_options.loader_file_path = None
                load_options = acting_client.request_load_project_option_values(
                    load_options)

                if load_options.loader_file_path is None:
                    self.reset_state(acting_client)
                    return ERRMSG_INPUT_FILE_NOT_FOUND

                # Verify that the given input file is valid, or error descriptively.
                with open(load_options.loader_file_path,
                          "rb") as input_data_file:
                    input_data_file.seek(0, os.SEEK_END)
                    errmsg = None
                    if input_data_file.tell(
                    ) != self.disassembly_state.get_file_size():
                        errmsg = ERRMSG_INPUT_FILE_SIZE_DIFFERS
                    elif util.calculate_file_checksum(
                            input_data_file
                    ) != self.disassembly_state.get_file_checksum():
                        errmsg = ERRMSG_INPUT_FILE_CHECKSUM_MISMATCH
                    if type(errmsg) is str:
                        self.reset_state(acting_client)
                        return errmsg
                    self.disassembly_state.load_project_file_finalise(
                        input_data_file)

        entrypoint_address = self.disassembly_state.get_entrypoint_address()
        line_number = self.disassembly_state.get_line_number_for_address(
            entrypoint_address)
        self.set_line_number(acting_client, line_number)

        def _pre_line_change_callback(line0, line_count):
            for client in self.clients:
                client.event_pre_line_change(client is acting_client, line0,
                                             line_count)

        self.disassembly_state.set_pre_line_change_func(
            _pre_line_change_callback)

        def _post_line_change_callback(line0, line_count):
            for client in self.clients:
                client.event_post_line_change(client is acting_client, line0,
                                              line_count)

        self.disassembly_state.set_post_line_change_func(
            _post_line_change_callback)

        for client in self.clients:
            client.event_load_successful(client is acting_client)
        return result
예제 #2
0
    def load_file(self, acting_client):
        self.reset_state(acting_client)

        # Request a file name to load.
        result = acting_client.request_load_file()
        if result is None:
            return
        if type(result) is str:
            self.reset_state(acting_client)
            return result
        load_file, file_path = result

        self.state_id = EditorState.STATE_LOADING
        file_name = os.path.basename(file_path)
        is_saved_project = disassembly_persistence.check_is_project_file(load_file)

        for client in self.clients:
            client.event_load_start(client is acting_client, file_path)

        if is_saved_project:
            disassembly_state = self._prolonged_action(acting_client, "TITLE_LOADING_PROJECT", "TEXT_GENERIC_LOADING", disassembly.load_project_file, load_file, file_name)
        else:
            new_options = disassembly.get_new_project_options()
            identify_result = loaderlib.identify_file(load_file, file_name)
            # Parameters passed in, to help the client make up it's mind.
            if identify_result is not None:
                new_options.is_binary_file = False
                new_options.loader_load_address = loaderlib.get_load_address(identify_result[0])
                new_options.loader_entrypoint_offset = loaderlib.get_entrypoint_address(identify_result[0])
                new_options.loader_filetype = identify_result[1]["filetype"]
                new_options.loader_processor = identify_result[1]["processor"]
            else:
                new_options.is_binary_file = True
                new_options.loader_load_address = 0
                new_options.loader_entrypoint_offset = 0
                new_options.loader_filetype = loaderlib.constants.FILE_FORMAT_UNKNOWN
                new_options.loader_processor = ""
            # Prompt for new project option values.
            new_option_result = acting_client.request_new_project_option_values(new_options)
            if new_option_result is None or type(new_option_result) is str:
                self.reset_state(acting_client)
                return new_option_result

            disassembly_state = self._prolonged_action(acting_client, "TITLE_LOADING_FILE", "TEXT_GENERIC_LOADING", disassembly.load_file, load_file, new_option_result, file_name)

        # Loading was cancelled.
        if disassembly_state is None:
            self.reset_state(acting_client)
            return

        self.state_id = EditorState.STATE_LOADED
        self.disassembly_state = disassembly_state

        # Register our event dispatching callbacks.
        self.disassembly_state.set_uncertain_reference_modification_func(self._uncertain_reference_modification_callback)
        self.disassembly_state.set_symbol_insert_func(self._symbol_insert_callback)
        self.disassembly_state.set_symbol_delete_func(self._symbol_delete_callback)

        line_count = self.disassembly_state.get_file_line_count()
        if line_count == 0:
            self.reset_state(acting_client)
            return ERRMSG_NOT_SUPPORTED_EXECUTABLE_FILE_FORMAT

        is_saved_project = disassembly_persistence.check_is_project_file(acting_client.get_load_file())
        if is_saved_project:
            # User may have optionally chosen to not save the input file, as part of the project file.
            if not self.disassembly_state.is_segment_data_cached():
                load_options = disassembly.get_new_project_options()
                # Parameters passed in, to help the client make up it's mind.
                load_options.input_file_filesize = self.disassembly_state.get_file_size()
                load_options.input_file_filename = self.disassembly_state.get_file_name()
                load_options.input_file_checksum = self.disassembly_state.get_file_checksum()
                # Parameters received out, our "return values".
                load_options.loader_file_path = None
                load_options = acting_client.request_load_project_option_values(load_options)

                if load_options.loader_file_path is None:
                    self.reset_state(acting_client)
                    return ERRMSG_INPUT_FILE_NOT_FOUND

                # Verify that the given input file is valid, or error descriptively.
                with open(load_options.loader_file_path, "rb") as input_data_file:
                    input_data_file.seek(0, os.SEEK_END)
                    errmsg = None
                    if input_data_file.tell() != self.disassembly_state.get_file_size():
                        errmsg = ERRMSG_INPUT_FILE_SIZE_DIFFERS
                    elif util.calculate_file_checksum(input_data_file) != self.disassembly_state.get_file_checksum():
                        errmsg = ERRMSG_INPUT_FILE_CHECKSUM_MISMATCH
                    if type(errmsg) is str:
                        self.reset_state(acting_client)
                        return errmsg
                    self.disassembly_state.load_project_file_finalise(input_data_file)

        entrypoint_address = self.disassembly_state.get_entrypoint_address()
        line_number = self.disassembly_state.get_line_number_for_address(entrypoint_address)
        self.set_line_number(acting_client, line_number)

        def _pre_line_change_callback(line0, line_count):
            for client in self.clients:
                client.event_pre_line_change(client is acting_client, line0, line_count)
        self.disassembly_state.set_pre_line_change_func(_pre_line_change_callback)
        def _post_line_change_callback(line0, line_count):
            for client in self.clients:
                client.event_post_line_change(client is acting_client, line0, line_count)
        self.disassembly_state.set_post_line_change_func(_post_line_change_callback)

        for client in self.clients:
            client.event_load_successful(client is acting_client)
        return result
예제 #3
0
 def is_project_file(self, acting_client, input_file):
     return disassembly_persistence.check_is_project_file(input_file)
예제 #4
0
 def is_project_file(self, acting_client, input_file):
     return disassembly_persistence.check_is_project_file(input_file)