예제 #1
0
def main(argv=None):
    """Runs the tool.

    :param list argv: Tool arguments.

    If `argv` is ``None``, ``sys.argv`` is used.
    """
    args = parse_args(argv if argv is not None else sys.argv)

    decompiler = Decompiler(api_url=args.api_url, api_key=args.api_key)

    decompilation = decompiler.start_decompilation(
        input_file=args.input_file,
        mode=args.mode,
        generate_archive=args.generate_archive)

    displayer = get_progress_displayer(args)
    displayer.display_decompilation_progress(decompilation)
    decompilation.wait_until_finished(
        callback=displayer.display_decompilation_progress)

    output_dir = get_output_dir(args)

    file_path = decompilation.save_hll_code(output_dir)
    display_download_progress(displayer, file_path)

    file_path = decompilation.save_dsm_code(output_dir)
    display_download_progress(displayer, file_path)

    if args.generate_archive:
        decompilation.wait_until_archive_is_generated()
        file_path = decompilation.save_archive(output_dir)
        display_download_progress(displayer, file_path)

    return 0
예제 #2
0
    def test_repr_returns_correct_value(self):
        decompiler = Decompiler(api_key='API-KEY',
                                api_url='https://retdec.com/service/api/')

        self.assertEqual(
            repr(decompiler),
            "<retdec.decompiler.Decompiler api_url='https://retdec.com/service/api'>"
        )
예제 #3
0
    def setUp(self):
        super().setUp()

        self.input_file = mock.Mock(spec_set=File)

        self.decompiler = Decompiler(api_key='KEY')
예제 #4
0
class DecompilerStartDecompilationTests(BaseServiceTests):
    """Tests for :func:`retdec.decompiler.Decompiler.start_decompilation()`."""

    def setUp(self):
        super().setUp()

        self.input_file = mock.Mock(spec_set=File)

        self.decompiler = Decompiler(api_key='KEY')

    def start_decompilation(self, *args, **kwargs):
        """Starts a decompilation with the given parameters."""
        return self.decompiler.start_decompilation(*args, **kwargs)

    def start_decompilation_with_any_input_file(self, *args, **kwargs):
        """Starts a decompilation with the default input file and,
        additionally, the given parameters.
        """
        kwargs.setdefault('input_file', self.input_file)
        return self.decompiler.start_decompilation(*args, **kwargs)

    def test_creates_api_connection_with_correct_url_and_api_key(self):
        self.start_decompilation_with_any_input_file()

        self.APIConnectionMock.assert_called_once_with(
            'https://retdec.com/service/api/decompiler/decompilations',
            self.decompiler.api_key
        )

    def test_sends_input_file(self):
        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            files=AnyFilesWith(input=AnyFileNamed(self.input_file.name))
        )

    def test_raises_exception_when_input_file_is_not_given(self):
        with self.assertRaises(MissingParameterError):
            self.start_decompilation()

    def test_sends_pdb_file_when_given(self):
        pdb_file = mock.Mock(spec_set=File)

        self.start_decompilation_with_any_input_file(
            pdb_file=pdb_file
        )

        self.assert_post_request_was_sent_with(
            files=AnyFilesWith(pdb=AnyFileNamed(pdb_file.name))
        )

    def test_mode_is_set_to_c_when_not_given_and_file_name_ends_with_c(self):
        self.input_file.name = 'test.c'

        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='c')
        )

    def test_mode_is_set_to_bin_when_not_given_and_file_name_does_not_end_with_c(self):
        self.input_file.name = 'test.exe'

        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='bin')
        )

    def test_mode_is_used_when_given(self):
        self.start_decompilation_with_any_input_file(
            mode='bin'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='bin')
        )

    def test_raises_exception_when_mode_is_invalid(self):
        with self.assertRaises(InvalidValueError):
            self.start_decompilation_with_any_input_file(
                mode='xxx'
            )

    def test_file_name_extension_is_case_insensitive_during_mode_detection(self):
        self.input_file.name = 'test.C'

        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='c')
        )

    def test_target_language_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            target_language='py'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(target_language='py')
        )

    def test_graph_format_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            graph_format='svg'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(graph_format='svg')
        )

    def test_decomp_var_names_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_var_names='simple'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_var_names='simple')
        )

    def test_decomp_optimizations_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_optimizations='none'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_optimizations='none')
        )

    def test_decomp_unreach_funcs_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_unreach_funcs=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_unreach_funcs=True)
        )

    def test_decomp_emit_addresses_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_emit_addresses=False
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_emit_addresses=False)
        )

    def test_architecture_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            architecture='arm'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(architecture='arm')
        )

    def test_file_format_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            file_format='elf'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(file_format='elf')
        )

    def test_comp_compiler_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_compiler='clang'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_compiler='clang')
        )

    def test_comp_optimizations_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_optimizations='-O1'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_optimizations='-O1')
        )

    def test_comp_debug_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_debug=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_debug=True)
        )

    def test_comp_strip_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_strip=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_strip=True)
        )

    def test_sel_decomp_funcs_is_passed_directly_when_given_as_str(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_funcs='func1,func2'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_funcs='func1,func2')
        )

    def test_sel_decomp_funcs_is_converted_to_str_when_given_as_list(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_funcs=['func1', 'func2']
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_funcs='func1,func2')
        )

    def test_sel_decomp_ranges_is_passed_directly_when_given_as_str(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges='0x100-0x200,0x400-0x500'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_sel_decomp_ranges_is_converted_to_str_when_given_as_list_with_str(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges=['0x100-0x200', '0x400-0x500']
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_sel_decomp_ranges_is_converted_to_str_when_given_as_list_with_int_tuples(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges=[(0x100, 0x200), (0x400, 0x500)]
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_sel_decomp_ranges_is_converted_to_str_when_given_as_list_with_str_tuples(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges=[('0x100', '0x200'), ('0x400', '0x500')]
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_asserts_when_invalid_range_is_passed(self):
        with self.assertRaisesRegex(AssertionError, r'invalid range'):
            self.start_decompilation_with_any_input_file(
                sel_decomp_ranges=[(0x100,)]
            )

    def test_sel_decomp_decoding_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_decoding='only'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_decoding='only')
        )

    def test_endian_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            endian='little'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(endian='little')
        )

    def test_raw_endian_is_still_supported_as_alias_for_endian(self):
        self.start_decompilation_with_any_input_file(
            raw_endian='little'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(endian='little')
        )

    def test_raw_entry_point_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            raw_entry_point='0x400000'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(raw_entry_point='0x400000')
        )

    def test_raw_section_vma_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            raw_section_vma='0x400000'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(raw_section_vma='0x400000')
        )

    def test_ar_index_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            ar_index=1
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(ar_index=1)
        )

    def test_ar_name_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            ar_name=1
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(ar_name=1)
        )

    def test_generate_cg_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            generate_cg=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_cg=True)
        )

    def test_generate_cfgs_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            generate_cfgs=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_cfgs=True)
        )

    def test_generate_archive_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            generate_archive=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_archive=True)
        )

    def test_uses_returned_id_to_initialize_decompilation(self):
        self.conn.send_post_request.return_value = {'id': 'ID'}

        decompilation = self.start_decompilation_with_any_input_file()

        self.assertTrue(decompilation.id, 'ID')
예제 #5
0
def main(argv=None):
    """Runs the tool.

    :param list argv: Tool arguments.

    If `argv` is ``None``, ``sys.argv`` is used.
    """
    args = parse_args(argv if argv is not None else sys.argv)

    decompiler = Decompiler(api_url=args.api_url, api_key=args.api_key)

    params = {}
    add_decompilation_param_when_given(args, params, 'input_file')
    add_decompilation_param_when_given(args, params, 'pdb_file')
    add_decompilation_param_when_given(args, params, 'mode')
    add_decompilation_param_when_given(args, params, 'target_language')
    add_decompilation_param_when_given(args, params, 'graph_format')
    add_decompilation_param_when_given(args, params, 'architecture')
    add_decompilation_param_when_given(args, params, 'file_format')
    add_decompilation_param_when_given(args, params, 'comp_compiler')
    add_decompilation_param_when_given(args, params, 'comp_optimizations')
    add_decompilation_param_when_given(args, params, 'comp_debug')
    add_decompilation_param_when_given(args, params, 'comp_strip')
    add_decompilation_param_when_given(args, params, 'decomp_var_names')
    add_decompilation_param_when_given(args, params, 'decomp_optimizations')
    add_decompilation_param_when_given(args, params, 'decomp_unreach_funcs')
    add_decompilation_param_when_given(args, params, 'decomp_emit_addresses')
    add_decompilation_param_when_given(args, params, 'sel_decomp_funcs')
    add_decompilation_param_when_given(args, params, 'sel_decomp_ranges')
    add_decompilation_param_when_given(args, params, 'sel_decomp_decoding')
    add_decompilation_param_when_given(args, params, 'endian')
    add_decompilation_param_when_given(args, params, 'raw_entry_point')
    add_decompilation_param_when_given(args, params, 'raw_section_vma')
    add_decompilation_param_when_given(args, params, 'ar_index')
    add_decompilation_param_when_given(args, params, 'ar_name')
    add_decompilation_param_when_given(args, params, 'generate_cg')
    add_decompilation_param_when_given(args, params, 'generate_cfgs')
    add_decompilation_param_when_given(args, params, 'generate_archive')
    decompilation = decompiler.start_decompilation(**params)

    displayer = get_progress_displayer(args)
    displayer.display_decompilation_progress(decompilation)
    decompilation.wait_until_finished(
        callback=displayer.display_decompilation_progress)

    output_dir = get_output_dir(args)

    file_path = decompilation.save_hll_code(output_dir)
    display_download_progress(displayer, file_path)

    file_path = decompilation.save_dsm_code(output_dir)
    display_download_progress(displayer, file_path)

    if should_download_output_binary_file(args):
        file_path = decompilation.save_binary(output_dir)
        display_download_progress(displayer, file_path)

    if args.generate_cg:
        try:
            decompilation.wait_until_cg_is_generated()
            file_path = decompilation.save_cg(output_dir)
            display_download_progress(displayer, file_path)
        except CGGenerationFailedError as ex:
            displayer.display_generation_failure('call graph', str(ex))

    if args.generate_cfgs:
        for func in decompilation.funcs_with_cfg:
            try:
                decompilation.wait_until_cfg_is_generated(func)
                file_path = decompilation.save_cfg(func, output_dir)
                display_download_progress(displayer, file_path)
            except CFGGenerationFailedError as ex:
                displayer.display_generation_failure(
                    'control-flow graph for {}'.format(func), str(ex))

    if args.generate_archive:
        try:
            decompilation.wait_until_archive_is_generated()
            file_path = decompilation.save_archive(output_dir)
            display_download_progress(displayer, file_path)
        except ArchiveGenerationFailedError as ex:
            displayer.display_generation_failure('archive', str(ex))

    return 0
예제 #6
0
    def setUp(self):
        super().setUp()

        self.input_file = mock.Mock(spec_set=File)

        self.decompiler = Decompiler(api_key='KEY')
예제 #7
0
class DecompilerStartDecompilationTests(BaseServiceTests):
    """Tests for :func:`retdec.decompiler.Decompiler.start_decompilation()`."""

    def setUp(self):
        super().setUp()

        self.input_file = mock.Mock(spec_set=File)

        self.decompiler = Decompiler(api_key='KEY')

    def test_creates_api_connection_with_correct_url_and_api_key(self):
        self.decompiler.start_decompilation(input_file=self.input_file)

        self.APIConnectionMock.assert_called_once_with(
            'https://retdec.com/service/api/decompiler/decompilations',
            self.decompiler.api_key
        )

    def test_sends_input_file(self):
        self.decompiler.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            files=AnyFilesWith(input=AnyFileNamed(self.input_file.name))
        )

    def test_mode_is_set_to_c_when_not_given_and_file_name_ends_with_c(self):
        self.input_file.name = 'test.c'

        self.decompiler.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='c')
        )

    def test_mode_is_set_to_bin_when_not_given_and_file_name_does_not_end_with_c(self):
        self.input_file.name = 'test.exe'

        self.decompiler.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='bin')
        )

    def test_generate_archive_is_set_to_false_when_not_given(self):
        self.input_file.name = 'test.exe'

        self.decompiler.start_decompilation(
            input_file=self.input_file
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_archive=False)
        )

    def test_generate_archive_is_set_to_true_when_given_as_true(self):
        self.input_file.name = 'test.exe'

        self.decompiler.start_decompilation(
            input_file=self.input_file,
            generate_archive=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_archive=True)
        )

    def test_generate_archive_is_set_to_false_when_given_as_false(self):
        self.input_file.name = 'test.exe'

        self.decompiler.start_decompilation(
            input_file=self.input_file,
            generate_archive=False
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_archive=False)
        )

    def test_raises_exception_when_generate_archive_parameter_is_invalid(self):
        self.input_file.name = 'test.exe'

        with self.assertRaises(InvalidValueError):
            self.decompiler.start_decompilation(
                input_file=self.input_file,
                generate_archive='some data'
            )

    def test_mode_is_used_when_given(self):
        self.decompiler.start_decompilation(
            input_file=self.input_file,
            mode='bin'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='bin')
        )

    def test_raises_exception_when_mode_is_invalid(self):
        with self.assertRaises(InvalidValueError):
            self.decompiler.start_decompilation(
                input_file=self.input_file,
                mode='xxx'
            )

    def test_file_name_extension_is_case_insensitive_during_mode_detection(self):
        self.input_file.name = 'test.C'

        self.decompiler.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='c')
        )

    def test_uses_returned_id_to_initialize_decompilation(self):
        self.conn.send_post_request.return_value = {'id': 'ID'}

        decompilation = self.decompiler.start_decompilation(
            input_file=self.input_file
        )

        self.assertTrue(decompilation.id, 'ID')
예제 #8
0
class DecompilerStartDecompilationTests(BaseServiceTests):
    """Tests for :func:`retdec.decompiler.Decompiler.start_decompilation()`."""

    def setUp(self):
        super().setUp()

        self.input_file = mock.Mock(spec_set=File)

        self.decompiler = Decompiler(api_key='KEY')

    def start_decompilation(self, *args, **kwargs):
        """Starts a decompilation with the given parameters."""
        return self.decompiler.start_decompilation(*args, **kwargs)

    def start_decompilation_with_any_input_file(self, *args, **kwargs):
        """Starts a decompilation with the default input file and,
        additionally, the given parameters.
        """
        kwargs.setdefault('input_file', self.input_file)
        return self.decompiler.start_decompilation(*args, **kwargs)

    def test_creates_api_connection_with_correct_url_and_api_key(self):
        self.start_decompilation_with_any_input_file()

        self.APIConnectionMock.assert_called_once_with(
            'https://retdec.com/service/api/decompiler/decompilations',
            self.decompiler.api_key
        )

    def test_sends_input_file(self):
        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            files=AnyFilesWith(input=AnyFileNamed(self.input_file.name))
        )

    def test_raises_exception_when_input_file_is_not_given(self):
        with self.assertRaises(MissingParameterError):
            self.start_decompilation()

    def test_sends_pdb_file_when_given(self):
        pdb_file = mock.Mock(spec_set=File)

        self.start_decompilation_with_any_input_file(
            pdb_file=pdb_file
        )

        self.assert_post_request_was_sent_with(
            files=AnyFilesWith(pdb=AnyFileNamed(pdb_file.name))
        )

    def test_mode_is_set_to_c_when_not_given_and_file_name_ends_with_c(self):
        self.input_file.name = 'test.c'

        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='c')
        )

    def test_mode_is_set_to_bin_when_not_given_and_file_name_does_not_end_with_c(self):
        self.input_file.name = 'test.exe'

        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='bin')
        )

    def test_mode_is_used_when_given(self):
        self.start_decompilation_with_any_input_file(
            mode='bin'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='bin')
        )

    def test_raises_exception_when_mode_is_invalid(self):
        with self.assertRaises(InvalidValueError):
            self.start_decompilation_with_any_input_file(
                mode='xxx'
            )

    def test_file_name_extension_is_case_insensitive_during_mode_detection(self):
        self.input_file.name = 'test.C'

        self.start_decompilation(input_file=self.input_file)

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(mode='c')
        )

    def test_target_language_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            target_language='py'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(target_language='py')
        )

    def test_graph_format_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            graph_format='svg'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(graph_format='svg')
        )

    def test_decomp_var_names_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_var_names='simple'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_var_names='simple')
        )

    def test_decomp_optimizations_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_optimizations='none'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_optimizations='none')
        )

    def test_decomp_unreach_funcs_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_unreach_funcs=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_unreach_funcs=True)
        )

    def test_decomp_emit_addresses_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            decomp_emit_addresses=False
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(decomp_emit_addresses=False)
        )

    def test_architecture_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            architecture='arm'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(architecture='arm')
        )

    def test_file_format_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            file_format='elf'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(file_format='elf')
        )

    def test_comp_compiler_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_compiler='clang'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_compiler='clang')
        )

    def test_comp_optimizations_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_optimizations='-O1'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_optimizations='-O1')
        )

    def test_comp_debug_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_debug=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_debug=True)
        )

    def test_comp_strip_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            comp_strip=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_strip=True)
        )

    def test_adds_leading_dash_to_comp_optimizations_when_missing(self):
        self.start_decompilation_with_any_input_file(
            comp_optimizations='O1'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(comp_optimizations='-O1')
        )

    def test_sel_decomp_funcs_is_passed_directly_when_given_as_str(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_funcs='func1,func2'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_funcs='func1,func2')
        )

    def test_sel_decomp_funcs_is_converted_to_str_when_given_as_list(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_funcs=['func1', 'func2']
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_funcs='func1,func2')
        )

    def test_sel_decomp_ranges_is_passed_directly_when_given_as_str(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges='0x100-0x200,0x400-0x500'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_sel_decomp_ranges_is_converted_to_str_when_given_as_list_with_str(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges=['0x100-0x200', '0x400-0x500']
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_sel_decomp_ranges_is_converted_to_str_when_given_as_list_with_int_tuples(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges=[(0x100, 0x200), (0x400, 0x500)]
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_sel_decomp_ranges_is_converted_to_str_when_given_as_list_with_str_tuples(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_ranges=[('0x100', '0x200'), ('0x400', '0x500')]
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_ranges='0x100-0x200,0x400-0x500')
        )

    def test_asserts_when_invalid_range_is_passed(self):
        with self.assertRaisesRegex(AssertionError, r'invalid range'):
            self.start_decompilation_with_any_input_file(
                sel_decomp_ranges=[(0x100,)]
            )

    def test_sel_decomp_decoding_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            sel_decomp_decoding='only'
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(sel_decomp_decoding='only')
        )

    def test_generate_cg_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            generate_cg=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_cg=True)
        )

    def test_generate_cfgs_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            generate_cfgs=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_cfgs=True)
        )

    def test_raw_entry_point_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            raw_entry_point="0x400000"
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(raw_entry_point="0x400000")
        )

    def test_raw_section_vma_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            raw_section_vma="0x400000"
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(raw_section_vma="0x400000")
        )

    def test_raw_endian_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            raw_endian="little"
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(raw_endian="little")
        )

    def test_generate_archive_is_set_to_correct_value_when_given(self):
        self.start_decompilation_with_any_input_file(
            generate_archive=True
        )

        self.assert_post_request_was_sent_with(
            params=AnyParamsWith(generate_archive=True)
        )

    def test_uses_returned_id_to_initialize_decompilation(self):
        self.conn.send_post_request.return_value = {'id': 'ID'}

        decompilation = self.start_decompilation_with_any_input_file()

        self.assertTrue(decompilation.id, 'ID')
예제 #9
0
from retdec.decompiler import Decompiler

decompiler = Decompiler(api_key='YOUR-API-KEY')
decompilation = decompiler.start_decompilation(input_file='activator.exe')
decompilation.wait_until_finished()
decompilation.save_hll_code()
예제 #10
0
def main(argv=None):
    """Runs the tool.

    :param list argv: Tool arguments.

    If `argv` is ``None``, ``sys.argv`` is used.
    """
    args = parse_args(argv if argv is not None else sys.argv)

    decompiler = Decompiler(
        api_url=args.api_url,
        api_key=args.api_key
    )

    params = {}
    add_decompilation_param_when_given(args, params, 'input_file')
    add_decompilation_param_when_given(args, params, 'pdb_file')
    add_decompilation_param_when_given(args, params, 'mode')
    add_decompilation_param_when_given(args, params, 'target_language')
    add_decompilation_param_when_given(args, params, 'graph_format')
    add_decompilation_param_when_given(args, params, 'architecture')
    add_decompilation_param_when_given(args, params, 'file_format')
    add_decompilation_param_when_given(args, params, 'comp_compiler')
    add_decompilation_param_when_given(args, params, 'comp_optimizations')
    add_decompilation_param_when_given(args, params, 'comp_debug')
    add_decompilation_param_when_given(args, params, 'comp_strip')
    add_decompilation_param_when_given(args, params, 'decomp_var_names')
    add_decompilation_param_when_given(args, params, 'decomp_optimizations')
    add_decompilation_param_when_given(args, params, 'decomp_unreach_funcs')
    add_decompilation_param_when_given(args, params, 'sel_decomp_funcs')
    add_decompilation_param_when_given(args, params, 'sel_decomp_ranges')
    add_decompilation_param_when_given(args, params, 'sel_decomp_decoding')
    add_decompilation_param_when_given(args, params, 'decomp_emit_addresses')
    add_decompilation_param_when_given(args, params, 'generate_cg')
    add_decompilation_param_when_given(args, params, 'generate_cfgs')
    add_decompilation_param_when_given(args, params, 'generate_archive')
    decompilation = decompiler.start_decompilation(**params)

    displayer = get_progress_displayer(args)
    displayer.display_decompilation_progress(decompilation)
    decompilation.wait_until_finished(
        callback=displayer.display_decompilation_progress
    )

    output_dir = get_output_dir(args)

    file_path = decompilation.save_hll_code(output_dir)
    display_download_progress(displayer, file_path)

    file_path = decompilation.save_dsm_code(output_dir)
    display_download_progress(displayer, file_path)

    if should_download_output_binary_file(args):
        file_path = decompilation.save_binary(output_dir)
        display_download_progress(displayer, file_path)

    if args.generate_cg:
        decompilation.wait_until_cg_is_generated()
        file_path = decompilation.save_cg(output_dir)
        display_download_progress(displayer, file_path)

    if args.generate_cfgs:
        for func in decompilation.funcs_with_cfg:
            decompilation.wait_until_cfg_is_generated(func)
            file_path = decompilation.save_cfg(func, output_dir)
            display_download_progress(displayer, file_path)

    if args.generate_archive:
        decompilation.wait_until_archive_is_generated()
        file_path = decompilation.save_archive(output_dir)
        display_download_progress(displayer, file_path)

    return 0