├── .gitignore ├── CMakeLists.txt ├── INSTALL ├── LICENSE ├── MAL ├── descriptor │ ├── CMakeLists.txt │ ├── INSTALL │ ├── README │ ├── include │ │ └── rebours │ │ │ └── MAL │ │ │ └── descriptor │ │ │ ├── assumptions.hpp │ │ │ ├── development.hpp │ │ │ ├── dump.hpp │ │ │ ├── endian.hpp │ │ │ ├── file_utils.hpp │ │ │ ├── invariants.hpp │ │ │ ├── msgstream.hpp │ │ │ ├── storage.hpp │ │ │ └── test.hpp │ └── src │ │ ├── dump.cpp │ │ ├── file_utils.cpp │ │ ├── storage.cpp │ │ └── x86_64_Linux │ │ ├── build_register_maps.cpp │ │ ├── build_stack_init_data.cpp │ │ ├── build_stack_sections.cpp │ │ └── build_tls_template.cpp ├── encoder │ ├── CMakeLists.txt │ ├── INSTALL │ ├── README │ ├── include │ │ └── rebours │ │ │ └── MAL │ │ │ └── encoder │ │ │ ├── assumptions.hpp │ │ │ ├── development.hpp │ │ │ ├── encode.hpp │ │ │ ├── endian.hpp │ │ │ ├── invariants.hpp │ │ │ ├── msgstream.hpp │ │ │ └── test.hpp │ └── src │ │ └── encode.cpp ├── loader │ ├── CMakeLists.txt │ ├── INSTALL │ ├── README │ ├── include │ │ └── rebours │ │ │ └── MAL │ │ │ └── loader │ │ │ ├── address.hpp │ │ │ ├── assumptions.hpp │ │ │ ├── buffer_io.hpp │ │ │ ├── dependencies_graph.hpp │ │ │ ├── descriptor.hpp │ │ │ ├── detail │ │ │ ├── abi_loaders.hpp │ │ │ ├── address_fixing.hpp │ │ │ ├── load_elf.hpp │ │ │ ├── load_mach.hpp │ │ │ ├── load_pe.hpp │ │ │ ├── load_props_elf.hpp │ │ │ ├── load_props_mach.hpp │ │ │ ├── load_props_pe.hpp │ │ │ ├── mutable_sections_table.hpp │ │ │ ├── set_file_property.hpp │ │ │ └── std_pair_hash.hpp │ │ │ ├── dump.hpp │ │ │ ├── endian.hpp │ │ │ ├── file_props.hpp │ │ │ ├── file_utils.hpp │ │ │ ├── init_fini.hpp │ │ │ ├── invariants.hpp │ │ │ ├── load.hpp │ │ │ ├── msgstream.hpp │ │ │ ├── platform.hpp │ │ │ ├── relocations.hpp │ │ │ ├── sections_table.hpp │ │ │ ├── special_sections.hpp │ │ │ ├── special_sections │ │ │ ├── elf_tls.hpp │ │ │ ├── exceptions.hpp │ │ │ ├── load_configuration_structure.hpp │ │ │ ├── special_section_properties.hpp │ │ │ └── thread_local_storage_initialisers.hpp │ │ │ ├── to_string.hpp │ │ │ └── warnings.hpp │ ├── src │ │ ├── buffer_io.cpp │ │ ├── dependencies_graph.cpp │ │ ├── descriptor.cpp │ │ ├── detail │ │ │ ├── abi_loaders │ │ │ │ ├── ld_linux_x86_32_so_2.cpp │ │ │ │ └── ld_linux_x86_64_so_2.cpp │ │ │ ├── address_fixing.cpp │ │ │ ├── load_elf.cpp │ │ │ ├── load_elf_32bit.cpp │ │ │ ├── load_elf_64bit.cpp │ │ │ ├── load_mach.cpp │ │ │ ├── load_mach_32bit.cpp │ │ │ ├── load_mach_64bit.cpp │ │ │ ├── load_pe.cpp │ │ │ ├── load_pe_32bit.cpp │ │ │ ├── load_pe_64bit.cpp │ │ │ ├── load_props_elf.cpp │ │ │ ├── load_props_mach.cpp │ │ │ ├── load_props_pe.cpp │ │ │ └── mutable_sections_table.cpp │ │ ├── dump.cpp │ │ ├── file_props.cpp │ │ ├── file_utils.cpp │ │ ├── load.cpp │ │ ├── platform.cpp │ │ ├── relocations.cpp │ │ ├── sections_table.cpp │ │ ├── special_sections.cpp │ │ └── special_sections │ │ │ ├── elf_tls.cpp │ │ │ ├── exceptions.cpp │ │ │ ├── load_configuration_structure.cpp │ │ │ ├── special_section_properties.cpp │ │ │ └── thread_local_storage_initialisers.cpp │ └── tests │ │ ├── data_path.cpp │ │ ├── data_path.hpp │ │ ├── test.hpp │ │ └── test01 │ │ ├── CMakeLists.txt │ │ └── main.cpp ├── prologue │ ├── CMakeLists.txt │ ├── INSTALL │ ├── README │ ├── include │ │ └── rebours │ │ │ └── MAL │ │ │ └── prologue │ │ │ ├── assumptions.hpp │ │ │ ├── builder.hpp │ │ │ ├── development.hpp │ │ │ ├── endian.hpp │ │ │ ├── invariants.hpp │ │ │ ├── msgstream.hpp │ │ │ └── test.hpp │ └── src │ │ ├── builder.cpp │ │ └── builder_x86_64_Linux.cpp ├── recogniser │ ├── CMakeLists.txt │ ├── INSTALL │ ├── README │ ├── include │ │ └── rebours │ │ │ └── MAL │ │ │ └── recogniser │ │ │ ├── assumptions.hpp │ │ │ ├── detail │ │ │ ├── recognise_x86_64_Linux.hpp │ │ │ ├── recognise_x86_64_Linux_syscall_syscall.hpp │ │ │ ├── recognise_x86_64_Linux_syscall_utils.hpp │ │ │ ├── recognition_data.hpp │ │ │ ├── recognition_engine_x86_64_Linux.hpp │ │ │ └── register_info.hpp │ │ │ ├── development.hpp │ │ │ ├── dump.hpp │ │ │ ├── endian.hpp │ │ │ ├── file_utils.hpp │ │ │ ├── invariants.hpp │ │ │ ├── msgstream.hpp │ │ │ ├── recognise.hpp │ │ │ └── test.hpp │ └── src │ │ ├── detail │ │ ├── dump_x86_64_Linux.cpp │ │ ├── recognise_x86_64_Linux.cpp │ │ ├── recognise_x86_64_Linux_syscall_syscall.cpp │ │ ├── recognise_x86_64_Linux_syscall_utils.cpp │ │ ├── recognition_data.cpp │ │ ├── recognition_engine_x86_64_Linux.cpp │ │ └── register_info.cpp │ │ ├── dump.cpp │ │ ├── file_utils.cpp │ │ └── recognise.cpp └── reloader │ ├── CMakeLists.txt │ ├── INSTALL │ ├── README │ ├── include │ └── rebours │ │ └── MAL │ │ └── reloader │ │ ├── assumptions.hpp │ │ ├── development.hpp │ │ ├── endian.hpp │ │ ├── invariants.hpp │ │ ├── msgstream.hpp │ │ ├── reload.hpp │ │ └── test.hpp │ └── src │ └── reload.cpp ├── README.md ├── analysis └── native_execution │ ├── CMakeLists.txt │ ├── INSTALL │ ├── README │ ├── include │ └── rebours │ │ └── analysis │ │ └── native_execution │ │ ├── assumptions.hpp │ │ ├── branching_condition.hpp │ │ ├── development.hpp │ │ ├── dump.hpp │ │ ├── endian.hpp │ │ ├── execute_instruction.hpp │ │ ├── execute_program.hpp │ │ ├── execution_properties.hpp │ │ ├── exploration.hpp │ │ ├── file_utils.hpp │ │ ├── invariants.hpp │ │ ├── msgstream.hpp │ │ ├── recovery_properties.hpp │ │ ├── run.hpp │ │ ├── std_pair_hash.hpp │ │ └── test.hpp │ └── src │ ├── branching_condition.cpp │ ├── choose_next_unexplored_exit.cpp │ ├── close_unexplored_exit.cpp │ ├── compute_input_for_reaching_next_goal.cpp │ ├── execute_instruction.cpp │ ├── execute_program.cpp │ ├── execution_properties.cpp │ ├── file_utils.cpp │ ├── find_next_goal_from_unexplored_exit.cpp │ ├── find_traces_related_to_next_goal.cpp │ ├── merge_recovered_traces.cpp │ ├── natexe_dump.cpp │ ├── recovery_properties.cpp │ ├── run.cpp │ └── setup_next_execution_properties.cpp ├── bitvectors ├── CMakeLists.txt ├── INSTALL ├── README ├── include │ └── rebours │ │ └── bitvectors │ │ ├── assumptions.hpp │ │ ├── detail │ │ ├── execute_shell_command_with_async_pipe.hpp │ │ ├── file_utils.hpp │ │ ├── sat_checking_interruption_function.hpp │ │ └── unique_handles.hpp │ │ ├── endian.hpp │ │ ├── expression.hpp │ │ ├── expression_algo.hpp │ │ ├── expression_io.hpp │ │ ├── invariants.hpp │ │ ├── large_types.hpp │ │ ├── msgstream.hpp │ │ ├── sat_checking.hpp │ │ ├── symbol.hpp │ │ └── test.hpp ├── src │ ├── detail │ │ ├── execute_shell_command_with_async_pipe.cpp │ │ ├── file_utils.cpp │ │ ├── sat_checking_interruption_function.cpp │ │ └── unique_handles.cpp │ ├── expression.cpp │ ├── expression_algo.cpp │ ├── expression_load_smtlib2.cpp │ ├── expression_save_smtlib2.cpp │ ├── large_types.cpp │ ├── sat_checking.cpp │ ├── sat_engine_boolector │ │ └── sat_engine_boolector.cpp │ ├── sat_engine_mathsat5 │ │ └── sat_engine_mathsat5.cpp │ ├── sat_engine_z3 │ │ └── sat_engine_z3.cpp │ └── symbol.cpp └── tests │ ├── communication_with_solver │ ├── CMakeLists.txt │ └── main.cpp │ ├── expressions_io │ ├── CMakeLists.txt │ └── main.cpp │ ├── management_of_expressions │ ├── CMakeLists.txt │ └── main.cpp │ └── management_of_symbols │ ├── CMakeLists.txt │ └── main.cpp ├── data ├── benchmarks │ ├── SOURCES.txt │ └── src │ │ └── loadlibs │ │ ├── CMakeLists.txt │ │ └── src │ │ ├── CMakeLists.txt │ │ ├── dynamic_lib_five │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── dynamic_lib_five │ │ │ │ └── functions.hpp │ │ └── src │ │ │ └── functions.cpp │ │ ├── dynamic_lib_four │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── dynamic_lib_four │ │ │ │ └── functions.hpp │ │ └── src │ │ │ └── functions.cpp │ │ ├── dynamic_lib_one │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── dynamic_lib_one │ │ │ │ └── functions.hpp │ │ └── src │ │ │ └── functions.cpp │ │ ├── dynamic_lib_seven │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── dynamic_lib_seven │ │ │ │ └── functions.hpp │ │ └── src │ │ │ └── functions.cpp │ │ ├── dynamic_lib_six │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── dynamic_lib_six │ │ │ │ └── functions.hpp │ │ └── src │ │ │ └── functions.cpp │ │ ├── dynamic_lib_three │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── dynamic_lib_three │ │ │ │ └── functions.hpp │ │ └── src │ │ │ └── functions.cpp │ │ ├── dynamic_lib_two │ │ ├── CMakeLists.txt │ │ ├── include │ │ │ └── dynamic_lib_two │ │ │ │ └── functions.hpp │ │ └── src │ │ │ └── functions.cpp │ │ ├── import_export.hpp │ │ ├── loadlibs │ │ ├── CMakeLists.txt │ │ └── main.cpp │ │ └── static_lib_one │ │ ├── CMakeLists.txt │ │ ├── include │ │ └── static_lib_one │ │ │ └── functions.hpp │ │ └── src │ │ └── functions.cpp └── tests │ ├── asm │ ├── build.py │ └── src │ │ ├── inc_constant_in_mov.asm │ │ ├── inc_constant_in_mov_2.asm │ │ ├── move_block_of_code.asm │ │ ├── permute_instructions.asm │ │ ├── swap_tiny.asm │ │ └── where_was_i_A.asm │ └── c │ └── src │ ├── DOIF.c │ ├── DOIFex.c │ ├── EQCNT.c │ ├── EQCNTex.c │ ├── HW.c │ ├── HWM.c │ ├── OneLoop.c │ ├── OneLoop.s │ ├── TwoLoops.c │ ├── WinDriver.c │ ├── decode_packets.c │ ├── hello.c │ ├── matrIR.c │ └── matrIR_dyn.c ├── doc └── CFG_recovery │ ├── CFG_recovery.tex │ ├── fig_copy_program.pdf │ ├── fig_copy_program.svg │ ├── fig_prologue_stack_init.pdf │ ├── fig_prologue_stack_init.svg │ ├── fig_schema.pdf │ ├── fig_schema.svg │ ├── fig_schema_chaining.pdf │ ├── fig_schema_chaining.svg │ ├── fig_schema_encoding.pdf │ └── fig_schema_encoding.svg ├── program ├── CMakeLists.txt ├── INSTALL ├── README ├── include │ └── rebours │ │ └── program │ │ ├── assembly.hpp │ │ ├── assumptions.hpp │ │ ├── development.hpp │ │ ├── digraph.hpp │ │ ├── endian.hpp │ │ ├── instruction.hpp │ │ ├── invariants.hpp │ │ ├── large_types.hpp │ │ ├── msgstream.hpp │ │ ├── program.hpp │ │ └── test.hpp └── src │ ├── assembly.cpp │ ├── assembly_instruction.cpp │ ├── assembly_loader.cpp │ ├── assembly_writer.cpp │ ├── instruction.cpp │ ├── large_types.cpp │ └── program.cpp └── tool ├── ldexe ├── CMakeLists.txt ├── INSTALL ├── README ├── include │ └── ldexe │ │ ├── assumptions.hpp │ │ ├── endian.hpp │ │ ├── invariants.hpp │ │ ├── msgstream.hpp │ │ └── test.hpp └── src │ ├── ldexe.cpp │ └── ldexe.py └── natexe ├── CMakeLists.txt ├── INSTALL ├── README ├── include └── natexe │ ├── argparser.hpp │ ├── assumptions.hpp │ ├── development.hpp │ ├── endian.hpp │ ├── file_utils.hpp │ ├── invariants.hpp │ ├── msgstream.hpp │ └── test.hpp └── src ├── argparser.cpp ├── file_utils.cpp └── main.cpp /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8 FATAL_ERROR) 2 | 3 | project(rebours) 4 | 5 | set(REBOURS_GLOBAL_BUILD "yes") 6 | set(BUILD_TESTS "yes" CACHE STRING "Build tests (yes/no)?" FORCE) 7 | set(TESTS_DATA_PATH "${CMAKE_SOURCE_DIR}/data" CACHE STRING "${CMAKE_SOURCE_DIR}/data" FORCE) 8 | 9 | add_subdirectory(bitvectors) 10 | add_subdirectory(program) 11 | add_subdirectory(MAL/descriptor) 12 | add_subdirectory(MAL/loader) 13 | add_subdirectory(MAL/reloader) 14 | add_subdirectory(MAL/prologue) 15 | add_subdirectory(MAL/recogniser) 16 | add_subdirectory(MAL/encoder) 17 | add_subdirectory(analysis/native_execution) 18 | add_subdirectory(tool/ldexe) 19 | add_subdirectory(tool/natexe) 20 | 21 | set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/bin" CACHE STRING "${PROJECT_SOURCE_DIR}/bin" FORCE) 22 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | rebours 2 | ======= 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DBITVECTORS_ROOT= 27 | -DPROGRAM_ROOT= 28 | -DNATIVE_EXECUTION_ROOT= 29 | -DLOADER_ROOT= 30 | -DRELOADER_ROOT= 31 | -DDESCRIPTOR_ROOT= 32 | -DPROLOGUE_ROOT= 33 | -DRECOGNISER_ROOT= 34 | -DENCODER_ROOT= 35 | -DCAPSTONE_NEXT_ROOT= 36 | -DZ3_ROOT= 37 | -DBOOLECTOR_ROOT= 38 | -DMATHSAT5_ROOT= 39 | -DBUILD_TESTS= 40 | -DTESTS_DATA_PATH= 41 | 42 | 43 | All built binaries can be found in the directory: 44 | 45 | /tools/ldexe/bin/Linux_${CMAKE_BUILD_TYPE} 46 | 47 | 48 | 2) MS-Windows 7+ 49 | ---------------- 50 | 51 | TODO 52 | 53 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 Marek Trtik 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /MAL/descriptor/INSTALL: -------------------------------------------------------------------------------- 1 | descriptor 2 | ========== 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/MAL/descriptor/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DDESCRIPTOR_BUILD_TESTS= 27 | 28 | 29 | All built binaries can be found in the directory: 30 | 31 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/MAL 32 | 33 | 34 | 2) MS-Windows 7+ 35 | ---------------- 36 | 37 | TODO 38 | 39 | -------------------------------------------------------------------------------- /MAL/descriptor/README: -------------------------------------------------------------------------------- 1 | recogniser 2 | ========== 3 | 4 | 5 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/dump.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_DESCRIPTOR_DUMP_HPP_INCLUDED 2 | # define REBOURS_MAL_DESCRIPTOR_DUMP_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | namespace mal { namespace descriptor { 8 | 9 | /** 10 | * The following two functions read a passed descriptor 'data' and create one or more HTML file 11 | * on the disc showing the content of the descriptor. 12 | */ 13 | 14 | void dump_html(storage const& data, 15 | std::string const& output_file_pathname, 16 | //!< A path-name of the root HTML file into which the descriptor will be 17 | //!< dumped. Other generated HTML files are referenced from the root file 18 | //!< and they all will be created in the same directory as the root file. 19 | //!< If any of the created files already exists on the disc, then they 20 | //!< will be overwritten without any notification. 21 | bool const dump_also_contents_of_sections = false 22 | //!< It allows for dump of content of either all or no section. A content of 23 | //!< a section is an array of individual bytes of the section. 24 | ); 25 | 26 | void dump_html(storage const& data, 27 | std::string const& output_file_pathname, 28 | //!< A path-name of the root HTML file into which the descriptor will be 29 | //!< dumped. Other generated HTML files are referenced from the root file 30 | //!< and they all will be created in the same directory as the root file. 31 | //!< If any of the created files already exists on the disc, then they 32 | //!< will be overwritten without any notification. 33 | std::vector const& start_addresses_of_sections_whose_content_should_be_dumped 34 | //!< It allows for dump of content of selected sections. A content of 35 | //!< a section is an array of individual bytes of the section. 36 | ); 37 | 38 | 39 | }} 40 | 41 | #endif 42 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/file_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FILE_UTILS_HPP_INCLUDED 2 | # define FILE_UTILS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | 10 | /** 11 | * This module implements utility functions which provide us disc-related functionality, 12 | * like manipulation with disc paths (concatenation/splitting), checking for existence 13 | * of files, etc. 14 | */ 15 | 16 | namespace fileutl { 17 | 18 | 19 | bool file_exists(std::string const& pathname); 20 | bool is_directory(std::string const& pathname); 21 | uint64_t file_size(std::string const& file_pathname); 22 | std::string parse_name_in_pathname(std::string const& file_pathname); 23 | std::string parse_path_in_pathname(std::string const& file_pathname); 24 | void create_directory(std::string const& pathname); 25 | std::string concatenate_file_paths(std::string const& left_path, std::string const& right_path); 26 | std::string absolute_path(std::string const& path); 27 | std::string normalise_path(std::string const& path); 28 | void split_pathname(std::string const& pathname, std::vector& output); 29 | std::string join_path_parts(std::vector const& parts); 30 | std::string get_common_preffix(std::string const& pathname1, std::string const& pathname2); 31 | std::string get_relative_path(std::string const& pathname, std::string const& directory); 32 | 33 | 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MAL/descriptor/include/rebours/MAL/descriptor/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /MAL/descriptor/src/x86_64_Linux/build_stack_sections.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace mal { namespace descriptor { namespace detail { namespace x86_64_Linux { 5 | 6 | 7 | void build_stack_sections(std::vector& sections, uint64_t const desred_size, uint64_t const begin_address) 8 | { 9 | static uint64_t constexpr stack_max_address = 0x7FFFFFFFFFFFULL; 10 | static uint64_t constexpr stack_default_size = 0x800000ULL; 11 | 12 | uint64_t const stack_size = desred_size > 0ULL ? desred_size : stack_default_size; 13 | 14 | ASSUMPTION(begin_address < stack_max_address - stack_size); 15 | 16 | sections.push_back({ 17 | stack_max_address + 1ULL - stack_size, 18 | stack_max_address + 1ULL, 19 | true, 20 | true, 21 | false, 22 | false, 23 | true 24 | }); 25 | } 26 | 27 | 28 | }}}} 29 | -------------------------------------------------------------------------------- /MAL/encoder/INSTALL: -------------------------------------------------------------------------------- 1 | encoder 2 | ======= 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/MAL/encoder/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DDESCRIPTOR_ROOT= 27 | -DPROGRAM_ROOT= 28 | -DENCODER_BUILD_TESTS= 29 | 30 | 31 | All built binaries can be found in the directory: 32 | 33 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/MAL 34 | 35 | 36 | 2) MS-Windows 7+ 37 | ---------------- 38 | 39 | TODO 40 | 41 | -------------------------------------------------------------------------------- /MAL/encoder/README: -------------------------------------------------------------------------------- 1 | encoder 2 | ======= 3 | 4 | 5 | -------------------------------------------------------------------------------- /MAL/encoder/include/rebours/MAL/encoder/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /MAL/encoder/include/rebours/MAL/encoder/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /MAL/encoder/include/rebours/MAL/encoder/encode.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_ENCODER_ENCODE_HPP_INCLUDED 2 | # define REBOURS_MAL_ENCODER_ENCODE_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | namespace mal { namespace encoder { 10 | 11 | 12 | std::ostream& encode(std::ostream& output_stream, 13 | descriptor::storage const& description, 14 | microcode::program const& program, 15 | microcode::annotations const* const annotations 16 | ); 17 | 18 | 19 | }} 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /MAL/encoder/include/rebours/MAL/encoder/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MAL/encoder/include/rebours/MAL/encoder/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MAL/encoder/include/rebours/MAL/encoder/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MAL/encoder/include/rebours/MAL/encoder/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /MAL/encoder/src/encode.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mal { namespace encoder { 8 | 9 | 10 | std::ostream& encode(std::ostream& output_stream, 11 | descriptor::storage const& description, 12 | microcode::program const& program, 13 | microcode::annotations const* const annotations 14 | ) 15 | { 16 | NOT_IMPLEMENTED_YET(); 17 | } 18 | 19 | 20 | }} 21 | -------------------------------------------------------------------------------- /MAL/loader/INSTALL: -------------------------------------------------------------------------------- 1 | loader 2 | ====== 3 | 4 | Here is an installation guide for all supported platforms. 5 | 6 | 7 | Linux (tested on Ubuntu and Debian) 8 | ----------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/MAL/loader/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake ../ 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake ../ 25 | -DCMAKE_BUILD_TYPE= 26 | -DTESTS= 27 | -DTESTS_DATA_PATH= 28 | 29 | Where '' is a choice of flags with 'flag0' is the 30 | default choice when the variable is not triggered through the cmake 31 | '-D' option. 32 | 33 | And, '' is the directory, where tests of the loader project 34 | will look for data files. It is the installation directory of loader's 35 | database of benchmarks. You typically install the database to: 36 | /data 37 | 38 | Note that this directory is necessary only when you set 39 | '-DTESTS=yes'. 40 | 41 | All built binaries can be found in the directory: 42 | 43 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/MAL 44 | 45 | -------------------------------------------------------------------------------- /MAL/loader/README: -------------------------------------------------------------------------------- 1 | loader 2 | ====== 3 | 4 | 5 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/address.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_ADDRESS_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_ADDRESS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace loader { 7 | 8 | 9 | /** 10 | * We define an address into process's virtual address space as 64-bit unsigned integer. 11 | * This definition is NOT dependent on processor architectures of a loaded process. It means 12 | * that a loaded process can be for a 32-bit architecture (i.e. pointers inside the loaded 13 | * sections are 32-bit), but accesses to the loaded section from data stuctures of the Loader 14 | * are always 64-bit numbers. Also, pointers readed from sections are converted to 64-bit numbers. 15 | */ 16 | typedef uint64_t address; 17 | 18 | 19 | } 20 | 21 | #endif 22 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/buffer_io.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IOBUFFER_HPP 2 | #define IOBUFFER_HPP 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | /** 9 | * These utility functions allow for conversion of raw sequence of bytes in the memory into a numeric constant. 10 | * Each function converts the memory into a differnt type of number. 11 | */ 12 | 13 | void address_to_buffer(loader::address const value, std::vector& buffer, bool const use_big_endian_buffer); 14 | void uint16_t_to_buffer(uint16_t const value, std::vector& buffer, bool const use_big_endian_buffer); 15 | void uint32_t_to_buffer(uint32_t const value, std::vector& buffer, bool const use_big_endian_buffer); 16 | void uint64_t_to_buffer(uint64_t const value, std::vector& buffer, bool const use_big_endian_buffer); 17 | 18 | 19 | uint16_t buffer_to_uint16_t(uint8_t const* const buffer_begin, uint8_t const* const buffer_end, bool is_it_big_endian_buffer); 20 | int16_t buffer_to_int16_t(uint8_t const* const buffer_begin, uint8_t const* const buffer_end, bool is_it_big_endian_buffer); 21 | uint32_t buffer_to_uint32_t(uint8_t const* const buffer_begin, uint8_t const* const buffer_end, bool is_it_big_endian_buffer); 22 | int32_t buffer_to_int32_t(uint8_t const* const buffer_begin, uint8_t const* const buffer_end, bool is_it_big_endian_buffer); 23 | uint64_t buffer_to_uint64_t(uint8_t const* const buffer_begin, uint8_t const* const buffer_end, bool is_it_big_endian_buffer); 24 | int64_t buffer_to_int64_t(uint8_t const* const buffer_begin, uint8_t const* const buffer_end, bool is_it_big_endian_buffer); 25 | 26 | 27 | inline uint16_t buffer_to_uint16_t(char const* const buffer_begin, char const* const buffer_end, bool is_it_big_endian_buffer) 28 | { return buffer_to_uint16_t((uint8_t const*)buffer_begin, (uint8_t const*)buffer_end, is_it_big_endian_buffer); } 29 | 30 | inline int16_t buffer_to_int16_t(char const* const buffer_begin, char const* const buffer_end, bool is_it_big_endian_buffer) 31 | { return buffer_to_int16_t((uint8_t const*)buffer_begin, (uint8_t const*)buffer_end, is_it_big_endian_buffer); } 32 | 33 | inline uint32_t buffer_to_uint32_t(char const* const buffer_begin, char const* const buffer_end, bool is_it_big_endian_buffer) 34 | { return buffer_to_uint32_t((uint8_t const*)buffer_begin, (uint8_t const*)buffer_end, is_it_big_endian_buffer); } 35 | 36 | inline int32_t buffer_to_int32_t(char const* const buffer_begin, char const* const buffer_end, bool is_it_big_endian_buffer) 37 | { return buffer_to_int32_t((uint8_t const*)buffer_begin, (uint8_t const*)buffer_end, is_it_big_endian_buffer); } 38 | 39 | inline uint64_t buffer_to_uint64_t(char const* const buffer_begin, char const* const buffer_end, bool is_it_big_endian_buffer) 40 | { return buffer_to_uint64_t((uint8_t const*)buffer_begin, (uint8_t const*)buffer_end, is_it_big_endian_buffer); } 41 | 42 | inline int64_t buffer_to_int64_t(char const* const buffer_begin, char const* const buffer_end, bool is_it_big_endian_buffer) 43 | { return buffer_to_int64_t((uint8_t const*)buffer_begin, (uint8_t const*)buffer_end, is_it_big_endian_buffer); } 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/dependencies_graph.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEPENDENCIES_GRAPH_HPP_INCLUDED 2 | # define DEPENDENCIES_GRAPH_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | namespace loader { 10 | 11 | 12 | /** 13 | * Keys and values in this dictionary are full path-names of binary files. 14 | * For a given key there is stored a vector of values the key depends on 15 | * all of them. For example, if a binary file A depends on binary files B and C, 16 | * then the dictionary stores the vector [B,C] for the key A. 17 | * 18 | * In general, dependencies between binary files may by cyclic. So, the dictionary 19 | * can represent arbitrary directed graph. Nevertheless, dependencies are typically 20 | * acyclic in practice. The dictionary thus typically represents only a DAG. 21 | */ 22 | typedef std::map > file_dependencies_map; 23 | 24 | 25 | /** 26 | * It is basically a pair of directed graphs represented by the type 'file_dependencies_map' 27 | * defined above (please, read its description now). The first graph defines 'forward dependencies', 28 | * i.e. what binary file depend on (loads) what other binary files. The second graph defines 'backward dependencies', 29 | * i.e. what binary file is necessary for (is loaded by) what other binary files. In other words, both graphs differ 30 | * only in the orientation of their edges. 31 | * 32 | * Since the load always starts with a single binary file, we mark that binary file as the 'root file' 33 | * in this data structure. 34 | * 35 | * Note that all data are read-only. 36 | */ 37 | struct dependencies_graph 38 | { 39 | /** 40 | * It takes a (shared) ownership of data passed as arguments, except the 'root_file' 41 | * which is coppied. 42 | */ 43 | dependencies_graph(std::string const& root_file, 44 | std::shared_ptr const forward_dependencies, 45 | std::shared_ptr const backward_dependencies); 46 | 47 | std::string const& root_file() const { return m_root_file; } 48 | std::vector const& files_loaded_by(std::string const& file) const; 49 | std::vector const& files_loading_file(std::string const& file) const; 50 | 51 | std::shared_ptr forward_dependencies() const { return m_forward_dependencies; } 52 | std::shared_ptr backward_dependencies() const { return m_backward_dependencies; } 53 | 54 | private: 55 | std::string m_root_file; 56 | std::shared_ptr m_forward_dependencies; 57 | std::shared_ptr m_backward_dependencies; 58 | }; 59 | 60 | 61 | typedef std::shared_ptr dependencies_graph_ptr; 62 | 63 | 64 | } 65 | 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/detail/address_fixing.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_DETAIL_ADDRESS_FIXING_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_DETAIL_ADDRESS_FIXING_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace loader { namespace detail { 9 | 10 | 11 | typedef std::map address_fixes_map; 12 | typedef std::shared_ptr address_fixes_map_ptr; 13 | 14 | bool can_address_be_fixed(address const orig_address, address_fixes_map const& fixed_section_starts); 15 | 16 | address fixed_base_address(address_fixes_map const& fixed_section_starts); 17 | 18 | address adjust_address_to_fixed_sections(address const orig_address, 19 | address_fixes_map const& fixed_section_starts); 20 | 21 | inline bool can_address_be_fixed(address const orig_address, address_fixes_map_ptr const fixed_section_starts) 22 | { 23 | return can_address_be_fixed(orig_address,*fixed_section_starts); 24 | } 25 | 26 | inline address fixed_base_address(address_fixes_map_ptr const fixed_section_starts) 27 | { 28 | return fixed_base_address(*fixed_section_starts); 29 | } 30 | 31 | inline address adjust_address_to_fixed_sections(address const orig_address, 32 | address_fixes_map_ptr const fixed_section_starts) 33 | { 34 | return adjust_address_to_fixed_sections(orig_address,*fixed_section_starts); 35 | } 36 | 37 | 38 | }} 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/detail/load_elf.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_DETAIL_LOAD_ELF_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_DETAIL_LOAD_ELF_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace loader { namespace detail { 9 | 10 | 11 | inline std::string NOT_ELF_FILE() { return "Not ELF file."; } 12 | 13 | file_props_ptr load_elf_file_props(std::string const& elf_file, std::ifstream& elf, 14 | load_props_elf& load_props, std::string& error_message); 15 | std::string load_elf(std::string const& elf_file, load_props_elf& load_props); 16 | 17 | std::string load_elf_32bit(std::ifstream& elf, file_props_ptr elf_props, load_props_elf& load_props); 18 | std::string load_elf_64bit(std::ifstream& elf, file_props_ptr elf_props, load_props_elf& load_props); 19 | 20 | 21 | }} 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/detail/load_mach.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_DETAIL_LOAD_MACH_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_DETAIL_LOAD_MACH_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | namespace loader { namespace detail { 10 | 11 | 12 | typedef std::tuple mach_header_props; 13 | 14 | 15 | inline std::string NOT_MACH_FILE() { return "Not MACH file."; } 16 | 17 | std::pair 18 | load_mach_file_props(std::string const& mach_file, std::ifstream& mach, 19 | load_props_mach& load_props, std::string& error_message); 20 | std::string load_mach(std::string const& mach_file, load_props_mach& load_props); 21 | 22 | std::string load_mach_32bit(std::ifstream& mach, file_props_ptr mach_props, 23 | uint32_t const num_load_commnads, 24 | uint32_t const num_bytes_of_load_commnads, 25 | bool const is_fixed_dynamic_library, 26 | load_props_mach& load_props); 27 | std::string load_mach_64bit(std::ifstream& mach, file_props_ptr mach_props, 28 | uint32_t const num_load_commnads, 29 | uint32_t const num_bytes_of_load_commnads, 30 | bool const is_fixed_dynamic_library, 31 | load_props_mach& load_props); 32 | 33 | 34 | symbol_table_ptr build_visible_symbols_table(load_props_mach const& load_props); 35 | 36 | 37 | }} 38 | 39 | #endif 40 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/detail/mutable_sections_table.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_DETAIL_MUTABLE_SECTIONS_TABLE_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_DETAIL_MUTABLE_SECTIONS_TABLE_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | 10 | namespace loader { namespace detail { 11 | 12 | 13 | typedef std::shared_ptr mutable_sections_table_ptr; 14 | 15 | 16 | std::string write_buffer( 17 | address const start_address, 18 | std::vector const& buffer, 19 | bool const is_buffer_in_big_endian, 20 | mutable_sections_table_ptr const table 21 | ); 22 | 23 | std::string write_byte(address const key, uint8_t const value, section_ptr const section); 24 | std::string write_address(address const start_address, address const value, mutable_sections_table_ptr const table); 25 | std::string write_uint16_t(address const start_address, uint16_t const value, mutable_sections_table_ptr const table); 26 | std::string write_uint32_t(address const start_address, uint32_t const value, mutable_sections_table_ptr const table); 27 | std::string write_uint64_t(address const start_address, uint64_t const value, mutable_sections_table_ptr const table); 28 | 29 | 30 | }} 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/detail/set_file_property.hpp: -------------------------------------------------------------------------------- 1 | #ifndef SET_FILE_PROPERTY_HPP_INCLUDED 2 | # define SET_FILE_PROPERTY_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | namespace loader { namespace detail { 8 | 9 | 10 | inline void set_file_property(file_property_map_ptr const property_map, 11 | std::string const& property_name, 12 | std::string const& property_value) 13 | { 14 | (*std::const_pointer_cast(property_map))[property_name] = property_value; 15 | } 16 | 17 | 18 | }} 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/detail/std_pair_hash.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STD_PAIR_HASH_HPP_INCLUDED 2 | # define STD_PAIR_HASH_HPP_INCLUDED 3 | 4 | # include 5 | 6 | template 7 | inline void hash_combine(std::size_t & seed, const T & v) 8 | { 9 | std::hash hasher; 10 | seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 11 | } 12 | 13 | namespace std 14 | { 15 | template struct hash> 16 | { 17 | inline size_t operator()(const pair & v) const 18 | { 19 | size_t seed = 0; 20 | ::hash_combine(seed, v.first); 21 | ::hash_combine(seed, v.second); 22 | return seed; 23 | } 24 | }; 25 | } 26 | 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/dump.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_DUMP_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_DUMP_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | namespace loader { 8 | 9 | /** 10 | * The following two functions read a passed descriptor 'data' and create one or more HTML file 11 | * on the disc showing the content of the descriptor. 12 | */ 13 | 14 | void dump_html(descriptor_ptr const data, 15 | //!< A descriptor of loaded binaries whose content will be dumped. 16 | std::string const& output_file_pathname, 17 | //!< A path-name of the root HTML file into which the descriptor will be 18 | //!< dumped. Other generated HTML files are referenced from the root file 19 | //!< and they all will be created in the same directory as the root file. 20 | //!< If any of the created files already exists on the disc, then they 21 | //!< will be overwritten without any notification. 22 | bool const dump_also_contents_of_sections = false 23 | //!< It allows for dump of content of either all or no section. A content of 24 | //!< a section is an array of individual bytes of the section. 25 | ); 26 | 27 | void dump_html(descriptor_ptr const data, 28 | //!< A descriptor of loaded binaries whose content will be dumped. 29 | std::string const& output_file_pathname, 30 | //!< A path-name of the root HTML file into which the descriptor will be 31 | //!< dumped. Other generated HTML files are referenced from the root file 32 | //!< and they all will be created in the same directory as the root file. 33 | //!< If any of the created files already exists on the disc, then they 34 | //!< will be overwritten without any notification. 35 | std::vector
const& start_addresses_of_sections_whose_content_should_be_dumped 36 | //!< It allows for dump of content of selected sections. A content of 37 | //!< a section is an array of individual bytes of the section. 38 | ); 39 | 40 | 41 | /** 42 | * It creates Graphviz's .dot file on the disc whose content is the passed dependencies graph. 43 | */ 44 | void dump_dot(dependencies_graph_ptr const graph, 45 | //!< A dependencies graph which will be dumped. 46 | std::string const& output_file_pathname 47 | //!< A path-name of Graphviz's .dot file into which the dependencies graph 48 | //!< will be dumped. If the file already exists on the disc, then it will be 49 | //!< overwritten without any notification. 50 | ); 51 | 52 | 53 | } 54 | 55 | #endif 56 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/file_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_FILE_UTILS_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_FILE_UTILS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | 10 | /** 11 | * This module implements utility functions which provide us disc-related functionality, 12 | * like manipulation with disc paths (concatenation/splitting), checking for existence 13 | * of files, read from and write to files, etc. 14 | */ 15 | 16 | 17 | bool file_exists(std::string const& pathname); 18 | bool is_directory(std::string const& pathname); 19 | uint64_t file_size(std::string const& file_pathname); 20 | std::string parse_name_in_pathname(std::string const& file_pathname); 21 | std::string parse_path_in_pathname(std::string const& file_pathname); 22 | void create_directory(std::string const& pathname); 23 | std::string concatenate_file_paths(std::string const& left_path, std::string const& right_path); 24 | std::string absolute_path(std::string const& path); 25 | std::string normalise_path(std::string const& path); 26 | void split_pathname(std::string const& pathname, std::vector& output); 27 | std::string join_path_parts(std::vector const& parts); 28 | std::string get_common_preffix(std::string const& pathname1, std::string const& pathname2); 29 | std::string get_relative_path(std::string const& pathname, std::string const& directory); 30 | 31 | void skip_bytes(std::ifstream& stream, uint64_t const count); 32 | 33 | uint8_t read_byte(std::ifstream& stream); 34 | void read_bytes(std::ifstream& stream, uint64_t const count, std::vector& output); 35 | void read_bytes(std::ifstream& stream, uint64_t const count, std::string& output); 36 | std::string read_bytes_as_null_terminated_string(std::ifstream& stream); 37 | uint16_t read_bytes_to_uint16_t(std::ifstream& stream, uint8_t const num_bytes, bool const is_in_big_endian); 38 | int16_t read_bytes_to_int16_t(std::ifstream& stream, uint8_t const num_bytes, bool const is_in_big_endian); 39 | uint32_t read_bytes_to_uint32_t(std::ifstream& stream, uint8_t const num_bytes, bool const is_in_big_endian); 40 | int32_t read_bytes_to_int32_t(std::ifstream& stream, uint8_t const num_bytes, bool const is_in_big_endian); 41 | uint64_t read_bytes_to_uint64_t(std::ifstream& stream, uint8_t const num_bytes, bool const is_in_big_endian); 42 | int64_t read_bytes_to_int64_t(std::ifstream& stream, uint8_t const num_bytes, bool const is_in_big_endian); 43 | 44 | 45 | #endif 46 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/init_fini.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_INIT_FINI_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_INIT_FINI_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | namespace loader { 10 | 11 | 12 | /** 13 | * It is a dictionary where keys are path-names of loaded binary files and values are 14 | * vectors of entry points (start addresses) of special functions inside those binaries. 15 | * A special function is either initialisation or termination function of the loaded file. 16 | * One dictionary may store either initialisation or termination function. Mixing of 17 | * initialisation or termination functions in one dictionary is not allowed. Special 18 | * functions of a binary file must be called in the order as they appear the vector. 19 | * An order in which special functions of different loaded files are called is given 20 | * by a dependency graph (see file Loader/dependencies_graph.hpp). 21 | * 22 | * Note that the entry point to the root binary (i.e. the 'main' function) is also 23 | * considered as a special (initialisation) function of that binary file. It always 24 | * appears at the last position in the vector of that file. 25 | */ 26 | typedef std::unordered_map< std::string,std::vector
> special_functions_of_files; 27 | 28 | typedef std::shared_ptr init_functions_ptr; 29 | typedef std::shared_ptr fini_functions_ptr; 30 | 31 | 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/platform.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_PLATFORM_HPP 2 | # define REBOURS_MAL_LOADER_PLATFORM_HPP 3 | 4 | #include 5 | #include 6 | 7 | namespace loader { 8 | /* CPU architectures */ 9 | enum class architecture_t { 10 | ARM, 11 | ARM64, 12 | MIPS, 13 | POWERPC, 14 | SPARC, 15 | SPARC64, 16 | X86_32, 17 | X86_64, 18 | UNKNOWN_ARCH 19 | }; 20 | 21 | /* Application Binary Interfaces (ABI) */ 22 | enum class abi_t { 23 | DARWIN, 24 | LINUX, 25 | OPENBSD, 26 | SOLARIS, 27 | WINDOWS, 28 | UNIX, 29 | UNKNOWN_ABI 30 | }; 31 | 32 | /* Store the CPU architecture and the ABI */ 33 | class platform { 34 | private: 35 | architecture_t m_architecture; 36 | abi_t m_abi; 37 | public: 38 | platform(architecture_t const&, abi_t const&); 39 | architecture_t const& architecture() const { return m_architecture; } 40 | abi_t const& abi() const { return m_abi; } 41 | }; 42 | 43 | typedef std::shared_ptr platform_ptr; 44 | } 45 | 46 | /* Operators on 'platform' struct */ 47 | bool operator==(loader::platform const&, loader::platform const&); 48 | inline bool operator!=(loader::platform const& l, loader::platform const& r) 49 | { 50 | return !(l == r); 51 | } 52 | 53 | /* Output operators for architecture and abi */ 54 | std::ostream& operator<<(std::ostream&, loader::architecture_t); 55 | std::ostream& operator<<(std::ostream&, loader::abi_t); 56 | 57 | #endif /* LOADER_PLATFORM_HPP */ 58 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/special_sections.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_SPECIAL_SECTIONS_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_SPECIAL_SECTIONS_HPP_INCLUDED 3 | 4 | /** 5 | * Special sections hold an information parsed from loaded sections (see Loader/sections_table.hpp) 6 | * which is than used by an underlying system for managing execution of the loaded process. 7 | */ 8 | 9 | /** 10 | * This header file contains a definition of a base class for all special sections. 11 | */ 12 | # include 13 | 14 | /** 15 | * These headers contain concrete definitions of individual special sections. 16 | */ 17 | # include 18 | # include 19 | # include 20 | # include 21 | 22 | # include 23 | 24 | namespace loader { 25 | 26 | 27 | namespace special_section_name { 28 | 29 | /** 30 | * Here are string constants identifying kinds of special sections. 31 | */ 32 | 33 | std::string thread_local_storage(); 34 | std::string thread_local_storage_initialisers(); 35 | std::string resources(); 36 | std::string load_configuration_structure(); 37 | std::string exceptions(); 38 | 39 | 40 | } 41 | 42 | /** 43 | * It is a table of special sections ordered by their names from the namespace loader::special_section_name 44 | */ 45 | typedef std::map 48 | special_sections; 49 | 50 | /** 51 | * For each loaded file (the root binary and its dynamic libraries) we store its table of 52 | * special sections. So, we build a table where for each loaded file (its path-name) 53 | * we store a table with special sections. 54 | */ 55 | typedef std::map 58 | special_sections_table; 59 | 60 | 61 | typedef std::shared_ptr special_sections_table_ptr; 62 | 63 | 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/special_sections/elf_tls.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_SPECIAL_SECTION_ELF_TLS_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_SPECIAL_SECTION_ELF_TLS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace loader { namespace special_section { 7 | 8 | 9 | struct elf_tls : public special_section_properties 10 | { 11 | elf_tls(address const start_address, 12 | address const image_end_address, 13 | address const end_address, 14 | uint64_t const file_offset, 15 | uint64_t const alignment, 16 | uint64_t const flags, 17 | bool const use_static_scheme 18 | ); 19 | 20 | address image_end_address() const noexcept { return m_image_end_address; } 21 | uint64_t file_offset() const noexcept { return m_file_offset; } 22 | uint64_t alignment() const noexcept { return m_alignment; } 23 | uint64_t flags() const noexcept { return m_flags; } 24 | bool use_static_scheme() const noexcept { return m_use_static_scheme; } 25 | 26 | private: 27 | address m_image_end_address; 28 | uint64_t m_file_offset; 29 | uint64_t m_alignment; 30 | uint64_t m_flags; 31 | bool m_use_static_scheme; 32 | }; 33 | 34 | typedef std::shared_ptr elf_tls_ptr; 35 | 36 | }} 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/special_sections/exceptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_SPECIAL_SECTION_EXCEPTIONS_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_SPECIAL_SECTION_EXCEPTIONS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace loader { namespace special_section { 9 | 10 | 11 | struct exceptions : public special_section_properties 12 | { 13 | exceptions(address const start_address, address const end_address, 14 | std::vector< std::tuple > const& records); 15 | 16 | uint64_t num_records() const { return m_records.size(); } 17 | 18 | address start_address(uint64_t const index) const { return std::get<0>(m_records.at(index)); } 19 | address end_address(uint64_t const index) const { return std::get<1>(m_records.at(index)); } 20 | address unwind_info_address(uint64_t const index) const { return std::get<2>(m_records.at(index)); } 21 | 22 | private: 23 | std::vector< std::tuple > m_records; 24 | }; 25 | 26 | typedef std::shared_ptr exceptions_ptr; 27 | 28 | }} 29 | 30 | #endif 31 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/special_sections/special_section_properties.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_SPECIAL_SECTIONS_SPECIAL_SECTION_PROPERTIES_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_SPECIAL_SECTIONS_SPECIAL_SECTION_PROPERTIES_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace loader { 9 | 10 | /** 11 | * It is a base class for all special sections (see the header file Loader/special_sections.hpp). 12 | */ 13 | struct special_section_properties 14 | { 15 | special_section_properties(address const start_address, 16 | address const end_address, 17 | std::string const& description = "" //!< A textual description describing purpose 18 | //!< of a special section derived from this class. 19 | ); 20 | virtual ~special_section_properties() {} 21 | 22 | address start_address() const noexcept { return m_start_address; } 23 | address end_address() const noexcept { return m_end_address; } 24 | std::string const& description() const noexcept { return m_description; } 25 | 26 | private: 27 | address const m_start_address; 28 | address const m_end_address; 29 | std::string m_description; 30 | }; 31 | 32 | typedef std::shared_ptr special_section_properties_ptr; 33 | 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/special_sections/thread_local_storage_initialisers.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_SPECIAL_SECTION_THREAD_LOCAL_STORAGE_INITIALISERS_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_SPECIAL_SECTION_THREAD_LOCAL_STORAGE_INITIALISERS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace loader { namespace special_section { 9 | 10 | 11 | struct thread_local_storage_initialisers : public special_section_properties 12 | { 13 | thread_local_storage_initialisers( 14 | address const start_address, 15 | address const end_address, 16 | std::vector
const& init_functions 17 | ); 18 | 19 | std::vector
const& init_functions() const { return m_init_functions; } 20 | 21 | private: 22 | std::vector
m_init_functions; 23 | }; 24 | 25 | typedef std::shared_ptr thread_local_storage_initialisers_ptr; 26 | 27 | }} 28 | 29 | #endif 30 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/to_string.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TO_STRING_HPP_INCLUDED 2 | # define TO_STRING_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | template 9 | std::string to_string(type const value, bool const as_hexadecimal = true) 10 | { 11 | std::ostringstream ostr; 12 | if (as_hexadecimal) 13 | ostr << std::hex << value; 14 | else 15 | ostr << value; 16 | return ostr.str(); 17 | } 18 | 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /MAL/loader/include/rebours/MAL/loader/warnings.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_WARNINGS_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_WARNINGS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | namespace loader { 10 | 11 | 12 | /** 13 | * This dictionary holds for each loaded binary a list of all detected warnings 14 | * describing inconsistences in a structure or content of the loaded binary. 15 | */ 16 | typedef std::map //!< Warnings occured during the load of the binary. 18 | > 19 | warnings; 20 | 21 | typedef std::shared_ptr warnings_ptr; 22 | 23 | 24 | } 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /MAL/loader/src/dependencies_graph.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace loader { 5 | 6 | 7 | dependencies_graph::dependencies_graph(std::string const& root_file, 8 | std::shared_ptr const forward_dependencies, 9 | std::shared_ptr const backward_dependencies) 10 | : m_root_file(root_file) 11 | , m_forward_dependencies(forward_dependencies) 12 | , m_backward_dependencies(backward_dependencies) 13 | { 14 | ASSUMPTION(m_forward_dependencies.operator bool()); 15 | ASSUMPTION(m_forward_dependencies->find(m_root_file) != m_forward_dependencies->cend()); 16 | 17 | ASSUMPTION(m_backward_dependencies.operator bool()); 18 | ASSUMPTION(m_backward_dependencies->find(m_root_file) != m_backward_dependencies->cend()); 19 | ASSUMPTION(m_backward_dependencies->find(m_root_file)->second.empty()); 20 | } 21 | 22 | 23 | std::vector const& dependencies_graph::files_loaded_by(std::string const& file) const 24 | { 25 | auto const it = m_forward_dependencies->find(file); 26 | ASSUMPTION(it != m_forward_dependencies->cend()); 27 | return it->second; 28 | } 29 | 30 | std::vector const& dependencies_graph::files_loading_file(std::string const& file) const 31 | { 32 | auto const it = m_backward_dependencies->find(file); 33 | ASSUMPTION(it != m_backward_dependencies->cend()); 34 | return it->second; 35 | } 36 | 37 | 38 | 39 | } 40 | -------------------------------------------------------------------------------- /MAL/loader/src/descriptor.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { 4 | 5 | 6 | descriptor::descriptor(platform_ptr const platform, 7 | sections_table_ptr const sections_table, 8 | special_sections_table_ptr const special_sections, 9 | address const entry_point, 10 | files_table_ptr const files_table, 11 | skipped_files_ptr const skipped_files, 12 | dependencies_graph_ptr const dependencies_of_loaded_files, 13 | dependencies_graph_ptr const dependencies_of_all_files, 14 | init_functions_ptr const init_function, 15 | fini_functions_ptr const fini_functions, 16 | relocations_ptr const performed_relocations, 17 | relocations_ptr const skipped_relocations, 18 | symbol_table_ptr const visible_symbol_table, 19 | symbol_table_ptr const hidden_symbol_table, 20 | warnings_ptr const warnings 21 | ) 22 | : m_platform(platform) 23 | , m_sections_table(sections_table) 24 | , m_special_sections(special_sections) 25 | , m_entry_point(entry_point) 26 | , m_files_table(files_table) 27 | , m_skipped_files(skipped_files) 28 | , m_dependencies_of_loaded_files(dependencies_of_loaded_files) 29 | , m_dependencies_of_all_files(dependencies_of_all_files) 30 | , m_init_functions(init_function) 31 | , m_fini_functions(fini_functions) 32 | , m_performed_relocations(performed_relocations) 33 | , m_skipped_relocations(skipped_relocations) 34 | , m_visible_symbol_table(visible_symbol_table) 35 | , m_hidden_symbol_table(hidden_symbol_table) 36 | , m_warnings(warnings) 37 | {} 38 | 39 | 40 | } 41 | -------------------------------------------------------------------------------- /MAL/loader/src/detail/address_fixing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | namespace loader { namespace detail { 5 | 6 | 7 | bool can_address_be_fixed(address const orig_address, address_fixes_map const& fixed_section_starts) 8 | { 9 | return fixed_section_starts.upper_bound(orig_address) != fixed_section_starts.cbegin(); 10 | } 11 | 12 | address fixed_base_address(address_fixes_map const& fixed_section_starts) 13 | { 14 | ASSUMPTION(!fixed_section_starts.empty()); 15 | return fixed_section_starts.cbegin()->second; 16 | } 17 | 18 | address adjust_address_to_fixed_sections(address const orig_address, 19 | address_fixes_map const& fixed_section_starts) 20 | { 21 | auto const it = fixed_section_starts.upper_bound(orig_address); 22 | ASSUMPTION(it != fixed_section_starts.cbegin()); 23 | auto const address_it = std::prev(it); 24 | return address_it->second + (orig_address - address_it->first); 25 | } 26 | 27 | 28 | }} 29 | -------------------------------------------------------------------------------- /MAL/loader/src/detail/load_mach_32bit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | namespace loader { namespace detail { 18 | 19 | 20 | std::string load_mach_32bit(std::ifstream& mach, file_props_ptr mach_props, 21 | uint32_t const num_load_commnads, 22 | uint32_t const num_bytes_of_load_commnads, 23 | bool const is_fixed_dynamic_library, 24 | load_props_mach& load_props) 25 | { 26 | ASSUMPTION( mach.is_open() ); 27 | ASSUMPTION( mach_props->num_address_bits() == 32U ); 28 | 29 | //bool const is_it_load_of_root_binary = load_props.root_file() == mach_props->path(); 30 | 31 | (void)is_fixed_dynamic_library; 32 | (void)load_props; 33 | 34 | uint64_t const commands_begin_offset = mach.tellg(); 35 | for (uint32_t i = 0U; i < num_load_commnads; ++i) 36 | { 37 | uint64_t const command_offset = mach.tellg(); 38 | 39 | uint32_t const commnad_type = read_bytes_to_int32_t(mach,4U,mach_props->is_in_big_endian()); 40 | uint32_t const commnad_size = read_bytes_to_int32_t(mach,4U,mach_props->is_in_big_endian()); 41 | 42 | if (commnad_size % 4U != 0U) 43 | return "Reached a load command which is not 4-byte aligned."; 44 | 45 | std::string error_message = ""; 46 | switch (commnad_type) 47 | { 48 | default: 49 | break; 50 | } 51 | if (!error_message.empty()) 52 | return error_message; 53 | if ((uint64_t)mach.tellg() > command_offset + commnad_size) 54 | return "The load command went beyond its expected size."; 55 | 56 | mach.seekg(command_offset + commnad_size); 57 | } 58 | if ((uint64_t)mach.tellg() > commands_begin_offset + num_bytes_of_load_commnads) 59 | return "Load commands went beyond their expected size."; 60 | 61 | return "The load of Mach-O 32 bit is NOT IMPLEMENTED YET!"; 62 | } 63 | 64 | 65 | }} 66 | -------------------------------------------------------------------------------- /MAL/loader/src/platform.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | std::ostream& operator<<(std::ostream& os, loader::architecture_t type) 6 | { 7 | switch(type) { 8 | case loader::architecture_t::ARM : os << "Arm"; break; 9 | case loader::architecture_t::ARM64 : os << "Arm64"; break; 10 | case loader::architecture_t::MIPS : os << "MIPS"; break; 11 | case loader::architecture_t::POWERPC : os << "PowerPC"; break; 12 | case loader::architecture_t::SPARC : os << "Sparc"; break; 13 | case loader::architecture_t::SPARC64 : os << "Sparc64"; break; 14 | case loader::architecture_t::X86_32 : os << "x86-32"; break; 15 | case loader::architecture_t::X86_64 : os << "x86-64"; break; 16 | case loader::architecture_t::UNKNOWN_ARCH : os << "Unknown"; break; 17 | default : os.setstate(std::ios_base::failbit); 18 | } 19 | return os; 20 | } 21 | 22 | std::ostream& operator<<(std::ostream& os, loader::abi_t type) 23 | { 24 | switch(type) { 25 | case loader::abi_t::DARWIN : os << "Apple Darwin"; break; 26 | case loader::abi_t::LINUX : os << "Linux"; break; 27 | case loader::abi_t::OPENBSD : os << "OpenBSD"; break; 28 | case loader::abi_t::SOLARIS : os << "Oracle Solaris"; break; 29 | case loader::abi_t::WINDOWS : os << "MS-Windows"; break; 30 | case loader::abi_t::UNIX : os << "UNIX"; break; 31 | case loader::abi_t::UNKNOWN_ABI : os << "Unknown"; break; 32 | default : os.setstate(std::ios_base::failbit); 33 | } 34 | return os; 35 | } 36 | 37 | loader::platform::platform(architecture_t const& arch, abi_t const& abi) 38 | : m_architecture(arch), m_abi(abi) 39 | {} 40 | 41 | bool operator==(loader::platform const& l, loader::platform const& r) 42 | { 43 | return ((l.architecture() == r.architecture()) && (l.abi() == r.abi())); 44 | } 45 | -------------------------------------------------------------------------------- /MAL/loader/src/relocations.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { namespace relocation_type { 4 | 5 | 6 | std::string UNKNOWN() { return "UNKNOWN"; } 7 | std::string DATA() { return "DATA"; } 8 | std::string FUNCTION() { return "FUNCTION"; } 9 | std::string COMMON() { return "COMMON"; } 10 | std::string TLS() { return "TLS"; } 11 | 12 | 13 | }} 14 | 15 | namespace loader { 16 | 17 | 18 | relocation::relocation(address const start_address, 19 | uint64_t const num_bytes, 20 | std::string const& type, 21 | uint64_t const stored_value, 22 | uint64_t const original_value, 23 | relocation_symbol_id const& symbol_id, 24 | std::string const& description) 25 | : m_start_address(start_address) 26 | , m_num_bytes(num_bytes) 27 | , m_type(type) 28 | , m_stored_value(stored_value) 29 | , m_original_value(original_value) 30 | , m_symbol_id(symbol_id) 31 | , m_description(description) 32 | {} 33 | 34 | 35 | } 36 | -------------------------------------------------------------------------------- /MAL/loader/src/special_sections.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { namespace special_section_name { 4 | 5 | 6 | std::string thread_local_storage() { return ".tls"; } 7 | std::string thread_local_storage_initialisers() { return "thread_local_storage_initialisers"; } 8 | std::string resources() { return ".rsrc"; } 9 | std::string load_configuration_structure() { return "load_configuration_structure"; } 10 | std::string exceptions() { return ".pdata"; } 11 | 12 | 13 | }} 14 | -------------------------------------------------------------------------------- /MAL/loader/src/special_sections/elf_tls.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { namespace special_section { 4 | 5 | 6 | elf_tls::elf_tls( 7 | address const start_address, 8 | address const image_end_address, 9 | address const end_address, 10 | uint64_t const file_offset, 11 | uint64_t const alignment, 12 | uint64_t const flags, 13 | bool const use_static_scheme 14 | ) 15 | : special_section_properties(start_address,end_address,"Template of the thread-local section.") 16 | , m_image_end_address(image_end_address) 17 | , m_file_offset(file_offset) 18 | , m_alignment(alignment) 19 | , m_flags(flags) 20 | , m_use_static_scheme(use_static_scheme) 21 | {} 22 | 23 | 24 | }} 25 | -------------------------------------------------------------------------------- /MAL/loader/src/special_sections/exceptions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { namespace special_section { 4 | 5 | 6 | exceptions::exceptions(address const start_address, address const end_address, 7 | std::vector< std::tuple > const& records) 8 | : special_section_properties(start_address,end_address,"An address-sorted table of exception handlers.") 9 | , m_records(records) 10 | {} 11 | 12 | 13 | }} 14 | -------------------------------------------------------------------------------- /MAL/loader/src/special_sections/load_configuration_structure.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { namespace special_section { 4 | 5 | load_configuration_structure::load_configuration_structure( 6 | address const start_address, 7 | address const end_address 8 | ) 9 | : special_section_properties(start_address,end_address, 10 | "Holds additional info for the loader, including SEH list (x86 only).") 11 | , m_timestamp(0) 12 | , m_major_version(0U) 13 | , m_minor_version(0U) 14 | , m_global_clear_flags(0U) 15 | , m_global_set_flags(0U) 16 | , m_critical_section_timeout(0U) 17 | , m_decommit_block_thresold(0ULL) 18 | , m_decommit_free_thresold(0ULL) 19 | , m_lock_prefix_table(0ULL) 20 | , m_max_alloc_size(0ULL) 21 | , m_memory_thresold(0ULL) 22 | , m_process_affinity_mask(0ULL) 23 | , m_process_heap_flags(0U) 24 | , m_service_pack_version(0U) 25 | , m_security_cookie(0ULL) 26 | , m_structured_exception_handlers() 27 | {} 28 | 29 | load_configuration_structure::load_configuration_structure( 30 | address const start_address, 31 | address const end_address, 32 | std::time_t const timestamp, 33 | uint16_t const major_version, 34 | uint16_t const minor_version, 35 | uint32_t const global_clear_flags, 36 | uint32_t const global_set_flags, 37 | uint32_t const critical_section_timeout, 38 | uint64_t const decommit_block_thresold, 39 | uint64_t const decommit_free_thresold, 40 | address const lock_prefix_table, 41 | uint64_t const max_alloc_size, 42 | uint64_t const memory_thresold, 43 | uint64_t const process_affinity_mask, 44 | uint32_t const process_heap_flags, 45 | uint16_t const service_pack_version, 46 | address const security_cookie, 47 | std::vector
const& structured_exception_handlers 48 | ) 49 | : special_section_properties(start_address,end_address, 50 | "Holds additional info for the loader, including SEH list (x86 only).") 51 | , m_timestamp(timestamp) 52 | , m_major_version(major_version) 53 | , m_minor_version(minor_version) 54 | , m_global_clear_flags(global_clear_flags) 55 | , m_global_set_flags(global_set_flags) 56 | , m_critical_section_timeout(critical_section_timeout) 57 | , m_decommit_block_thresold(decommit_block_thresold) 58 | , m_decommit_free_thresold(decommit_free_thresold) 59 | , m_lock_prefix_table(lock_prefix_table) 60 | , m_max_alloc_size(max_alloc_size) 61 | , m_memory_thresold(memory_thresold) 62 | , m_process_affinity_mask(process_affinity_mask) 63 | , m_process_heap_flags(process_heap_flags) 64 | , m_service_pack_version(service_pack_version) 65 | , m_security_cookie(security_cookie) 66 | , m_structured_exception_handlers(structured_exception_handlers) 67 | {} 68 | 69 | 70 | }} 71 | -------------------------------------------------------------------------------- /MAL/loader/src/special_sections/special_section_properties.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { 4 | 5 | 6 | special_section_properties::special_section_properties( 7 | address const start_address, 8 | address const end_address, 9 | std::string const& description) 10 | : m_start_address(start_address) 11 | , m_end_address(end_address) 12 | , m_description(description) 13 | {} 14 | 15 | 16 | } 17 | -------------------------------------------------------------------------------- /MAL/loader/src/special_sections/thread_local_storage_initialisers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace loader { namespace special_section { 4 | 5 | thread_local_storage_initialisers::thread_local_storage_initialisers( 6 | address const start_address, 7 | address const end_address, 8 | std::vector
const& init_functions 9 | ) 10 | : special_section_properties(start_address,end_address, 11 | "Section contains pointers to init functions of the thread local data.") 12 | , m_init_functions(init_functions) 13 | {} 14 | 15 | 16 | }} 17 | -------------------------------------------------------------------------------- /MAL/loader/tests/data_path.cpp: -------------------------------------------------------------------------------- 1 | #include "./data_path.hpp" 2 | #include 3 | 4 | #define xstr(s) str(s) 5 | #define str(s) #s 6 | 7 | std::string data_path() 8 | { 9 | static std::string const data_path = normalise_path( absolute_path( xstr(TESTS_DATA_PATH) ) ); 10 | return data_path; 11 | } 12 | 13 | std::string benchmarks_path() 14 | { 15 | return concatenate_file_paths(data_path(),"benchmarks/bin"); 16 | } 17 | -------------------------------------------------------------------------------- /MAL/loader/tests/data_path.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_LOADER_TESTS_DATA_PATH_HPP_INCLUDED 2 | # define REBOURS_MAL_LOADER_TESTS_DATA_PATH_HPP_INCLUDED 3 | 4 | # include 5 | 6 | 7 | std::string data_path(); 8 | std::string benchmarks_path(); 9 | 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /MAL/loader/tests/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TEST_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define TEST_SUCCESS(C) assert(C) 7 | # define TEST_FAILURE(C) assert(!(C)) 8 | 9 | #endif 10 | -------------------------------------------------------------------------------- /MAL/loader/tests/test01/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME test01) 2 | 3 | add_executable(test01 4 | main.cpp 5 | 6 | ../data_path.hpp 7 | ../data_path.cpp 8 | ) 9 | 10 | target_compile_definitions(test01 PRIVATE TESTS_DATA_PATH=${TESTS_DATA_PATH}) 11 | 12 | target_link_libraries(test01 13 | loader 14 | ) 15 | 16 | install(TARGETS test01 17 | CONFIGURATIONS Debug 18 | DESTINATION "${CMAKE_SYSTEM_NAME}_Debug/test/MAL/${PROJECT_NAME}" 19 | ) 20 | install(TARGETS test01 21 | CONFIGURATIONS Release 22 | DESTINATION "${CMAKE_SYSTEM_NAME}_Release/test/MAL/${PROJECT_NAME}" 23 | ) 24 | -------------------------------------------------------------------------------- /MAL/prologue/INSTALL: -------------------------------------------------------------------------------- 1 | prologue 2 | ======== 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/MAL/prologue/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DDESCRIPTOR_ROOT= 27 | -DPROGRAM_ROOT= 28 | -DPROLOGUE_BUILD_TESTS= 29 | 30 | 31 | All built binaries can be found in the directory: 32 | 33 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/MAL 34 | 35 | 36 | 2) MS-Windows 7+ 37 | ---------------- 38 | 39 | TODO 40 | 41 | -------------------------------------------------------------------------------- /MAL/prologue/README: -------------------------------------------------------------------------------- 1 | prologue 2 | ======== 3 | 4 | 5 | -------------------------------------------------------------------------------- /MAL/prologue/include/rebours/MAL/prologue/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /MAL/prologue/include/rebours/MAL/prologue/builder.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_PROLOGUE_BUILDER_HPP_INCLUDED 2 | # define REBOURS_MAL_PROLOGUE_BUILDER_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | 10 | namespace mal { namespace prologue { 11 | 12 | 13 | std::pair,std::unique_ptr > build(descriptor::storage const& description); 14 | 15 | 16 | }} 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /MAL/prologue/include/rebours/MAL/prologue/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /MAL/prologue/include/rebours/MAL/prologue/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MAL/prologue/include/rebours/MAL/prologue/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MAL/prologue/include/rebours/MAL/prologue/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MAL/prologue/include/rebours/MAL/prologue/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /MAL/prologue/src/builder.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace mal { namespace prologue { namespace detail { 6 | 7 | 8 | namespace x86_64_Linux { 9 | std::pair,std::unique_ptr > build(descriptor::storage const& description); 10 | } 11 | 12 | 13 | }}} 14 | 15 | namespace mal { namespace prologue { 16 | 17 | 18 | std::pair,std::unique_ptr > build(descriptor::storage const& description) 19 | { 20 | if (description.processor() == descriptor::processor_architecture::X86_64 && 21 | (description.system() == descriptor::operating_system::LINUX || 22 | description.system() == descriptor::operating_system::UNIX)) 23 | return detail::x86_64_Linux::build(description); 24 | 25 | UNREACHABLE(); 26 | } 27 | 28 | 29 | }} 30 | -------------------------------------------------------------------------------- /MAL/recogniser/INSTALL: -------------------------------------------------------------------------------- 1 | recogniser 2 | ========== 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/MAL/recogniser/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DDESCRIPTOR_ROOT= 27 | -DPROGRAM_ROOT= 28 | -DRECOGNISER_BUILD_TESTS= 29 | -DCAPSTONE_NEXT_ROOT= 30 | 31 | 32 | All built binaries can be found in the directory: 33 | 34 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/MAL 35 | 36 | 37 | 2) MS-Windows 7+ 38 | ---------------- 39 | 40 | TODO 41 | 42 | -------------------------------------------------------------------------------- /MAL/recogniser/README: -------------------------------------------------------------------------------- 1 | recogniser 2 | ========== 3 | 4 | 5 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/detail/recognise_x86_64_Linux_syscall_syscall.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_RECOGNISER_DETAIL_RECOGNISE_X86_64_LINUX_SYSCALL_SYSCALL_HPP_INCLUDED 2 | # define REBOURS_MAL_RECOGNISER_DETAIL_RECOGNISE_X86_64_LINUX_SYSCALL_SYSCALL_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | namespace mal { namespace recogniser { namespace detail { namespace x86_64_Linux { namespace syscall { 8 | 9 | 10 | ret_type recognise_syscall_1_write(reg_fn_type const& reg_fn, mem_fn_type const& , descriptor::storage const& D, 11 | uint8_t const num_bytes_of_instruction, microcode::program_component& C); 12 | ret_type recognise_syscall_5_fstat(reg_fn_type const& reg_fn, mem_fn_type const& , descriptor::storage const& D, 13 | uint8_t const num_bytes_of_instruction, microcode::program_component& C); 14 | ret_type recognise_syscall_9_mmap(reg_fn_type const& reg_fn, mem_fn_type const& , descriptor::storage const& D, 15 | uint8_t const num_bytes_of_instruction, microcode::program_component& C); 16 | ret_type recognise_syscall_231_exit_group(reg_fn_type const& , mem_fn_type const& , descriptor::storage const& , 17 | uint8_t const , microcode::program_component& C); 18 | 19 | 20 | }}}}} 21 | 22 | #endif 23 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/detail/recognition_data.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_RECOGNISER_DETAIL_RECOGNITION_DATA_HPP_INCLUDED 2 | # define REBOURS_MAL_RECOGNISER_DETAIL_RECOGNITION_DATA_HPP_INCLUDED 3 | 4 | # include 5 | //# include 6 | # include 7 | # include 8 | # include 9 | 10 | namespace mal { namespace recogniser { namespace detail { 11 | 12 | 13 | struct recognition_data 14 | { 15 | recognition_data(uint64_t const start_address, reg_fn_type const& reg_fn, mem_fn_type const& mem_fn); 16 | virtual ~recognition_data() {} 17 | 18 | virtual void recognise(descriptor::storage const& description) = 0; 19 | virtual bool dump(std::string const& dump_file_pathname) const = 0; 20 | 21 | uint64_t start_address() const noexcept { return m_start_address; } 22 | reg_fn_type const& reg_fn() const noexcept { return m_reg_fn; } 23 | mem_fn_type const& mem_fn() const noexcept { return m_mem_fn; } 24 | 25 | // std::unordered_map reg_values() const noexcept { return m_reg_values; } 26 | // std::unordered_map mem_values() const noexcept { return m_mem_values; } 27 | 28 | std::shared_ptr program() const noexcept { return m_program; } 29 | std::string const& asm_text() const noexcept { return m_asm_text; } 30 | std::string const& asm_bytes() const noexcept { return m_asm_bytes; } 31 | uint8_t error_result() const noexcept { return m_error_result; } 32 | uint64_t error_address() const noexcept { return m_error_address; } 33 | uint8_t error_rights() const noexcept { return m_error_rights; } 34 | std::vector const& buffer() const noexcept { return m_buffer; } 35 | 36 | void set_asm_text(std::string const& value) { m_asm_text = value; } 37 | void set_asm_bytes(std::string const& value) { m_asm_bytes = value; } 38 | void set_error_result(uint8_t const value) noexcept; 39 | void set_error_address(uint64_t const value) noexcept { m_error_address = value; } 40 | void set_error_rights(uint8_t const value) noexcept; 41 | std::vector& buffer() { return m_buffer; } 42 | 43 | private: 44 | uint64_t m_start_address; 45 | reg_fn_type m_reg_fn; 46 | mem_fn_type m_mem_fn; 47 | 48 | // std::unordered_map m_reg_values; 49 | // std::unordered_map m_mem_values; 50 | 51 | std::shared_ptr m_program; 52 | std::string m_asm_text; 53 | std::string m_asm_bytes; 54 | uint8_t m_error_result; 55 | uint64_t m_error_address; 56 | uint8_t m_error_rights; 57 | std::vector m_buffer; 58 | }; 59 | 60 | 61 | using recognition_data_ptr = std::shared_ptr; 62 | 63 | 64 | }}} 65 | 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/detail/recognition_engine_x86_64_Linux.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_RECOGNISER_DETAIL_RECOGNITION_ENGINE_X86_64_LINUX_HPP_INCLUDED 2 | # define REBOURS_MAL_RECOGNISER_DETAIL_RECOGNITION_ENGINE_X86_64_LINUX_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | 10 | namespace mal { namespace recogniser { namespace detail { namespace x86_64_Linux { 11 | 12 | 13 | struct recognition_engine 14 | { 15 | recognition_engine(csh const handle, cs_insn* instruction); 16 | ~recognition_engine(); 17 | 18 | csh handle() const noexcept { return m_handle; } 19 | cs_insn const& instruction() const noexcept { return *m_instruction; } 20 | cs_x86 const& details() const noexcept { return *m_details; } 21 | 22 | unsigned int instruction_id() const { return instruction().id; } 23 | 24 | uint8_t get_rex() const { return details().rex; } 25 | bool uses_rex() const { return get_rex() != 0U; } 26 | 27 | uint8_t num_bytes_of_instruction() const { return instruction().size; } 28 | uint8_t get_byte_of_instruction(uint8_t const idx) const; 29 | 30 | uint8_t get_address_size() const { return details().addr_size; } 31 | 32 | uint8_t get_num_instruction_groups() const; 33 | uint8_t get_instruction_group(uint8_t const idx) const; 34 | 35 | bool is_relative_jump() const; 36 | bool is_relative_call() const; 37 | 38 | uint8_t num_operands() const { return details().op_count; } 39 | bool is_register_operand(uint8_t const idx) const; 40 | bool is_memory_operand(uint8_t const idx) const; 41 | bool is_segment_register_of_memory_operand_valid(uint8_t const idx) const; 42 | bool is_index_register_of_memory_operand_valid(uint8_t const idx) const; 43 | bool is_base_register_of_memory_operand_valid(uint8_t const idx) const; 44 | bool is_immediate_operand(uint8_t const idx) const; 45 | bool is_floating_point_operand(uint8_t const idx) const; 46 | bool is_read_operand(uint8_t const idx) const; 47 | bool is_write_operand(uint8_t const idx) const; 48 | uint8_t get_num_bytes_of_operand(uint8_t const idx) const; 49 | register_info get_register_operand(uint8_t const idx, descriptor::storage const& D) const; 50 | register_info get_segment_register_of_memory_operand(uint8_t const idx, descriptor::storage const& D) const; 51 | register_info get_index_register_of_memory_operand(uint8_t const idx, descriptor::storage const& D) const; 52 | register_info get_base_register_of_memory_operand(uint8_t const idx, descriptor::storage const& D) const; 53 | int get_scale_of_index_register_of_memory_operand(uint8_t const idx) const; 54 | int64_t get_displacement_of_memory_operand(uint8_t const idx) const; 55 | int64_t get_immediate_operand(uint8_t const idx) const; 56 | double get_floating_point_operand(uint8_t const idx) const; 57 | 58 | private: 59 | csh m_handle; 60 | cs_insn* m_instruction; 61 | cs_x86* m_details; 62 | }; 63 | 64 | 65 | }}}} 66 | 67 | #endif 68 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/detail/register_info.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_RECOGNISER_DETAIL_REGISTER_INFO_HPP_INCLUDED 2 | # define REBOURS_MAL_RECOGNISER_DETAIL_REGISTER_INFO_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace mal { namespace descriptor { 9 | struct storage; 10 | }} 11 | 12 | namespace mal { namespace recogniser { namespace detail { 13 | 14 | 15 | using register_info = std::pair; 18 | 19 | register_info get_register_info(std::string const& reg_name, mal::descriptor::storage const& D); 20 | 21 | 22 | }}} 23 | 24 | #endif 25 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/dump.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MAL_RECOGNISER_DUMP_HPP_INCLUDED 2 | # define MAL_RECOGNISER_DUMP_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | namespace mal { namespace recogniser { 8 | 9 | 10 | bool dump_details_of_recognised_instruction(recognition_result const& result, std::string const& dump_file_pathname); 11 | 12 | 13 | }} 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/file_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FILE_UTILS_HPP_INCLUDED 2 | # define FILE_UTILS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | 10 | /** 11 | * This module implements utility functions which provide us disc-related functionality, 12 | * like manipulation with disc paths (concatenation/splitting), checking for existence 13 | * of files, etc. 14 | */ 15 | 16 | namespace fileutl { 17 | 18 | 19 | bool file_exists(std::string const& pathname); 20 | bool is_directory(std::string const& pathname); 21 | uint64_t file_size(std::string const& file_pathname); 22 | std::string parse_name_in_pathname(std::string const& file_pathname); 23 | std::string parse_path_in_pathname(std::string const& file_pathname); 24 | void create_directory(std::string const& pathname); 25 | std::string concatenate_file_paths(std::string const& left_path, std::string const& right_path); 26 | std::string absolute_path(std::string const& path); 27 | std::string normalise_path(std::string const& path); 28 | void split_pathname(std::string const& pathname, std::vector& output); 29 | std::string join_path_parts(std::vector const& parts); 30 | std::string get_common_preffix(std::string const& pathname1, std::string const& pathname2); 31 | std::string get_relative_path(std::string const& pathname, std::string const& directory); 32 | 33 | 34 | } 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MAL/recogniser/include/rebours/MAL/recogniser/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /MAL/recogniser/src/detail/recognise_x86_64_Linux_syscall_utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace mal { namespace recogniser { namespace detail { namespace x86_64_Linux { namespace syscall { 7 | 8 | 9 | ret_type make_succes() 10 | { 11 | return ret_type{0U,0ULL,0U,true}; 12 | } 13 | 14 | ret_type make_failure() 15 | { 16 | return ret_type{0U,0ULL,0U,false}; 17 | } 18 | 19 | ret_type make_reg_error(uint64_t const address) 20 | { 21 | ASSUMPTION(address != 0ULL); 22 | return ret_type{1U,address,0U,true}; 23 | } 24 | 25 | ret_type make_mem_error(int16_t const fn_retval, uint64_t const address, uint8_t const rights) 26 | { 27 | ASSUMPTION(fn_retval == -1 || fn_retval == -2 || fn_retval == -3); 28 | ASSUMPTION(rights == 1U || rights == 2U); 29 | return ret_type{1U << (-fn_retval),address,rights,true}; 30 | } 31 | 32 | 33 | ret_type read_register(std::string const& reg_name, descriptor::storage const& D, reg_fn_type const& reg_fn, std::vector& buffer) 34 | { 35 | register_info const reg_info = get_register_info(reg_name,D); 36 | ASSUMPTION(reg_info.first != 0ULL); 37 | for (uint64_t adr = reg_info.first; adr != reg_info.first + reg_info.second; ++adr) 38 | { 39 | int16_t const result = reg_fn(adr); 40 | ASSUMPTION(result < 256 && result > -2); 41 | if (result < 0) 42 | return make_reg_error(adr); 43 | buffer.push_back((uint8_t)result); 44 | } 45 | return make_succes(); 46 | } 47 | 48 | 49 | }}}}} 50 | -------------------------------------------------------------------------------- /MAL/recogniser/src/detail/recognition_data.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace mal { namespace recogniser { namespace detail { 8 | 9 | 10 | recognition_data::recognition_data(uint64_t const start_address, reg_fn_type const& reg_fn, mem_fn_type const& mem_fn) 11 | : m_start_address(start_address) 12 | , m_reg_fn(reg_fn) 13 | , m_mem_fn(mem_fn) 14 | , m_program(microcode::create_initial_program("Rebours_recognition_result", 15 | msgstream() << "Microcode representation of a native instruction stored at the address " 16 | << start_address 17 | << ".\nThis program was built by Rebours' MAL/recogniser.")) 18 | , m_asm_text() 19 | , m_asm_bytes() 20 | , m_error_result(0U) 21 | , m_error_address(0ULL) 22 | , m_error_rights(0U) 23 | , m_buffer() 24 | {} 25 | 26 | void recognition_data::set_error_result(uint8_t const value) noexcept 27 | { 28 | ASSUMPTION(value == 1U || value == 2U || value == 4U || value == 254U || value == 255U); 29 | m_error_result = value; 30 | } 31 | 32 | void recognition_data::set_error_rights(uint8_t const value) noexcept 33 | { 34 | ASSUMPTION(value == 1U || value == 2U); 35 | m_error_rights = value; 36 | } 37 | 38 | 39 | }}} 40 | -------------------------------------------------------------------------------- /MAL/recogniser/src/detail/register_info.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace mal { namespace recogniser { namespace detail { 10 | 11 | 12 | register_info get_register_info(std::string const& reg_name, mal::descriptor::storage const& D) 13 | { 14 | ASSUMPTION(D.registers_to_ranges().count(reg_name) != 0ULL); 15 | mal::descriptor::address_range const rng = D.registers_to_ranges().at(reg_name); 16 | ASSUMPTION(rng.second > rng.first && rng.second - rng.first < 256); 17 | return {rng.first,rng.second - rng.first}; 18 | } 19 | 20 | 21 | }}} 22 | -------------------------------------------------------------------------------- /MAL/recogniser/src/recognise.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace mal { namespace recogniser { namespace detail { 9 | 10 | 11 | std::shared_ptr get_implementation_details(recognition_result const& result) { return result.m_data; } 12 | 13 | 14 | namespace x86_64_Linux { 15 | recognition_data_ptr recognise(descriptor::storage const& description, uint64_t const start_address, reg_fn_type const& reg_fn, mem_fn_type const& mem_fn); 16 | } 17 | 18 | 19 | }}} 20 | 21 | namespace mal { namespace recogniser { 22 | 23 | 24 | recognition_result::recognition_result(std::shared_ptr const data) 25 | : m_data(data) 26 | {} 27 | 28 | std::shared_ptr recognition_result::program() const noexcept 29 | { 30 | return result() != 0U || (m_data->program()->num_components() == 1ULL && m_data->program()->component(0ULL).edges().empty()) ? 31 | std::shared_ptr() : m_data->program(); 32 | } 33 | 34 | std::string const& recognition_result::asm_text() const noexcept 35 | { 36 | return m_data->asm_text(); 37 | } 38 | 39 | std::string const& recognition_result::asm_bytes() const noexcept 40 | { 41 | return m_data->asm_bytes(); 42 | } 43 | 44 | uint8_t recognition_result::result() const noexcept 45 | { 46 | return m_data->error_result(); 47 | } 48 | 49 | uint64_t recognition_result::address() const noexcept 50 | { 51 | return m_data->error_address(); 52 | } 53 | 54 | uint8_t recognition_result::rights() const noexcept 55 | { 56 | return m_data->error_rights(); 57 | } 58 | 59 | std::vector const& recognition_result::buffer() const noexcept 60 | { 61 | return m_data->buffer(); 62 | } 63 | 64 | 65 | recognition_result recognise(descriptor::storage const& description, 66 | uint64_t const start_address, 67 | reg_fn_type const& reg_fn, 68 | mem_fn_type const& mem_fn) 69 | { 70 | if (description.processor() == descriptor::processor_architecture::X86_64 && 71 | (description.system() == descriptor::operating_system::LINUX || 72 | description.system() == descriptor::operating_system::UNIX)) 73 | return recognition_result( detail::x86_64_Linux::recognise(description,start_address,reg_fn,mem_fn) ); 74 | 75 | UNREACHABLE(); 76 | } 77 | 78 | 79 | }} 80 | -------------------------------------------------------------------------------- /MAL/reloader/INSTALL: -------------------------------------------------------------------------------- 1 | reloader 2 | ======== 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/MAL/reloader/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DPROGRAM_ROOT= 27 | -DRELOADER_BUILD_TESTS= 28 | 29 | 30 | All built binaries can be found in the directory: 31 | 32 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/MAL 33 | 34 | 35 | 2) MS-Windows 7+ 36 | ---------------- 37 | 38 | TODO 39 | 40 | -------------------------------------------------------------------------------- /MAL/reloader/README: -------------------------------------------------------------------------------- 1 | reloader 2 | ======== 3 | 4 | 5 | -------------------------------------------------------------------------------- /MAL/reloader/include/rebours/MAL/reloader/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /MAL/reloader/include/rebours/MAL/reloader/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /MAL/reloader/include/rebours/MAL/reloader/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /MAL/reloader/include/rebours/MAL/reloader/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /MAL/reloader/include/rebours/MAL/reloader/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /MAL/reloader/include/rebours/MAL/reloader/reload.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_MAL_RELOADER_RELOAD_HPP_INCLUDED 2 | # define REBOURS_MAL_RELOADER_RELOAD_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | namespace mal { namespace reloader { 10 | 11 | 12 | descriptor::file_descriptor_ptr reload(microcode::program const& prologue, 13 | microcode::annotations const& annotations, 14 | bool const reload_also_file_info, 15 | std::string const& error_message); 16 | 17 | 18 | }} 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /MAL/reloader/include/rebours/MAL/reloader/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /MAL/reloader/src/reload.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | namespace mal { namespace reloader { 6 | 7 | 8 | descriptor::file_descriptor_ptr reload(microcode::program const& prologue, 9 | microcode::annotations const& annotations, 10 | bool const reload_also_file_info, 11 | std::string const& error_message) 12 | { 13 | ASSUMPTION(false); // not implemented yet! 14 | } 15 | 16 | 17 | }} 18 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Rebours 2 | A framework for control-flow recovery in binary programs. 3 | -------------------------------------------------------------------------------- /analysis/native_execution/INSTALL: -------------------------------------------------------------------------------- 1 | native_execution 2 | ================ 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/analyses/native_execution/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DMAL_PROGRAM_ROOT= 27 | -DMAL_RECOGNISER_ROOT= 28 | -DNATIVE_EXECUTION_BUILD_TESTS= 29 | 30 | 31 | All built binaries can be found in the directory: 32 | 33 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/analysis 34 | 35 | 36 | 2) MS-Windows 7+ 37 | ---------------- 38 | 39 | TODO 40 | 41 | -------------------------------------------------------------------------------- /analysis/native_execution/README: -------------------------------------------------------------------------------- 1 | native_execution 2 | ================ 3 | 4 | 5 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/branching_condition.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_ANALYSIS_NATIVE_EXECUTION_BRANCHING_CONDITION_HPP_INCLUDED 2 | # define REBOURS_ANALYSIS_NATIVE_EXECUTION_BRANCHING_CONDITION_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | # include 10 | # include 11 | # include 12 | # include 13 | # include 14 | 15 | namespace analysis { namespace natexe { 16 | 17 | 18 | 19 | 20 | 21 | }} 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/exploration.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_ANALYSIS_NATIVE_EXPLORATION_HPP_INCLUDED 2 | # define REBOURS_ANALYSIS_NATIVE_EXPLORATION_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | # include 10 | # include 11 | 12 | namespace analysis { namespace natexe { 13 | 14 | 15 | std::string merge_recovered_traces(microcode::program& program, recovery_properties& rprops); 16 | 17 | std::string choose_next_unexplored_exit(microcode::program const& program, recovery_properties const& rprops, node_id& exit); 18 | 19 | std::string find_next_goal_from_unexplored_exit(microcode::program const& program, recovery_properties const& rprops, node_id const exit, edge_id& next_goal); 20 | 21 | std::string find_traces_related_to_next_goal(microcode::program const& prologue, microcode::program const& program, recovery_properties const& rprops, 22 | edge_id const next_goal, std::vector< std::pair,node_counter_type> >& traces); 23 | 24 | std::string compute_input_for_reaching_next_goal(microcode::program const& prologue, microcode::program const& program, recovery_properties const& rprops, 25 | edge_id const next_goal, std::vector< std::pair,node_counter_type> > const& traces, 26 | std::unordered_map > const& input_streams); 27 | 28 | void close_unexplored_exit(microcode::program& program, recovery_properties& rprops, node_id const exit); 29 | 30 | std::string setup_next_execution_properties(execution_properties& eprops, std::unordered_map > const& input_streams, 31 | std::vector const& default_stack_init_data); 32 | 33 | 34 | }} 35 | 36 | #endif 37 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/file_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FILE_UTILS_HPP_INCLUDED 2 | # define FILE_UTILS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | 10 | /** 11 | * This module implements utility functions which provide us disc-related functionality, 12 | * like manipulation with disc paths (concatenation/splitting), checking for existence 13 | * of files, etc. 14 | */ 15 | 16 | namespace fileutl { 17 | 18 | 19 | bool file_exists(std::string const& pathname); 20 | bool is_directory(std::string const& pathname); 21 | uint64_t file_size(std::string const& file_pathname); 22 | std::string parse_name_in_pathname(std::string const& file_pathname); 23 | std::string parse_path_in_pathname(std::string const& file_pathname); 24 | std::string remove_extension(std::string const& filename); 25 | void create_directory(std::string const& pathname); 26 | std::string concatenate_file_paths(std::string const& left_path, std::string const& right_path); 27 | std::string absolute_path(std::string const& path); 28 | std::string normalise_path(std::string const& path); 29 | void split_pathname(std::string const& pathname, std::vector& output); 30 | std::string join_path_parts(std::vector const& parts); 31 | std::string get_common_preffix(std::string const& pathname1, std::string const& pathname2); 32 | std::string get_relative_path(std::string const& pathname, std::string const& directory); 33 | 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/std_pair_hash.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STD_PAIR_HASH_HPP_INCLUDED 2 | # define STD_PAIR_HASH_HPP_INCLUDED 3 | 4 | # include 5 | 6 | template 7 | inline void hash_combine(std::size_t & seed, const T & v) 8 | { 9 | std::hash hasher; 10 | seed ^= hasher(v) + 0x9e3779b9 + (seed << 6) + (seed >> 2); 11 | } 12 | 13 | namespace std 14 | { 15 | template struct hash> 16 | { 17 | inline size_t operator()(const pair & v) const 18 | { 19 | size_t seed = 0; 20 | ::hash_combine(seed, v.first); 21 | ::hash_combine(seed, v.second); 22 | return seed; 23 | } 24 | }; 25 | } 26 | 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /analysis/native_execution/include/rebours/analysis/native_execution/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /analysis/native_execution/src/branching_condition.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | //#include 6 | //#include 7 | 8 | namespace analysis { namespace natexe { namespace detail { 9 | 10 | 11 | }}} 12 | 13 | namespace analysis { namespace natexe { 14 | 15 | 16 | 17 | 18 | }} 19 | -------------------------------------------------------------------------------- /analysis/native_execution/src/choose_next_unexplored_exit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace analysis { namespace natexe { 8 | 9 | 10 | std::string choose_next_unexplored_exit(microcode::program const& program, recovery_properties const& rprops, node_id& exit) 11 | { 12 | (void)program; 13 | for (auto const& u_i : rprops.unexplored()) 14 | if (is_inside_important_code(u_i.second.IP(),rprops.important_code())) 15 | { 16 | exit = u_i.first; 17 | return ""; 18 | } 19 | for (auto const& u_i : rprops.unexplored()) 20 | if (!is_inside_important_code(u_i.second.IP(),rprops.important_code())) 21 | { 22 | exit = u_i.first; 23 | return ""; 24 | } 25 | 26 | return "Done!"; 27 | } 28 | 29 | 30 | }} 31 | -------------------------------------------------------------------------------- /analysis/native_execution/src/close_unexplored_exit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace analysis { namespace natexe { 8 | 9 | 10 | void close_unexplored_exit(microcode::program& program, recovery_properties& rprops, node_id const exit) 11 | { 12 | uint64_t const component_index = microcode::find_component(program,exit); 13 | INVARIANT(component_index < program.num_components()); 14 | microcode::program_component& C = program.component(component_index); 15 | 16 | C.insert_sequence(exit,{microcode::create_MISCELLANEOUS__STOP()}); 17 | rprops.update_unexplored(exit); 18 | } 19 | 20 | 21 | }} 22 | -------------------------------------------------------------------------------- /analysis/native_execution/src/find_next_goal_from_unexplored_exit.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | namespace analysis { namespace natexe { 9 | 10 | 11 | std::string find_next_goal_from_unexplored_exit(microcode::program const& program, recovery_properties const& rprops, node_id const exit, edge_id& next_goal) 12 | { 13 | uint64_t const component_index = microcode::find_component(program,exit); 14 | INVARIANT(component_index < program.num_components()); 15 | microcode::program_component const& C = program.component(component_index); 16 | 17 | std::deque queue{exit}; 18 | std::unordered_set visited; 19 | do 20 | { 21 | node_id const u = queue.front(); 22 | queue.pop_front(); 23 | 24 | if (visited.count(u) != 0ULL) 25 | continue; 26 | visited.insert(u); 27 | 28 | std::vector const& succ = C.successors(u); 29 | if (succ.size() == 2ULL) 30 | { 31 | bool const uf = rprops.visited_branchings().count({u,succ.front()}); 32 | bool const ub = rprops.visited_branchings().count({u,succ.back()}); 33 | if (uf && !ub) 34 | { 35 | next_goal = {u,succ.back()}; 36 | return ""; 37 | } 38 | if (!uf && ub) 39 | { 40 | next_goal = {u,succ.front()}; 41 | return ""; 42 | } 43 | } 44 | 45 | for (node_id const v : C.predecessors(u)) 46 | queue.push_back(v); 47 | } 48 | while (!queue.empty()); 49 | 50 | return msgstream() << "Cannot find goal edge from the unexplored exit node " << exit << "."; 51 | } 52 | 53 | 54 | }} 55 | -------------------------------------------------------------------------------- /analysis/native_execution/src/find_traces_related_to_next_goal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace analysis { namespace natexe { 8 | 9 | 10 | std::string find_traces_related_to_next_goal(microcode::program const& prologue, microcode::program const& program, recovery_properties const& rprops, 11 | edge_id const next_goal, std::vector< std::pair,node_counter_type> >& traces) 12 | { 13 | (void)prologue; 14 | (void)program; 15 | for (index eid = 0ULL; eid < rprops.num_executions_performed(); ++eid) 16 | for (thread_id const tid : rprops.threads_of_execution(eid)) 17 | for (node_counter_type const cnt : rprops.branchings().at(eid).at(tid)) 18 | if (rprops.node_histories().at(eid).at(tid).at(cnt) == next_goal.first) 19 | traces.push_back({{eid,tid},cnt}); 20 | INVARIANT(!traces.empty()); 21 | return ""; 22 | } 23 | 24 | 25 | }} 26 | -------------------------------------------------------------------------------- /analysis/native_execution/src/merge_recovered_traces.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace analysis { namespace natexe { 8 | 9 | 10 | std::string merge_recovered_traces(microcode::program& program, recovery_properties& rprops) 11 | { 12 | (void)program; 13 | (void)rprops; 14 | 15 | // TODO! 16 | 17 | return ""; 18 | } 19 | 20 | 21 | }} 22 | -------------------------------------------------------------------------------- /analysis/native_execution/src/setup_next_execution_properties.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace analysis { namespace natexe { 8 | 9 | 10 | std::string setup_next_execution_properties(execution_properties& eprops, std::unordered_map > const& input_streams, 11 | std::vector const& default_stack_init_data) 12 | { 13 | 14 | 15 | 16 | 17 | return "ERROR in 'analysis::natexe::setup_next_execution_properties()': NOT IMPLEMENTED YET!"; 18 | } 19 | 20 | 21 | }} 22 | -------------------------------------------------------------------------------- /bitvectors/INSTALL: -------------------------------------------------------------------------------- 1 | bitvectors 2 | ========== 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/bitvectors/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DBITVECTORS_BUILD_TOOLS= 27 | -DBITVECTORS_BUILD_TESTS= 28 | -DZ3_ROOT= 29 | -DBOOLECTOR_ROOT= 30 | -DMATHSAT5_ROOT= 31 | 32 | Where '' is a choice of flags with 'flag0' is the 33 | default choice when the variable is not triggered through the cmake 34 | '-D' option. 35 | 36 | All built binaries can be found in the directory: 37 | 38 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib 39 | 40 | 41 | 2) MS-Windows 7+ 42 | ---------------- 43 | 44 | TODO 45 | 46 | -------------------------------------------------------------------------------- /bitvectors/README: -------------------------------------------------------------------------------- 1 | bitvectors 2 | ========== 3 | 4 | 5 | This module implements bitvector expressions. There is included 6 | simplification and satisfiability checking functionality boosted 7 | by SMT solvers like Boolector, MathSAT5, and Z3. 8 | 9 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/detail/execute_shell_command_with_async_pipe.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_BITVECTORS_DETAIL_EXECUTE_SHELL_COMMAND_WITH_ASYNC_PIPE_HPP_INCLUDED 2 | # define REBOURS_BITVECTORS_DETAIL_EXECUTE_SHELL_COMMAND_WITH_ASYNC_PIPE_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace bv { namespace detail { 9 | 10 | 11 | bool execute_shell_command_with_async_pipe(std::string const& shell_command, std::function const& interrupt, 12 | std::stringstream& ostr); 13 | 14 | 15 | }} 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/detail/file_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_BITVECTORS_DETAIL_FILE_UTILS_HPP_INCLUDED 2 | # define REBOURS_BITVECTORS_DETAIL_FILE_UTILS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | namespace bv { namespace detail { 8 | 9 | 10 | void enumerate_files_by_pattern(const std::string& pattern, std::vector& output_pathnames); 11 | 12 | bool delete_file(const std::string& pathname); 13 | 14 | }} 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/detail/sat_checking_interruption_function.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_BITVECTORS_DETAIL_SAT_CHECKING_INTERRUPTION_FUNCTION_HPP_INCLUDED 2 | # define REBOURS_BITVECTORS_DETAIL_SAT_CHECKING_INTERRUPTION_FUNCTION_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace bv { namespace detail { 9 | 10 | 11 | std::function get_sat_checking_interruption_function(uint32_t const timeout_in_milliseconds, 12 | sat_result const& output, std::mutex& output_mutex); 13 | 14 | 15 | }} 16 | 17 | #endif 18 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/detail/unique_handles.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_BITVECTORS_DETAIL_UNIQUE_HANDLES_HPP_INCLUDED 2 | # define REBOURS_BITVECTORS_DETAIL_UNIQUE_HANDLES_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace bv { namespace detail { 7 | 8 | 9 | /** 10 | * Each instances of this type possesses a unique number. More precisely, it is 11 | * impossible for two different instances of this type to exist at the same time 12 | * and to store the same number. Construction of instances is thread-safe. 13 | * 14 | * The type is usefull to distinguish some global (shared) data. For instance, 15 | * generation of temporary files. 16 | */ 17 | struct unique_handle 18 | { 19 | unique_handle(); 20 | ~unique_handle(); 21 | unique_handle& operator=(unique_handle const& ) = delete; 22 | unique_handle(unique_handle const& ) = delete; 23 | 24 | uint32_t value() const noexcept { return m_id; } 25 | operator uint32_t() const noexcept { return value(); } 26 | 27 | private: 28 | uint32_t m_id; 29 | }; 30 | 31 | 32 | }} 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/expression_algo.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_BITVECTORS_EXPRESSION_ALGO_HPP_INCLUDED 2 | # define REBOURS_BITVECTORS_EXPRESSION_ALGO_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | namespace bv { 10 | 11 | 12 | bool find_symbols(expression const e, std::function const selector, 13 | std::unordered_set& output); 14 | 15 | bool find_unintepreted_symbols(expression const e, std::unordered_set& output); 16 | 17 | 18 | expression to_conjunction(std::vector const& conjuncts); 19 | 20 | 21 | } 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/large_types.hpp: -------------------------------------------------------------------------------- 1 | #ifndef LARGE_TYPES_HPP_INCLUDED 2 | # define LARGE_TYPES_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | # include 10 | 11 | 12 | struct uint128_t 13 | { 14 | using data_type = std::array; 15 | 16 | uint128_t() : m_data() {} 17 | uint128_t(uint64_t const lo, uint64_t const hi = 0ULL); 18 | 19 | static constexpr uint64_t size() noexcept { return std::tuple_size::value; } 20 | uint8_t at(uint64_t const i) const { return m_data.at(i); } 21 | uint8_t& at(uint64_t const i) { return m_data.at(i); } 22 | 23 | uint8_t const* data() const { return m_data.data(); } 24 | uint8_t* data() { return m_data.data(); } 25 | 26 | uint64_t lo() const { return *reinterpret_cast(data()); } 27 | uint64_t hi() const { return *reinterpret_cast(data() + 8ULL); } 28 | 29 | uint64_t& lo() { return *reinterpret_cast(data()); } 30 | uint64_t& hi() { return *reinterpret_cast(data() + 8ULL); } 31 | 32 | private: 33 | data_type m_data; 34 | }; 35 | 36 | uint128_t operator+(uint128_t const& a, uint128_t const& b); 37 | uint128_t operator*(uint128_t const& a, uint128_t const& b); 38 | uint128_t operator%(uint128_t const& a, uint128_t const& b); 39 | uint128_t operator/(uint128_t const& a, uint128_t const& b); 40 | 41 | bool operator==(uint128_t const& a, uint128_t const& b); 42 | bool operator<(uint128_t const& a, uint128_t const& b); 43 | 44 | inline bool operator!=(uint128_t const& a, uint128_t const& b) { return !(a == b); } 45 | inline bool operator<=(uint128_t const& a, uint128_t const& b) { return a == b || a < b; } 46 | inline bool operator>=(uint128_t const& a, uint128_t const& b) { return a == b || b < a; } 47 | inline bool operator>(uint128_t const& a, uint128_t const& b) { return b < a; } 48 | 49 | 50 | using float80_t = std::array; 51 | 52 | 53 | std::string to_string(uint128_t const& a, std::ios_base::fmtflags const flags = std::ios::dec); 54 | 55 | 56 | msgstream& operator<<(msgstream& ostr, uint128_t const& a); 57 | std::ostream& operator<<(std::ostream& ostr, uint128_t const& a); 58 | 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /bitvectors/include/rebours/bitvectors/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /bitvectors/src/detail/file_utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | # if defined(WIN32) 4 | # error "NOT IMPLEMENTED YET!" 5 | # elif defined(__linux__) || defined(__APPLE__) 6 | # include 7 | # else 8 | # error "Unsuported platform." 9 | # endif 10 | 11 | namespace bv { namespace detail { 12 | 13 | 14 | void enumerate_files_by_pattern(const std::string& pattern, std::vector& output_pathnames) 15 | { 16 | ::glob_t glob_result; 17 | ::glob(pattern.c_str(),GLOB_TILDE,NULL,&glob_result); 18 | for(unsigned int i = 0U; i < glob_result.gl_pathc; ++i) 19 | output_pathnames.push_back(glob_result.gl_pathv[i]); 20 | globfree(&glob_result); 21 | } 22 | 23 | bool delete_file(const std::string& pathname) 24 | { 25 | return std::remove(pathname.c_str()) != 0; 26 | } 27 | 28 | 29 | }} 30 | -------------------------------------------------------------------------------- /bitvectors/src/detail/sat_checking_interruption_function.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace bv { namespace detail { namespace { 4 | 5 | 6 | bool sat_checking_interruption_function(std::chrono::system_clock::time_point const start_time, 7 | uint32_t const timeout_in_milliseconds, 8 | sat_result const& output, std::mutex& output_mutex) 9 | { 10 | std::chrono::system_clock::time_point const current_time = std::chrono::high_resolution_clock::now(); 11 | double const duration = std::chrono::duration(current_time - start_time).count(); 12 | if (duration >= double(timeout_in_milliseconds)) 13 | return true; 14 | 15 | { 16 | std::lock_guard const lock(output_mutex); 17 | if (output != sat_result::FAIL) 18 | return true; 19 | } 20 | 21 | return false; 22 | } 23 | 24 | 25 | }}} 26 | 27 | namespace bv { namespace detail { 28 | 29 | 30 | std::function get_sat_checking_interruption_function(uint32_t const timeout_in_milliseconds, 31 | sat_result const& output, std::mutex& output_mutex) 32 | { 33 | return std::bind(&sat_checking_interruption_function, 34 | std::chrono::high_resolution_clock::now(), 35 | timeout_in_milliseconds, 36 | std::cref(output), 37 | std::ref(output_mutex) 38 | ); 39 | } 40 | 41 | 42 | }} 43 | -------------------------------------------------------------------------------- /bitvectors/src/detail/unique_handles.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | namespace bv { namespace detail { namespace { 7 | 8 | std::mutex mutex_for_handles; 9 | std::set handles; 10 | 11 | }}} 12 | 13 | namespace bv { namespace detail { 14 | 15 | 16 | unique_handle::unique_handle() 17 | : m_id{0U} 18 | { 19 | std::lock_guard const lock(mutex_for_handles); 20 | auto const it = handles.crbegin(); 21 | m_id = it == handles.crend() ? 0U : *it + 1U; 22 | INVARIANT(handles.count(m_id) == 0ULL); 23 | handles.insert(m_id); 24 | } 25 | 26 | unique_handle::~unique_handle() 27 | { 28 | std::lock_guard const lock(mutex_for_handles); 29 | handles.erase(m_id); 30 | } 31 | 32 | 33 | }} 34 | -------------------------------------------------------------------------------- /bitvectors/src/expression_algo.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | namespace bv { 4 | 5 | 6 | bool find_symbols(expression const e, std::function const selector, 7 | std::unordered_set& output) 8 | { 9 | if (selector(get_symbol(e))) 10 | output.insert(get_symbol(e)); 11 | for (uint64_t i = 0ULL; i < num_parameters(e); ++i) 12 | find_symbols(argument(e,i),selector,output); 13 | return !output.empty(); 14 | } 15 | 16 | bool find_unintepreted_symbols(expression const e, std::unordered_set& output) 17 | { 18 | return find_symbols(e,std::not1(std::function(&symbol_is_interpreted)),output); 19 | } 20 | 21 | expression to_conjunction(std::vector const& conjuncts) 22 | { 23 | if (conjuncts.empty()) 24 | return tt(); 25 | expression result = conjuncts.front(); 26 | for (auto it = std::next(conjuncts.cbegin()); it != conjuncts.cend(); ++it) 27 | result = result && *it; 28 | return result; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /bitvectors/tests/communication_with_solver/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME communication_with_solver) 2 | 3 | add_executable(communication_with_solver 4 | main.cpp 5 | ) 6 | 7 | target_link_libraries(communication_with_solver 8 | bitvectors 9 | ${Z3_LIBRARIES_TO_LINK_WITH} 10 | ${CMAKE_THREAD_LIBS_INIT} 11 | ) 12 | 13 | install(TARGETS communication_with_solver 14 | CONFIGURATIONS Debug 15 | DESTINATION "${CMAKE_SYSTEM_NAME}_Debug/test/${PROJECT_NAME}" 16 | ) 17 | install(TARGETS communication_with_solver 18 | CONFIGURATIONS Release 19 | DESTINATION "${CMAKE_SYSTEM_NAME}_Release/test/${PROJECT_NAME}" 20 | ) 21 | -------------------------------------------------------------------------------- /bitvectors/tests/expressions_io/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME expressions_io) 2 | 3 | add_executable(expressions_io 4 | main.cpp 5 | ) 6 | 7 | target_link_libraries(expressions_io 8 | bitvectors 9 | ) 10 | 11 | install(TARGETS expressions_io 12 | CONFIGURATIONS Debug 13 | DESTINATION "${CMAKE_SYSTEM_NAME}_Debug/test/${PROJECT_NAME}" 14 | ) 15 | install(TARGETS expressions_io 16 | CONFIGURATIONS Release 17 | DESTINATION "${CMAKE_SYSTEM_NAME}_Release/test/${PROJECT_NAME}" 18 | ) 19 | -------------------------------------------------------------------------------- /bitvectors/tests/management_of_expressions/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME management_of_expressions) 2 | 3 | add_executable(management_of_expressions 4 | main.cpp 5 | ) 6 | 7 | target_link_libraries(management_of_expressions 8 | bitvectors 9 | ) 10 | 11 | install(TARGETS management_of_expressions 12 | CONFIGURATIONS Debug 13 | DESTINATION "${CMAKE_SYSTEM_NAME}_Debug/test/${PROJECT_NAME}" 14 | ) 15 | install(TARGETS management_of_expressions 16 | CONFIGURATIONS Release 17 | DESTINATION "${CMAKE_SYSTEM_NAME}_Release/test/${PROJECT_NAME}" 18 | ) 19 | -------------------------------------------------------------------------------- /bitvectors/tests/management_of_symbols/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME management_of_symbols) 2 | 3 | add_executable(management_of_symbols 4 | main.cpp 5 | ) 6 | 7 | target_link_libraries(management_of_symbols 8 | bitvectors 9 | ) 10 | 11 | install(TARGETS management_of_symbols 12 | CONFIGURATIONS Debug 13 | DESTINATION "${CMAKE_SYSTEM_NAME}_Debug/test/${PROJECT_NAME}" 14 | ) 15 | install(TARGETS management_of_symbols 16 | CONFIGURATIONS Release 17 | DESTINATION "${CMAKE_SYSTEM_NAME}_Release/test/${PROJECT_NAME}" 18 | ) 19 | -------------------------------------------------------------------------------- /bitvectors/tests/management_of_symbols/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | 8 | static void test_symbol_construction() 9 | { 10 | std::cout << "Starting: test_symbol_construction()\n"; 11 | 12 | bv::symbol const num10 = bv::make_symbol_of_interpreted_constant(int16_t(10)); 13 | TEST_SUCCESS(num10.operator bool()); 14 | TEST_SUCCESS(bv::symbol_name(num10) == "0x000a"); 15 | TEST_SUCCESS(bv::symbol_num_bits_of_return_value(num10) == 16ULL); 16 | TEST_SUCCESS(bv::symbol_num_parameters(num10) == 0ULL); 17 | TEST_SUCCESS(bv::symbol_is_interpreted(num10)); 18 | TEST_SUCCESS(bv::symbol_is_interpreted_constant(num10)); 19 | 20 | bv::symbol const F = bv::make_symbol_of_unintepreted_function("F",8ULL,{}); 21 | TEST_SUCCESS(F.operator bool()); 22 | TEST_SUCCESS(bv::symbol_name(F) == "F"); 23 | TEST_SUCCESS(bv::symbol_num_bits_of_return_value(F) == 8ULL); 24 | TEST_SUCCESS(bv::symbol_num_parameters(F) == 0ULL); 25 | TEST_SUCCESS(!bv::symbol_is_interpreted(F)); 26 | TEST_SUCCESS(!bv::symbol_is_interpreted_constant(F)); 27 | 28 | bv::symbol const F2 = bv::make_symbol_of_unintepreted_function("F",8ULL,{}); 29 | TEST_SUCCESS(F2.operator bool()); 30 | TEST_SUCCESS(bv::symbol_name(F2) == "F"); 31 | TEST_SUCCESS(bv::symbol_num_bits_of_return_value(F2) == 8ULL); 32 | TEST_SUCCESS(bv::symbol_num_parameters(F2) == 0ULL); 33 | TEST_SUCCESS(!bv::symbol_is_interpreted(F2)); 34 | TEST_SUCCESS(!bv::symbol_is_interpreted_constant(F2)); 35 | 36 | TEST_FAILURE(num10 == F); 37 | TEST_SUCCESS(F == F2); 38 | 39 | std::cout << "SUCCESS\n"; 40 | } 41 | 42 | static void save_crash_report(std::string const& crash_message) 43 | { 44 | std::cout << "ERROR: " << crash_message << "\n"; 45 | std::ofstream ofile("management_of_symbols_CRASH.txt", std::ios_base::app ); 46 | ofile << crash_message << "\n"; 47 | } 48 | 49 | int main(int argc, char* argv[]) 50 | { 51 | (void)argc; 52 | (void)argv; 53 | try 54 | { 55 | test_symbol_construction(); 56 | } 57 | catch(std::exception const& e) 58 | { 59 | try { save_crash_report(e.what()); } catch (...) {} 60 | return -1; 61 | } 62 | catch(...) 63 | { 64 | try { save_crash_report("Unknown exception was thrown."); } catch (...) {} 65 | return -2; 66 | } 67 | return 0; 68 | } 69 | -------------------------------------------------------------------------------- /data/benchmarks/SOURCES.txt: -------------------------------------------------------------------------------- 1 | ./src/loadlibs 2 | - source code of all binaries: ./bin/loadlibs_* 3 | - origin: Marek 4 | - cathegory: Regular SW. 5 | - chalenges: Loading. 6 | 7 | ./bin/crackme_* 8 | - origin: Emmanuel 9 | - cathegory: Self-rewriting. 10 | - chalenges: Loading, CFG-recovery. 11 | 12 | ./bin/tiny* 13 | - origin: Emmanuel 14 | - cathegory: Regular SW. 15 | - chalenges: Loading. 16 | 17 | ./bin/malwaredb.malekal.com/linux/* 18 | - origin: malwaredb.malekal.com 19 | - cathegory: Malware 20 | - chalenges: Loading, CFG-recovery. 21 | 22 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | project(loadlibs) 2 | 3 | cmake_minimum_required(VERSION 2.8 FATAL_ERROR) 4 | 5 | if(NOT CMAKE_BUILD_TYPE) 6 | message("Build type not set => setting 'Release' as default.") 7 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Release" FORCE) 8 | endif() 9 | 10 | # Select build type (Release, Debug, ReleaseWithDebugInfo) 11 | message("Build type = " ${CMAKE_BUILD_TYPE}) 12 | if(CMAKE_BUILD_TYPE MATCHES "Debug") 13 | add_definitions(-DDEBUG) 14 | elseif(CMAKE_BUILD_TYPE MATCHES "Release") 15 | add_definitions(-DRELEASE) 16 | elseif(CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") 17 | add_definitions(-DRELEASE) 18 | else() 19 | message(FATAL_ERROR "Unknown build type. Use either Debug, Release, or RelWithDebInfo. E.g.: -DCMAKE_BUILD_TYPE=Release") 20 | endif() 21 | 22 | # OS specific settings 23 | if (APPLE) 24 | set(CMAKE_MACOSX_RPATH ON) 25 | message("Operating System = Darwin") 26 | elseif(UNIX) 27 | message("Operating System = Unix") 28 | elseif(WIN32) 29 | message("Operating System = MS-Windows") 30 | else() 31 | message(FATAL_ERROR "Unsupported Operating System ! Aborting... 32 | (supported OS: MacOS X, Linux, *BSD, MS-Windows)") 33 | endif() 34 | 35 | # Compiler specific settings 36 | set(CMAKE_CXX_STANDARD 11) 37 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 38 | 39 | 40 | if(CMAKE_COMPILER_IS_GNUCXX OR ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")) 41 | add_definitions("-std=c++11 -Wall -Wextra") 42 | if ((CMAKE_BUILD_TYPE STREQUAL Debug) OR 43 | (CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)) 44 | add_definitions("-ggdb3") 45 | endif() 46 | if(NOT DEFINED LOADLIBS_USE_32BIT_BUILD) 47 | set(LOADLIBS_USE_32BIT_BUILD "No" CACHE STRING "Build 32 bit application? (Yes/No)" FORCE) 48 | endif() 49 | message("Build 32bit application: " ${LOADLIBS_USE_32BIT_BUILD}) 50 | string( TOLOWER "${LOADLIBS_USE_32BIT_BUILD}" LOADER_TEMPORARY_VARIABLE) 51 | if(LOADER_TEMPORARY_VARIABLE STREQUAL "yes") 52 | set(CMAKE_CXX_FLAGS -m32) 53 | endif() 54 | message("Compiler = ${CMAKE_CXX_COMPILER}") 55 | elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") 56 | #add_definitions("/Wall") 57 | message("Compiler = MSVC") 58 | else() 59 | message(FATAL_ERROR "Unknown (unsupported) compiler detected. Supported is only GCC (on Linux) and MSVC (on Windows).") 60 | endif() 61 | 62 | if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT) 63 | set(CMAKE_INSTALL_PREFIX "${PROJECT_SOURCE_DIR}/bin" CACHE STRING "Install path" FORCE) 64 | endif() 65 | set(CMAKE_INSTALL_RPATH "./") 66 | message("Sources directory = ${PROJECT_SOURCE_DIR}/src") 67 | message("Install directory = ${CMAKE_INSTALL_PREFIX}") 68 | 69 | set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_CURRENT_SOURCE_DIR}/src") 70 | 71 | # Add project specific code 72 | add_subdirectory(./src) 73 | 74 | message("Generating build files ...") 75 | 76 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # Here follow all libraries of loadlibs 2 | include_directories( 3 | "${PROJECT_SOURCE_DIR}/src" 4 | "${PROJECT_SOURCE_DIR}/src/static_lib_one/include" 5 | "${PROJECT_SOURCE_DIR}/src/dynamic_lib_one/include" 6 | "${PROJECT_SOURCE_DIR}/src/dynamic_lib_two/include" 7 | "${PROJECT_SOURCE_DIR}/src/dynamic_lib_three/include" 8 | "${PROJECT_SOURCE_DIR}/src/dynamic_lib_four/include" 9 | "${PROJECT_SOURCE_DIR}/src/dynamic_lib_five/include" 10 | "${PROJECT_SOURCE_DIR}/src/dynamic_lib_six/include" 11 | "${PROJECT_SOURCE_DIR}/src/dynamic_lib_seven/include" 12 | ) 13 | message("Including the following loadlibs modules to the build:") 14 | 15 | add_subdirectory(./loadlibs) 16 | message("-- loadlibs") 17 | 18 | add_subdirectory(./static_lib_one) 19 | message("-- static_lib_one") 20 | 21 | add_subdirectory(./dynamic_lib_one) 22 | message("-- dynamic_lib_one") 23 | add_subdirectory(./dynamic_lib_two) 24 | message("-- dynamic_lib_two") 25 | add_subdirectory(./dynamic_lib_three) 26 | message("-- dynamic_lib_three") 27 | add_subdirectory(./dynamic_lib_four) 28 | message("-- dynamic_lib_four") 29 | add_subdirectory(./dynamic_lib_five) 30 | message("-- dynamic_lib_five") 31 | add_subdirectory(./dynamic_lib_six) 32 | message("-- dynamic_lib_six") 33 | add_subdirectory(./dynamic_lib_seven) 34 | message("-- dynamic_lib_seven") 35 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_five/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs_dynamic_lib_five) 2 | 3 | add_library(${THIS_TARGET_NAME} SHARED 4 | ./include/dynamic_lib_five/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 9 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 10 | ) 11 | 12 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 13 | 14 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_five/include/dynamic_lib_five/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_LIB_FIVE_FUNCTIONS_HPP_INCLUDED 2 | # define DYNAMIC_LIB_FIVE_FUNCTIONS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace dynamic_lib_five { 7 | 8 | 9 | DIMPORT extern int glob_five_var; 10 | 11 | DIMPORT extern int version(); 12 | DIMPORT extern double value(); 13 | DIMPORT extern int gvar(); 14 | 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_five/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | DIMPORT extern int glob_exe_var; 4 | 5 | namespace dynamic_lib_five { 6 | 7 | 8 | DEXPORT int glob_five_var = 115; 9 | 10 | 11 | DEXPORT int version() 12 | { 13 | return 5; 14 | } 15 | 16 | 17 | DEXPORT double value() 18 | { 19 | return 5.5; 20 | } 21 | 22 | 23 | DEXPORT int gvar() 24 | { 25 | return DLL_USE_EXE_VAR(glob_exe_var +) glob_five_var; 26 | } 27 | 28 | 29 | } 30 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_four/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs_dynamic_lib_four) 2 | 3 | add_library(${THIS_TARGET_NAME} SHARED 4 | ./include/dynamic_lib_four/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | target_link_libraries(${THIS_TARGET_NAME} 9 | loadlibs_dynamic_lib_five 10 | loadlibs_dynamic_lib_six 11 | ) 12 | 13 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 14 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 15 | ) 16 | 17 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 18 | 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_four/include/dynamic_lib_four/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_LIB_FOUR_FUNCTIONS_HPP_INCLUDED 2 | # define DYNAMIC_LIB_FOUR_FUNCTIONS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace dynamic_lib_four { 7 | 8 | 9 | DIMPORT extern int glob_four_var; 10 | 11 | DIMPORT extern int version(); 12 | DIMPORT extern double value(); 13 | DIMPORT extern int gvar(); 14 | 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_four/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | DIMPORT extern int glob_exe_var; 7 | 8 | namespace dynamic_lib_four { 9 | 10 | 11 | DEXPORT int glob_four_var = 114; 12 | 13 | 14 | DEXPORT int version() 15 | { 16 | std::cout << "(version = 4)\n"; 17 | return 4 + 100 * dynamic_lib_five::version() + 1000 * dynamic_lib_six::version(); 18 | } 19 | 20 | DEXPORT double value() 21 | { 22 | std::cout << "(value = 4.4)\n"; 23 | return 4.4 + 100.0 * dynamic_lib_five::value() + 1000.0 * dynamic_lib_six::value(); 24 | } 25 | 26 | DEXPORT int gvar() 27 | { 28 | return DLL_USE_EXE_VAR(glob_exe_var +) glob_four_var + dynamic_lib_five::glob_five_var + dynamic_lib_six::glob_six_var; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_one/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs_dynamic_lib_one) 2 | 3 | add_library(${THIS_TARGET_NAME} SHARED 4 | ./include/dynamic_lib_one/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | target_link_libraries(${THIS_TARGET_NAME} 9 | loadlibs_dynamic_lib_two 10 | loadlibs_dynamic_lib_six 11 | ) 12 | 13 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 14 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 15 | ) 16 | 17 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 18 | 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_one/include/dynamic_lib_one/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_LIB_ONE_FUNCTIONS_HPP_INCLUDED 2 | # define DYNAMIC_LIB_ONE_FUNCTIONS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace dynamic_lib_one { 7 | 8 | 9 | DIMPORT extern int glob_one_var; 10 | 11 | DIMPORT extern int version(); 12 | DIMPORT extern double value(); 13 | DIMPORT extern int gvar(); 14 | 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_one/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | DIMPORT extern int glob_exe_var; 7 | 8 | namespace dynamic_lib_one { 9 | 10 | 11 | DEXPORT int glob_one_var = 111; 12 | 13 | 14 | DEXPORT int version() 15 | { 16 | std::cout << "(version = 1)\n"; 17 | return 1 + 100 * dynamic_lib_two::version() + 1000 * dynamic_lib_six::version(); 18 | } 19 | 20 | DEXPORT double value() 21 | { 22 | std::cout << "(value = 1.1)\n"; 23 | return 1.1 + 100.0 * dynamic_lib_two::value() + 1000.0 * dynamic_lib_six::value(); 24 | } 25 | 26 | DEXPORT int gvar() 27 | { 28 | return DLL_USE_EXE_VAR(glob_exe_var +) glob_one_var + dynamic_lib_two::glob_two_var + dynamic_lib_six::glob_six_var; 29 | } 30 | 31 | 32 | } 33 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_seven/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs_dynamic_lib_seven) 2 | 3 | add_library(${THIS_TARGET_NAME} SHARED 4 | ./include/dynamic_lib_seven/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 9 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 10 | ) 11 | 12 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 13 | 14 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_seven/include/dynamic_lib_seven/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_LIB_SEVEN_FUNCTIONS_HPP_INCLUDED 2 | # define DYNAMIC_LIB_SEVEN_FUNCTIONS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace dynamic_lib_seven { 7 | 8 | 9 | DIMPORT extern int glob_seven_var; 10 | 11 | DIMPORT extern int version(); 12 | DIMPORT extern double value(); 13 | DIMPORT extern int gvar(); 14 | 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_seven/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | DIMPORT extern int glob_exe_var; 5 | 6 | namespace dynamic_lib_seven { 7 | 8 | 9 | DEXPORT int glob_seven_var = 117; 10 | 11 | 12 | DEXPORT int version() 13 | { 14 | std::cout << "(version = 7)\n"; 15 | return 7; 16 | } 17 | 18 | 19 | DEXPORT double value() 20 | { 21 | std::cout << "(value = 7.7)\n"; 22 | return 7.7; 23 | } 24 | 25 | DEXPORT int gvar() 26 | { 27 | return DLL_USE_EXE_VAR(glob_exe_var +) glob_seven_var; 28 | } 29 | 30 | 31 | } 32 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_six/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs_dynamic_lib_six) 2 | 3 | add_library(${THIS_TARGET_NAME} SHARED 4 | ./include/dynamic_lib_six/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 9 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 10 | ) 11 | 12 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 13 | 14 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_six/include/dynamic_lib_six/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_LIB_SIX_FUNCTIONS_HPP_INCLUDED 2 | # define DYNAMIC_LIB_SIX_FUNCTIONS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace dynamic_lib_six { 7 | 8 | 9 | DIMPORT extern int glob_six_var; 10 | 11 | DIMPORT extern int version(); 12 | DIMPORT extern double value(); 13 | DIMPORT extern int gvar(); 14 | 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_six/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | DIMPORT extern int glob_exe_var; 4 | 5 | namespace dynamic_lib_six { 6 | 7 | 8 | DEXPORT int glob_six_var = 116; 9 | 10 | 11 | DEXPORT int version() 12 | { 13 | return 6; 14 | } 15 | 16 | DEXPORT double value() 17 | { 18 | return 6.6; 19 | } 20 | 21 | DEXPORT int gvar() 22 | { 23 | return DLL_USE_EXE_VAR(glob_exe_var +) glob_six_var; 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_three/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs_dynamic_lib_three) 2 | 3 | add_library(${THIS_TARGET_NAME} SHARED 4 | ./include/dynamic_lib_three/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | target_link_libraries(${THIS_TARGET_NAME} 9 | loadlibs_dynamic_lib_seven 10 | ) 11 | 12 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 13 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 14 | ) 15 | 16 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 17 | 18 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_three/include/dynamic_lib_three/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_LIB_THREE_FUNCTIONS_HPP_INCLUDED 2 | # define DYNAMIC_LIB_THREE_FUNCTIONS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace dynamic_lib_three { 7 | 8 | 9 | DIMPORT extern int glob_three_var; 10 | 11 | DIMPORT extern int version(); 12 | DIMPORT extern double value(); 13 | DIMPORT extern int gvar(); 14 | 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_three/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | DIMPORT extern int glob_exe_var; 5 | 6 | namespace dynamic_lib_three { 7 | 8 | 9 | DEXPORT int glob_three_var = 113; 10 | 11 | 12 | DEXPORT int version() 13 | { 14 | return 3 + 100 * dynamic_lib_seven::version(); 15 | } 16 | 17 | DEXPORT double value() 18 | { 19 | return 3.3 + 100.0 * dynamic_lib_seven::value(); 20 | } 21 | 22 | DEXPORT int gvar() 23 | { 24 | return DLL_USE_EXE_VAR(glob_exe_var +) glob_three_var + dynamic_lib_seven::glob_seven_var; 25 | } 26 | 27 | 28 | } 29 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_two/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs_dynamic_lib_two) 2 | 3 | add_library(${THIS_TARGET_NAME} SHARED 4 | ./include/dynamic_lib_two/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | target_link_libraries(${THIS_TARGET_NAME} 9 | loadlibs_dynamic_lib_four 10 | loadlibs_dynamic_lib_five 11 | loadlibs_dynamic_lib_seven 12 | ) 13 | 14 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 15 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 16 | ) 17 | 18 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 19 | 20 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_two/include/dynamic_lib_two/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DYNAMIC_LIB_TWO_FUNCTIONS_HPP_INCLUDED 2 | # define DYNAMIC_LIB_TWO_FUNCTIONS_HPP_INCLUDED 3 | 4 | # include 5 | 6 | namespace dynamic_lib_two { 7 | 8 | 9 | DIMPORT extern int glob_two_var; 10 | 11 | DIMPORT extern int version(); 12 | DIMPORT extern double value(); 13 | DIMPORT extern int gvar(); 14 | 15 | 16 | } 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/dynamic_lib_two/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | DIMPORT extern int glob_exe_var; 7 | 8 | namespace dynamic_lib_two { 9 | 10 | 11 | DEXPORT int glob_two_var = 112; 12 | 13 | 14 | DEXPORT int version() 15 | { 16 | return 2 + 100 * dynamic_lib_four::version() + 1000 * dynamic_lib_five::version() + 10000 * dynamic_lib_seven::version(); 17 | } 18 | 19 | DEXPORT double value() 20 | { 21 | return 2.2 + 100.0 * dynamic_lib_four::value() + 1000.0 * dynamic_lib_five::value() + 10000.0 * dynamic_lib_seven::value(); 22 | } 23 | 24 | DEXPORT int gvar() 25 | { 26 | return DLL_USE_EXE_VAR(glob_exe_var +) glob_two_var + dynamic_lib_four::glob_four_var + dynamic_lib_five::glob_five_var + dynamic_lib_seven::glob_seven_var; 27 | } 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/import_export.hpp: -------------------------------------------------------------------------------- 1 | #ifndef IMPORT_EXPORT_HPP_INCLUDED 2 | # define IMPORT_EXPORT_HPP_INCLUDED 3 | 4 | # if defined(_MSC_VER) // MSVC 5 | # define DIMPORT __declspec(dllimport) 6 | # define DEXPORT __declspec(dllexport) 7 | # define DLL_USE_EXE_VAR(expr) 8 | # elif defined(__APPLE__) // LLVM 9 | # define DIMPORT 10 | # define DEXPORT 11 | # define DLL_USE_EXE_VAR(expr) 12 | # elif defined(__GNUC__) // gcc 13 | # define DIMPORT 14 | # define DEXPORT 15 | # define DLL_USE_EXE_VAR(expr) expr 16 | # else // unknown 17 | # error "Unknown compiler" 18 | # endif 19 | 20 | #endif 21 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/loadlibs/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME loadlibs) 2 | 3 | add_executable(${THIS_TARGET_NAME} 4 | main.cpp 5 | ) 6 | 7 | target_link_libraries(${THIS_TARGET_NAME} 8 | static_lib_one 9 | loadlibs_dynamic_lib_one 10 | loadlibs_dynamic_lib_two 11 | loadlibs_dynamic_lib_three 12 | ) 13 | 14 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 15 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 16 | ) 17 | 18 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 19 | 20 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/loadlibs/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | DEXPORT int glob_exe_var = 110; 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | std::cout << "static_lib_one::version() = " << static_lib_one::version() << "\n"; 16 | std::cout << "static_lib_one::value() = " << static_lib_one::value() << "\n"; 17 | 18 | std::cout << "dynamic_lib_one::version() = " << dynamic_lib_one::version() << "\n"; 19 | std::cout << "dynamic_lib_one::value() = " << dynamic_lib_one::value() << "\n"; 20 | 21 | std::cout << "dynamic_lib_two::version() = " << dynamic_lib_two::version() << "\n"; 22 | std::cout << "dynamic_lib_two::value() = " << dynamic_lib_two::value() << "\n"; 23 | 24 | std::cout << "dynamic_lib_three::version() = " << dynamic_lib_three::version() << "\n"; 25 | std::cout << "dynamic_lib_three::value() = " << dynamic_lib_three::value() << "\n"; 26 | 27 | std::cout << "static_lib_one::gvar() = " << static_lib_one::gvar() << "\n"; 28 | std::cout << "dynamic_lib_one::gvar() = " << dynamic_lib_one::gvar() << "\n"; 29 | std::cout << "dynamic_lib_two::gvar() = " << dynamic_lib_two::gvar() << "\n"; 30 | std::cout << "dynamic_lib_three::gvar() = " << dynamic_lib_three::gvar() << "\n"; 31 | 32 | std::cout << "static_lib_one::glob_static_one_var = " << static_lib_one::glob_static_one_var << "\n"; 33 | std::cout << "dynamic_lib_one::glob_one_var = " << dynamic_lib_one::glob_one_var << "\n"; 34 | std::cout << "dynamic_lib_two::glob_two_var = " << dynamic_lib_two::glob_two_var << "\n"; 35 | std::cout << "dynamic_lib_three::glob_three_var = " << dynamic_lib_three::glob_three_var << "\n"; 36 | 37 | int i; 38 | std::cin >> i; 39 | 40 | return 0; 41 | } 42 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/static_lib_one/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(THIS_TARGET_NAME static_lib_one) 2 | 3 | add_library(${THIS_TARGET_NAME} 4 | ./include/static_lib_one/functions.hpp 5 | ./src/functions.cpp 6 | ) 7 | 8 | set_target_properties(${THIS_TARGET_NAME} PROPERTIES 9 | OUTPUT_NAME "${THIS_TARGET_NAME}_${CMAKE_SYSTEM_NAME}_${CMAKE_BUILD_TYPE}" 10 | ) 11 | 12 | install(TARGETS ${THIS_TARGET_NAME} DESTINATION "./") 13 | 14 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/static_lib_one/include/static_lib_one/functions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef STATIC_LIB_ONE_FUNCTIONS_HPP_INCLUDED 2 | # define STATIC_LIB_ONE_FUNCTIONS_HPP_INCLUDED 3 | 4 | namespace static_lib_one { 5 | 6 | 7 | extern int glob_static_one_var; 8 | 9 | extern int version(); 10 | extern double value(); 11 | extern int gvar(); 12 | 13 | 14 | } 15 | 16 | #endif 17 | -------------------------------------------------------------------------------- /data/benchmarks/src/loadlibs/src/static_lib_one/src/functions.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int glob_exe_var; 4 | 5 | namespace static_lib_one { 6 | 7 | 8 | int glob_static_one_var = 333; 9 | 10 | 11 | int version() 12 | { 13 | return 6789; 14 | } 15 | 16 | double value() 17 | { 18 | return 2.8; 19 | } 20 | 21 | int gvar() 22 | { 23 | return glob_exe_var + glob_static_one_var; 24 | } 25 | 26 | 27 | } 28 | -------------------------------------------------------------------------------- /data/tests/asm/build.py: -------------------------------------------------------------------------------- 1 | import argparse 2 | import os 3 | import time 4 | 5 | def parse_cmd_line(): 6 | parser = argparse.ArgumentParser() 7 | parser.add_argument("-I","--input-file", type=str, 8 | help="A pathname of a source .ASM file to be build.") 9 | parser.add_argument("-O", "--output-file", type=str, 10 | help="A pathname of a resulting executable file. If not specified, the executable will be " 11 | "stored into the directory '../bin' relative to the directory of the source file.") 12 | args = parser.parse_args() 13 | return args 14 | 15 | 16 | def scriptMain(): 17 | args = parse_cmd_line() 18 | 19 | if args.input_file is None: 20 | print("ERROR: no source .ASM file was specified.") 21 | return 22 | if not os.path.exists(args.input_file): 23 | print("ERROR: the source file '" + args.input_file + "' does not exists.") 24 | return 25 | if not (os.path.isfile(args.input_file) and os.access(args.input_file,os.R_OK)): 26 | print("ERROR: the source file '" + args.input_file + "' is not accessible.") 27 | return 28 | 29 | source_pathname = os.path.abspath(args.input_file) 30 | source_dir = os.path.dirname(source_pathname) 31 | 32 | if args.output_file is None: 33 | output_dir = os.path.normpath(os.path.join(source_dir,"../bin")) 34 | output_file_name = os.path.splitext(os.path.basename(source_pathname))[0] 35 | output_file_ext = "" 36 | else: 37 | output_dir = os.path.dirname(args.output_file) 38 | output_file_name = os.path.splitext(os.path.basename(args.output_file))[0] 39 | output_file_ext = os.path.splitext(os.path.basename(args.output_file))[1] 40 | 41 | if not os.path.exists(output_dir): 42 | os.makedirs(output_dir) 43 | 44 | out_pathname = os.path.join(output_dir,output_file_name + output_file_ext) 45 | 46 | obj_dir = output_dir 47 | obj_name = output_file_name 48 | obj_ext = ".o" 49 | 50 | obj_pathname = os.path.join(obj_dir,obj_name + obj_ext) 51 | 52 | command = "nasm -f elf64 -O0 \"" + source_pathname + "\" -o \"" + obj_pathname + "\"" 53 | os.system(command) 54 | 55 | start_time = time.time() 56 | while not os.path.exists(obj_pathname) and time.time() - start_time < 2.0: 57 | pass 58 | 59 | if os.path.exists(obj_pathname): 60 | command = "ld \"" + obj_pathname + "\" -o \"" + out_pathname + "\"" 61 | os.system(command) 62 | if os.path.exists(out_pathname): 63 | os.remove(obj_pathname) 64 | 65 | 66 | if __name__ == "__main__": 67 | scriptMain() 68 | -------------------------------------------------------------------------------- /data/tests/asm/src/inc_constant_in_mov.asm: -------------------------------------------------------------------------------- 1 | section .text write 2 | global _start 3 | _start: 4 | mov rax,0x0000000000000000 5 | inc rax 6 | modify: 7 | mov rbx,modify+2 8 | mov [cs:rbx],rax 9 | jmp _start 10 | ret 11 | 12 | -------------------------------------------------------------------------------- /data/tests/asm/src/inc_constant_in_mov_2.asm: -------------------------------------------------------------------------------- 1 | section .text write 2 | global _start 3 | _start: 4 | mov rcx,1000 5 | loop: 6 | mov rax,0x0000000000000000 7 | inc rax 8 | mov [loop+2],rax 9 | cmp rax,rcx 10 | jnz loop 11 | mov rax,0 12 | add rcx,100 13 | jmp loop 14 | 15 | -------------------------------------------------------------------------------- /data/tests/asm/src/move_block_of_code.asm: -------------------------------------------------------------------------------- 1 | section .text write 2 | global _start 3 | block: ; 400080 4 | inc rbx 5 | mov rax,loop 6 | jmp rax 7 | _start: ; 40008f 8 | mov rcx,0 9 | mov rbx,0 10 | loop: ; 400099 11 | inc rcx 12 | mov rdx,0 13 | mov rax,rcx 14 | mov rdi,10 15 | div rdi 16 | mov rcx,rdx 17 | mov rdi,array 18 | add rdi,rcx 19 | mov rdx,0 20 | copy: ; 4000c1 21 | mov al,[rdx+block] 22 | mov [rdi+rdx],al 23 | inc rdx 24 | cmp rdx,_start-block 25 | jnz copy 26 | jmp rdi 27 | array: ; 4000d5 28 | nop 29 | nop 30 | nop 31 | nop 32 | nop 33 | nop 34 | nop 35 | ;... 36 | 37 | -------------------------------------------------------------------------------- /data/tests/asm/src/permute_instructions.asm: -------------------------------------------------------------------------------- 1 | section .text write 2 | global _start 3 | _start: ; 400080 4 | mov rax,1 5 | mov rcx,2 6 | loop: ; 40008a 7 | add rax,rcx ; 48 01 c8 40008a 8 | mul rcx ; 48 f7 e1 40008d 9 | sub rax,rcx ; 48 29 c8 400090 10 | 11 | mov bl,[loop+1] ; 400093 12 | mov bh,[loop+4] 13 | mov [loop+4],bl 14 | mov bl,bh 15 | mov bh,[loop+7] 16 | mov [loop+7],bl 17 | mov [loop+1],bh 18 | 19 | mov bl,[loop+2] 20 | mov bh,[loop+5] 21 | mov [loop+5],bl 22 | mov bl,bh 23 | mov bh,[loop+8] 24 | mov [loop+8],bl 25 | mov [loop+2],bh 26 | 27 | jmp loop 28 | 29 | -------------------------------------------------------------------------------- /data/tests/asm/src/swap_tiny.asm: -------------------------------------------------------------------------------- 1 | section .text 2 | global _start 3 | 4 | _start: 5 | mov rax,arg0 6 | mov rbx,arg1 7 | mov rcx,4 8 | jmp swap 9 | 10 | exit: 11 | mov eax,1 ;system call number (sys_exit) 12 | int 0x80 ;call kernel 13 | 14 | swap: 15 | mov dl, [rax] 16 | mov dh,[rbx] 17 | mov [rax],dh 18 | mov [rbx],dl 19 | inc rax 20 | inc rbx 21 | dec rcx 22 | jz exit 23 | jmp swap 24 | 25 | 26 | section .data 27 | 28 | arg0 db 0x0a, 0x0b, 0x0c, 0x0d 29 | arg1 db 0x01, 0x02, 0x03, 0x04 30 | 31 | -------------------------------------------------------------------------------- /data/tests/asm/src/where_was_i_A.asm: -------------------------------------------------------------------------------- 1 | ; Questions: What is the value of PC after execution of 57 instructions? 2 | ; How Microcode would look like after those 57 instructions? 3 | ; How we identify PC in the produced Microcode (consider also a 4 | ; case, when the number 10000000 inside the cmp instruction bellow 5 | ; is replaced by 10000001)? 6 | 7 | section .text write 8 | global _start 9 | 10 | _start: ; 400080 11 | mov rcx,0 12 | 13 | loop: ; 400085 14 | nop 15 | nop 16 | add rcx,2 17 | cmp rcx,10000000 ; What happens, if we put here 10000001 18 | jnz loop 19 | mov rax,loop 20 | mov bx,0xffe0 21 | mov [rax],bx 22 | mov rax,continue 23 | jmp loop 24 | 25 | continue: ; 4000b1 26 | ; ... ; Here can be a LOT of code!! 27 | mov eax,1 ; System function: sys_exit 28 | int 0x80 ; Call the kernel 29 | 30 | -------------------------------------------------------------------------------- /data/tests/c/src/DOIF.c: -------------------------------------------------------------------------------- 1 | // Returns 1 if the passed 'T'-terminated string contains 'U' 10 times and 'V' 2 | // 15 times. Otherwise it returns 0. 3 | #include 4 | 5 | int DOIF(char const* const P) { 6 | int U = 0, V = 0, ic; 7 | for (ic = 0; P[ic] != 'T'; ++ic) { 8 | if (P[ic] == 'U') ++U; 9 | if (P[ic] == 'V') ++V; 10 | } 11 | return U == 10 && V == 15; 12 | } 13 | 14 | // Test driver 15 | 16 | int main(int argc, char* argv[]) 17 | { 18 | if (argc != 2) 19 | { 20 | puts("Wrong count of paramenters.\n"); 21 | return -1; 22 | } 23 | 24 | if (DOIF(argv[1])) 25 | { 26 | puts("The condition was satisfied.\n"); 27 | return 1; 28 | } 29 | puts("The condition was NOT satisfied.\n"); 30 | return 0; 31 | } 32 | 33 | -------------------------------------------------------------------------------- /data/tests/c/src/DOIFex.c: -------------------------------------------------------------------------------- 1 | // Returns 1 if difference between counts of ('U' and 'u') and ('V' and 'v') are 2 | // 10 and 15 respectively. Otherwise it returns 0. 3 | int DOIFex(char const* const P) { 4 | int U = 0, V = 0, ic; 5 | for (ic = 0; P[ic] != 'T'; ++ic) { 6 | if (P[ic] == 'U') ++U; 7 | if (P[ic] == 'V') ++V; 8 | } 9 | for (ic = 0; P[ic] != 'T'; ++ic) { 10 | if (P[ic] == 'u') --U; 11 | if (P[ic] == 'v') --V; 12 | } 13 | return U == 10 && V == 15; 14 | } 15 | 16 | // Test driver 17 | 18 | int main(int argc, char* argv[]) 19 | { 20 | if (argc != 2) 21 | return -1; 22 | if (DOIFex(argv[1])) 23 | return 1; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /data/tests/c/src/EQCNT.c: -------------------------------------------------------------------------------- 1 | // Returns 1 if both passed zero terminated strings have the same length. 2 | // Otherwise it returns 0. 3 | int EQCNT(char const* const A, char const* const B) { 4 | int nA = 0, i,j; 5 | for (i = 0; A[i] != 0; ++i) 6 | for (j = 0; B[j] != 0; ++j) 7 | if (A[i] == B[j]) ++nA; 8 | return nA == 20; 9 | } 10 | 11 | // Test driver 12 | 13 | int main(int argc, char* argv[]) 14 | { 15 | if (argc != 2) 16 | return -1; 17 | if (EQCNT(argv[1],argv[2])) 18 | return 1; 19 | return 0; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /data/tests/c/src/EQCNTex.c: -------------------------------------------------------------------------------- 1 | // It always returns 0. 2 | int EQCNTex(char const* const A, char const* const B) { 3 | int nA = 0, nB = 0, i,j; 4 | for (i = 0; i < 3; ++i) 5 | for (j = 0; j < 3; ++j) 6 | if (A[i] == B[j]) ++nA; 7 | for (j = 0; j < 5; ++j) 8 | for (i = 0; i < 5; ++i) 9 | if (A[i] == B[j]) ++nB; 10 | return nA == 10 && nB == 13; 11 | } 12 | 13 | // Test driver 14 | 15 | int main(int argc, char* argv[]) 16 | { 17 | if (argc != 2) 18 | return -1; 19 | if (EQCNTex(argv[1],argv[2])) 20 | return 1; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /data/tests/c/src/HW.c: -------------------------------------------------------------------------------- 1 | extern void* malloc(unsigned int n); 2 | extern void free(void* p); 3 | 4 | typedef int elem_type; 5 | 6 | int containsAt(elem_type const* const A, int const k, elem_type const* const X) 7 | { 8 | int i = 0; 9 | for ( ; A[k+i] != 0 && X[i] != 0 && A[k+i] == X[i]; ++i) 10 | ; 11 | if (X[i] != 0) 12 | return 0; 13 | return 1; 14 | } 15 | 16 | int contains(elem_type const* const A, elem_type const* const X) 17 | { 18 | for (int i = 0; A[i] != 0; ++i) 19 | if (containsAt(A,i,X)) 20 | return 1; 21 | return 0; 22 | } 23 | 24 | #include "./bugst_utils.h" 25 | 26 | int main(void)//int argc, char* argv[]) 27 | { 28 | int N; 29 | BUGST_IGNORE_UNINITIALISED_INT(&N); 30 | if (N > 0) 31 | { 32 | elem_type const H[] = { 'H', 'e', 'l', 'l', 'o', 0 }; 33 | elem_type const W[] = { 'W', 'o', 'r', 'l', 'd', 0 }; 34 | elem_type* const A = (elem_type*)malloc(N * sizeof(elem_type)); 35 | A[N-1] = 0; 36 | BUGST_IGNORE_UNINITIALISED_INT_ARRAY(A,N-1); 37 | int const h = contains(A,H); 38 | int const w = contains(A,W); 39 | if (h == 1 && w == 1) 40 | { 41 | BUGST_REPORT_TARGET_LOCATION_REACHED(); 42 | BUGST_TERMINATE_WHOLE_PROGRAM_ANALYSIS(); 43 | } 44 | free(A); 45 | } 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /data/tests/c/src/HWM.c: -------------------------------------------------------------------------------- 1 | extern void* malloc(unsigned int n); 2 | extern void free(void* p); 3 | 4 | typedef int elem_type; 5 | 6 | int containsAt(elem_type const* const A, int const k, elem_type const* const X) 7 | { 8 | int i = 0; 9 | for ( ; A[k+i] != 0 && X[i] != 0 && A[k+i] == X[i]; ++i) 10 | ; 11 | if (X[i] != 0) 12 | return 0; 13 | return 1; 14 | } 15 | 16 | int contains(elem_type const* const A, elem_type const* const X) 17 | { 18 | for (int i = 0; A[i] != 0; ++i) 19 | if (containsAt(A,i,X)) 20 | return 1; 21 | return 0; 22 | } 23 | 24 | #include "./bugst_utils.h" 25 | 26 | int main(void)//int argc, char* argv[]) 27 | { 28 | int N; 29 | BUGST_IGNORE_UNINITIALISED_INT(&N); 30 | if (N > 0) 31 | { 32 | elem_type const H[] = { 'H', 'e', 'l', 'l', 'o', 0 }; 33 | elem_type const W[] = { 'W', 'o', 'r', 'l', 'd', 0 }; 34 | elem_type const T[] = { 'A', 't', 0 }; 35 | elem_type const M[] = { 'M', 'i', 'c', 'r', 'o', 's', 'o', 'f', 't', '!', 0 }; 36 | elem_type* const A = (elem_type*)malloc(N * sizeof(elem_type)); 37 | A[N-1] = 0; 38 | BUGST_IGNORE_UNINITIALISED_INT_ARRAY(A,N-1); 39 | int const h = contains(A,H); 40 | int const w = contains(A,W); 41 | int const t = contains(A,T); 42 | int const m = contains(A,M); 43 | if (h == 1 && w == 1 && t == 1 && m == 1) 44 | { 45 | BUGST_REPORT_TARGET_LOCATION_REACHED(); 46 | BUGST_TERMINATE_WHOLE_PROGRAM_ANALYSIS(); 47 | } 48 | free(A); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /data/tests/c/src/OneLoop.c: -------------------------------------------------------------------------------- 1 | // It always returns 0 2 | int OneLoop(int n) { 3 | int i = 0; 4 | while (i < n) i += 4; 5 | return i == 15; 6 | } 7 | 8 | // Test driver 9 | 10 | int main(int argc, char* argv[]) 11 | { 12 | if (argc != 2) 13 | return -1; 14 | if (OneLoop((int)argv[1][0])) 15 | { unsigned int i; for (i = 0U; 1; ++i); } 16 | return 0; 17 | } 18 | 19 | -------------------------------------------------------------------------------- /data/tests/c/src/OneLoop.s: -------------------------------------------------------------------------------- 1 | .file "OneLoop.c" 2 | .text 3 | .globl OneLoop 4 | .type OneLoop, @function 5 | OneLoop: 6 | .LFB0: 7 | .cfi_startproc 8 | pushq %rbp 9 | .cfi_def_cfa_offset 16 10 | .cfi_offset 6, -16 11 | movq %rsp, %rbp 12 | .cfi_def_cfa_register 6 13 | movl %edi, -20(%rbp) 14 | movl $0, -4(%rbp) 15 | jmp .L2 16 | .L3: 17 | addl $4, -4(%rbp) 18 | .L2: 19 | movl -4(%rbp), %eax 20 | cmpl -20(%rbp), %eax 21 | jl .L3 22 | cmpl $15, -4(%rbp) 23 | sete %al 24 | movzbl %al, %eax 25 | popq %rbp 26 | .cfi_def_cfa 7, 8 27 | ret 28 | .cfi_endproc 29 | .LFE0: 30 | .size OneLoop, .-OneLoop 31 | .globl main 32 | .type main, @function 33 | main: 34 | .LFB1: 35 | .cfi_startproc 36 | pushq %rbp 37 | .cfi_def_cfa_offset 16 38 | .cfi_offset 6, -16 39 | movq %rsp, %rbp 40 | .cfi_def_cfa_register 6 41 | subq $32, %rsp 42 | movl %edi, -20(%rbp) 43 | movq %rsi, -32(%rbp) 44 | cmpl $2, -20(%rbp) 45 | je .L6 46 | movl $-1, %eax 47 | jmp .L7 48 | .L6: 49 | movq -32(%rbp), %rax 50 | addq $8, %rax 51 | movq (%rax), %rax 52 | movzbl (%rax), %eax 53 | movsbl %al, %eax 54 | movl %eax, %edi 55 | call OneLoop 56 | testl %eax, %eax 57 | je .L8 58 | movl $0, -4(%rbp) 59 | .L9: 60 | addl $1, -4(%rbp) 61 | jmp .L9 62 | .L8: 63 | movl $0, %eax 64 | .L7: 65 | leave 66 | .cfi_def_cfa 7, 8 67 | ret 68 | .cfi_endproc 69 | .LFE1: 70 | .size main, .-main 71 | .ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4" 72 | .section .note.GNU-stack,"",@progbits 73 | -------------------------------------------------------------------------------- /data/tests/c/src/TwoLoops.c: -------------------------------------------------------------------------------- 1 | void TwoLoops(int n) { 2 | int i = 0, j = 0; 3 | while (i < n) i += 4; 4 | while (i != j + 7) j += 2; 5 | } 6 | 7 | // Test driver 8 | 9 | #include "./bugst_utils.h" 10 | 11 | int main(void)//int argc, char* argv[]) 12 | { 13 | int N; 14 | BUGST_IGNORE_UNINITIALISED_INT(&N); 15 | TwoLoops(N); 16 | BUGST_REPORT_TARGET_LOCATION_REACHED(); 17 | BUGST_TERMINATE_WHOLE_PROGRAM_ANALYSIS(); 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /data/tests/c/src/hello.c: -------------------------------------------------------------------------------- 1 | extern void* malloc(unsigned int n); 2 | extern void free(void* p); 3 | 4 | typedef int elem_type; 5 | 6 | int containsAt(elem_type const* const A, int const k, elem_type const* const X) 7 | { 8 | int i = 0; 9 | for ( ; A[k+i] != 0 && X[i] != 0 && A[k+i] == X[i]; ++i) 10 | ; 11 | if (X[i] != 0) 12 | return 0; 13 | return 1; 14 | } 15 | 16 | int contains(elem_type const* const A, elem_type const* const X) 17 | { 18 | for (int i = 0; A[i] != 0; ++i) 19 | if (containsAt(A,i,X)) 20 | return 1; 21 | return 0; 22 | } 23 | 24 | #include "./bugst_utils.h" 25 | 26 | int main(void)//int argc, char* argv[]) 27 | { 28 | int N; 29 | BUGST_IGNORE_UNINITIALISED_INT(&N); 30 | if (N > 0) 31 | { 32 | elem_type const hello[] = { 72, 101, 108, 108, 111, 0 }; // "Hello\0" 33 | elem_type* const A = (elem_type*)malloc(N * sizeof(elem_type)); 34 | A[N-1] = 0; 35 | BUGST_IGNORE_UNINITIALISED_INT_ARRAY(A,N-1); 36 | if (contains(A,hello)) 37 | { 38 | BUGST_REPORT_TARGET_LOCATION_REACHED(); 39 | BUGST_TERMINATE_WHOLE_PROGRAM_ANALYSIS(); 40 | } 41 | free(A); 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /data/tests/c/src/matrIR.c: -------------------------------------------------------------------------------- 1 | typedef int elem_type; 2 | 3 | int matrIR(elem_type const* const A, int const m, int const n) 4 | { 5 | int w = 0; 6 | for (int i = 0; i < m; ++i) 7 | { 8 | int k = 0; 9 | for (int j = i; j < n; ++j) 10 | if (A[i*n+j] > 10 && A[i*n+j] < 100) 11 | ++k; 12 | if (k > 15) 13 | { 14 | w = 1; 15 | break; 16 | } 17 | } 18 | return m > 20 && n > 20 && w == 1; 19 | } 20 | 21 | // Test driver 22 | 23 | extern void* malloc(unsigned int n); 24 | extern void free(void* p); 25 | 26 | #include "./bugst_utils.h" 27 | 28 | int main(void)//int argc, char* argv[]) 29 | { 30 | int M,N; 31 | BUGST_IGNORE_UNINITIALISED_INT(&M); 32 | BUGST_IGNORE_UNINITIALISED_INT(&N); 33 | if (M > 0 && N > 0) 34 | { 35 | elem_type A[M][N]; 36 | BUGST_IGNORE_UNINITIALISED_INT_ARRAY(&A[0][0],M*N); 37 | if (matrIR(&A[0][0],M,N)) 38 | { 39 | BUGST_REPORT_TARGET_LOCATION_REACHED(); 40 | BUGST_TERMINATE_WHOLE_PROGRAM_ANALYSIS(); 41 | } 42 | } 43 | return 0; 44 | } 45 | -------------------------------------------------------------------------------- /data/tests/c/src/matrIR_dyn.c: -------------------------------------------------------------------------------- 1 | typedef int elem_type; 2 | 3 | int matrIR(elem_type const* const A[], int const m, int const n) 4 | { 5 | int w = 0; 6 | for (int i = 0; i < m; ++i) 7 | { 8 | int k = 0; 9 | for (int j = i; j < n; ++j) 10 | if (A[i][j] > 10 && A[i][j] < 100) 11 | ++k; 12 | if (k > 15) 13 | { 14 | w = 1; 15 | break; 16 | } 17 | } 18 | return m > 20 && n > 20 && w == 1; 19 | } 20 | 21 | // Test driver 22 | 23 | extern void* malloc(unsigned int n); 24 | extern void free(void* p); 25 | 26 | #include "./bugst_utils.h" 27 | 28 | int main(void)//int argc, char* argv[]) 29 | { 30 | int M,N; 31 | BUGST_IGNORE_UNINITIALISED_INT(&M); 32 | BUGST_IGNORE_UNINITIALISED_INT(&N); 33 | if (M > 0 && N > 0) 34 | { 35 | elem_type* A[M]; 36 | for (int i = 0; i < M; ++i) 37 | { 38 | A[i] = (elem_type*)malloc(N * sizeof(elem_type)); 39 | BUGST_IGNORE_UNINITIALISED_INT_ARRAY(A[i],N); 40 | } 41 | if (matrIR(A,M,N)) 42 | { 43 | BUGST_REPORT_TARGET_LOCATION_REACHED(); 44 | BUGST_TERMINATE_WHOLE_PROGRAM_ANALYSIS(); 45 | } 46 | BUGST_DEATH_END(); 47 | for (int i = 0; i < M; ++i) 48 | free(A[i]); 49 | } 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /doc/CFG_recovery/fig_copy_program.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trtikm/Rebours/b52be64d8ede66f7c9fd19049e0bedf07737cd4e/doc/CFG_recovery/fig_copy_program.pdf -------------------------------------------------------------------------------- /doc/CFG_recovery/fig_prologue_stack_init.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trtikm/Rebours/b52be64d8ede66f7c9fd19049e0bedf07737cd4e/doc/CFG_recovery/fig_prologue_stack_init.pdf -------------------------------------------------------------------------------- /doc/CFG_recovery/fig_schema.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trtikm/Rebours/b52be64d8ede66f7c9fd19049e0bedf07737cd4e/doc/CFG_recovery/fig_schema.pdf -------------------------------------------------------------------------------- /doc/CFG_recovery/fig_schema_chaining.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trtikm/Rebours/b52be64d8ede66f7c9fd19049e0bedf07737cd4e/doc/CFG_recovery/fig_schema_chaining.pdf -------------------------------------------------------------------------------- /doc/CFG_recovery/fig_schema_encoding.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/trtikm/Rebours/b52be64d8ede66f7c9fd19049e0bedf07737cd4e/doc/CFG_recovery/fig_schema_encoding.pdf -------------------------------------------------------------------------------- /program/INSTALL: -------------------------------------------------------------------------------- 1 | program 2 | ======= 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/MAL/program/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | 27 | 28 | All built binaries can be found in the directory: 29 | 30 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib 31 | 32 | 33 | 2) MS-Windows 7+ 34 | ---------------- 35 | 36 | TODO 37 | 38 | -------------------------------------------------------------------------------- /program/README: -------------------------------------------------------------------------------- 1 | program 2 | ======= 3 | 4 | 5 | -------------------------------------------------------------------------------- /program/include/rebours/program/assembly.hpp: -------------------------------------------------------------------------------- 1 | #ifndef REBOURS_PROGRAM_MICROCODE_ASSEMBLY_HPP_INCLUDED 2 | # define REBOURS_PROGRAM_MICROCODE_ASSEMBLY_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | # include 10 | # include 11 | # include 12 | 13 | namespace microcode { 14 | 15 | 16 | using annotation = std::pair; 17 | using node_annotations = std::vector; 18 | using annotations = std::unordered_map; 19 | 20 | 21 | //void insert(annotations const& src, annotations& dst, bool const overwrite_old = false); 22 | void append(annotations const& src, annotations& dst); 23 | 24 | node_annotations::const_iterator find(node_annotations const& A, std::string const& keyword); 25 | node_annotations::iterator find(node_annotations& A, std::string const& keyword); 26 | 27 | std::string const* find(annotations const& A, program_component::node_id const node, std::string const& keyword); 28 | std::string* find(annotations& A, program_component::node_id const node, std::string const& keyword); 29 | 30 | inline std::string const* find(annotations const* const A, program_component::node_id const node, std::string const& keyword) 31 | { 32 | return A == nullptr ? nullptr : find(*A,node,keyword); 33 | } 34 | 35 | inline std::string* find(annotations* const A, program_component::node_id const node, std::string const& keyword) 36 | { 37 | return A == nullptr ? nullptr : find(*A,node,keyword); 38 | } 39 | 40 | std::unique_ptr create_initial_annotations(); 41 | 42 | 43 | std::pair,std::unique_ptr > create_program_from_assembly_text(std::istream& assembly_text, std::string& error_message); 44 | 45 | std::ostream& save_program_as_assembly_text(std::ostream& output_stream, program const& P, annotations const* const A, 46 | std::string const& header_text = "", bool const print_node_edge_ids = true); 47 | 48 | 49 | std::string assembly_text(instruction const& I, std::string const& line_adjustment = "", annotations const* const A = nullptr); 50 | 51 | } 52 | 53 | #endif 54 | -------------------------------------------------------------------------------- /program/include/rebours/program/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /program/include/rebours/program/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /program/include/rebours/program/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /program/include/rebours/program/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /program/include/rebours/program/large_types.hpp: -------------------------------------------------------------------------------- 1 | #ifndef LARGE_TYPES_HPP_INCLUDED 2 | # define LARGE_TYPES_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | # include 9 | # include 10 | 11 | 12 | struct uint128_t 13 | { 14 | using data_type = std::array; 15 | 16 | uint128_t() : m_data() {} 17 | uint128_t(uint64_t const lo, uint64_t const hi = 0ULL); 18 | 19 | static constexpr uint64_t size() noexcept { return std::tuple_size::value; } 20 | uint8_t at(uint64_t const i) const { return m_data.at(i); } 21 | uint8_t& at(uint64_t const i) { return m_data.at(i); } 22 | 23 | uint8_t const* data() const { return m_data.data(); } 24 | uint8_t* data() { return m_data.data(); } 25 | 26 | uint64_t lo() const { return *reinterpret_cast(data()); } 27 | uint64_t hi() const { return *reinterpret_cast(data() + 8ULL); } 28 | 29 | uint64_t& lo() { return *reinterpret_cast(data()); } 30 | uint64_t& hi() { return *reinterpret_cast(data() + 8ULL); } 31 | 32 | private: 33 | data_type m_data; 34 | }; 35 | 36 | uint128_t operator+(uint128_t const& a, uint128_t const& b); 37 | uint128_t operator*(uint128_t const& a, uint128_t const& b); 38 | uint128_t operator%(uint128_t const& a, uint128_t const& b); 39 | uint128_t operator/(uint128_t const& a, uint128_t const& b); 40 | 41 | bool operator==(uint128_t const& a, uint128_t const& b); 42 | bool operator<(uint128_t const& a, uint128_t const& b); 43 | 44 | inline bool operator!=(uint128_t const& a, uint128_t const& b) { return !(a == b); } 45 | inline bool operator<=(uint128_t const& a, uint128_t const& b) { return a == b || a < b; } 46 | inline bool operator>=(uint128_t const& a, uint128_t const& b) { return a == b || b < a; } 47 | inline bool operator>(uint128_t const& a, uint128_t const& b) { return b < a; } 48 | 49 | 50 | using float80_t = std::array; 51 | 52 | 53 | std::string to_string(uint128_t const& a, std::ios_base::fmtflags const flags = std::ios::dec); 54 | 55 | 56 | msgstream& operator<<(msgstream& ostr, uint128_t const& a); 57 | std::ostream& operator<<(std::ostream& ostr, uint128_t const& a); 58 | 59 | 60 | #endif 61 | -------------------------------------------------------------------------------- /program/include/rebours/program/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /program/include/rebours/program/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /program/src/assembly.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace microcode { 8 | 9 | 10 | void append(annotations const& src, annotations& dst) 11 | { 12 | for (auto const& node_ans : src) 13 | { 14 | annotations::iterator const nit = dst.find(node_ans.first); 15 | if (nit == dst.end()) 16 | dst.insert(node_ans); 17 | else 18 | std::copy(node_ans.second.cbegin(),node_ans.second.cend(),std::back_inserter(nit->second)); 19 | } 20 | } 21 | 22 | node_annotations::const_iterator find(node_annotations const& A, std::string const& keyword) 23 | { 24 | for (auto it = A.cbegin(); it != A.cend(); ++it) 25 | if (it->first == keyword) 26 | return it; 27 | return A.cend(); 28 | } 29 | 30 | node_annotations::iterator find(node_annotations& A, std::string const& keyword) 31 | { 32 | for (auto it = A.begin(); it != A.end(); ++it) 33 | if (it->first == keyword) 34 | return it; 35 | return A.end(); 36 | } 37 | 38 | std::string const* find(annotations const& A, program_component::node_id const node, std::string const& keyword) 39 | { 40 | annotations::const_iterator const nit = A.find(node); 41 | if (nit == A.end()) 42 | return nullptr; 43 | node_annotations::const_iterator ait = find(nit->second,keyword); 44 | return ait == nit->second.end() ? nullptr : &ait->second; 45 | } 46 | 47 | std::string* find(annotations& A, program_component::node_id const node, std::string const& keyword) 48 | { 49 | annotations::iterator const nit = A.find(node); 50 | if (nit == A.end()) 51 | return nullptr; 52 | node_annotations::iterator ait = find(nit->second,keyword); 53 | return ait == nit->second.end() ? nullptr : &ait->second; 54 | } 55 | 56 | 57 | std::unique_ptr create_initial_annotations() 58 | { 59 | return std::unique_ptr( new annotations ); 60 | } 61 | 62 | 63 | } 64 | -------------------------------------------------------------------------------- /program/src/assembly_loader.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | namespace microcode { namespace detail { 8 | 9 | 10 | 11 | }} 12 | 13 | namespace microcode { 14 | 15 | 16 | std::pair,std::unique_ptr > create_program_from_assembly_text(std::istream& assembly_text, std::string& error_message) 17 | { 18 | (void)assembly_text; 19 | (void)error_message; 20 | 21 | NOT_IMPLEMENTED_YET(); 22 | } 23 | 24 | 25 | } 26 | -------------------------------------------------------------------------------- /tool/ldexe/INSTALL: -------------------------------------------------------------------------------- 1 | ldexe 2 | ===== 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/tools/ldexe/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DDESCRIPTOR_ROOT= 27 | -DPROGRAM_ROOT= 28 | -DLOADER_ROOT= 29 | -DRELOADER_ROOT= 30 | -DPROLOGUE_ROOT= 31 | -DRECOGNISER_ROOT= 32 | -DENCODER_ROOT= 33 | -DCAPSTONE_NEXT_ROOT= 34 | -DLDEXE_BUILD_TESTS= 35 | 36 | 37 | All built binaries can be found in the directory: 38 | 39 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/tool 40 | 41 | 42 | 2) MS-Windows 7+ 43 | ---------------- 44 | 45 | TODO 46 | 47 | -------------------------------------------------------------------------------- /tool/ldexe/README: -------------------------------------------------------------------------------- 1 | ldexe 2 | ===== 3 | 4 | 5 | -------------------------------------------------------------------------------- /tool/ldexe/include/ldexe/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /tool/ldexe/include/ldexe/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /tool/ldexe/include/ldexe/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /tool/ldexe/include/ldexe/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | operator std::string() const { return m_buffer->str(); } 14 | private: 15 | std::shared_ptr m_buffer; 16 | }; 17 | 18 | 19 | #endif 20 | -------------------------------------------------------------------------------- /tool/ldexe/include/ldexe/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | -------------------------------------------------------------------------------- /tool/ldexe/src/ldexe.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import os 3 | 4 | if os.path.isfile("./ldexe"): 5 | exename = "./ldexe" 6 | else: 7 | print("ERROR: cannot locate the 'ldexe' executable file in the current directory.") 8 | exit() 9 | 10 | if len(sys.argv) == 1 or "--help" in sys.argv: 11 | os.system(exename + " --help") 12 | print("--root-dir=") 13 | print(" It is a root directory of a hierarchy of binary files to be loaded.") 14 | print(" This option is converted to several --binary options such that for") 15 | print(" each file [/]/ inside the hierarchy there") 16 | print(" is generated an option --binary=[/]/. Note") 17 | print(" that this option cannot be combined with --dump option.") 18 | exit() 19 | 20 | if "--root-dir=" in " ".join(sys.argv) and "--dump=" in " ".join(sys.argv): 21 | print("ERROR: Options --root-dir and --dump cannot be passed together.") 22 | exit() 23 | 24 | root_dir = None 25 | for opt in sys.argv: 26 | if opt.startswith("--root-dir="): 27 | root_dir = opt[len("--root-dir="):] 28 | break 29 | 30 | if root_dir is None: 31 | os.system(exename + " " + (" ".join(sys.argv[1:]))) 32 | exit() 33 | 34 | if not os.path.exists(root_dir): 35 | print("The path passed to --root-dir does not exist.") 36 | exit() 37 | 38 | if not os.path.isdir(root_dir): 39 | print("The path passed to --root-dir does not represent a directory.") 40 | exit() 41 | 42 | pathnames = [] 43 | for root, dirnames, filenames in os.walk(root_dir): 44 | for filename in filenames: 45 | pathname = os.path.join(root, filename) 46 | pathnames.append("--binary=\"" + pathname + "\"") 47 | 48 | if len(pathnames) == 0: 49 | print("There is no file under the directory passed to --root-dir.") 50 | exit() 51 | 52 | os.system(exename + " " + (" ".join(pathnames))) 53 | 54 | -------------------------------------------------------------------------------- /tool/natexe/INSTALL: -------------------------------------------------------------------------------- 1 | natexe 2 | ====== 3 | 4 | Here we provide an installation guide for all supported platforms. 5 | 6 | 7 | 1) Linux (tested on Ubuntu and Debian) 8 | -------------------------------------- 9 | First install the following software dependencies: 10 | - g++ 11 | - git (with its SVN extension) 12 | - cmake 13 | 14 | If you are in hurry, type the following commands in a terminal: 15 | 16 | $ git svn clone https://svn.labri.fr/repos/rebours ./ 17 | $ cd rebours/tools/natexe/ 18 | $ mkdir ./build 19 | $ cd ./build 20 | $ cmake .. 21 | $ make install 22 | 23 | If you want to know more about the compilation options: 24 | $ cmake .. 25 | -DCMAKE_BUILD_TYPE= 26 | -DDESCRIPTOR_ROOT= 27 | -DPROGRAM_ROOT= 28 | -DLOADER_ROOT= 29 | -DRELOADER_ROOT= 30 | -DPROLOGUE_ROOT= 31 | -DRECOGNISER_ROOT= 32 | -DENCODER_ROOT= 33 | -DCAPSTONE_NEXT_ROOT= 34 | -DNATEXE_BUILD_TESTS= 35 | 36 | 37 | All built binaries can be found in the directory: 38 | 39 | ./build/../bin/Linux_${CMAKE_BUILD_TYPE}/lib/tool 40 | 41 | 42 | 2) MS-Windows 7+ 43 | ---------------- 44 | 45 | TODO 46 | 47 | -------------------------------------------------------------------------------- /tool/natexe/README: -------------------------------------------------------------------------------- 1 | natexe 2 | ====== 3 | 4 | 5 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/argparser.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ARGPARSER_HPP_INCLUDED 2 | # define ARGPARSER_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | 8 | namespace argparser { 9 | 10 | 11 | std::string parse_arguments(int argc, char* argv[]); 12 | 13 | bool do_print_help(); 14 | std::string const& help_text(); 15 | 16 | bool do_print_version(); 17 | std::string const& version_text(); 18 | 19 | bool use_loader(); 20 | std::string const& path_and_name_of_a_binary_file_to_be_loaded(); 21 | std::vector const& ignored_dynamic_link_files(); 22 | std::vector const& search_directories_for_dynamic_link_files(); 23 | std::string const& path_and_name_of_a_prologue_program(); 24 | std::string const& path_and_name_of_a_microcode_program(); 25 | 26 | bool do_save_descriptor(); 27 | bool do_save_sections_of_descriptor(); 28 | std::string const& save_path_and_name_of_a_descriptor_start_file(); 29 | 30 | bool do_save_prologue_program(); 31 | std::string const& save_path_and_name_of_a_prologue_program(); 32 | 33 | bool do_save_recovered_program(); 34 | std::string const& save_path_and_name_of_a_recovered_program(); 35 | 36 | bool do_save_encoded_program(); 37 | std::string const& save_path_and_name_of_an_encoded_program(); 38 | 39 | uint32_t timeout_in_seconds(); 40 | 41 | std::string const& path_and_name_of_the_output_log_file(); 42 | 43 | 44 | } 45 | 46 | #endif 47 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/assumptions.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ASSUMPTIONS_HPP_INCLUDED 2 | # define ASSUMPTIONS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_ASSUMPTION_CHECKING 5 | # include 6 | # define ASSUMPTION(C) assert(C) 7 | # else 8 | # define ASSUMPTION(C) {} 9 | # endif 10 | 11 | #endif 12 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/development.hpp: -------------------------------------------------------------------------------- 1 | #ifndef DEVELOPMENT_HPP_INCLUDED 2 | # define DEVELOPMENT_HPP_INCLUDED 3 | 4 | # include 5 | 6 | # define NOT_IMPLEMENTED_YET() do { throw std::logic_error("NOT IMPLEMENTED YET!"); } while (false) 7 | 8 | #endif 9 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/endian.hpp: -------------------------------------------------------------------------------- 1 | #ifndef ENDIAN_HPP_INCLUDED 2 | # define ENDIAN_HPP_INCLUDED 3 | 4 | # include 5 | 6 | inline bool is_this_little_endian_machine() noexcept 7 | { 8 | return *reinterpret_cast("\1\0\0\0") == 1U; 9 | } 10 | 11 | 12 | #endif 13 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/file_utils.hpp: -------------------------------------------------------------------------------- 1 | #ifndef FILE_UTILS_HPP_INCLUDED 2 | # define FILE_UTILS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | # include 7 | # include 8 | 9 | 10 | /** 11 | * This module implements utility functions which provide us disc-related functionality, 12 | * like manipulation with disc paths (concatenation/splitting), checking for existence 13 | * of files, etc. 14 | */ 15 | 16 | namespace fileutl { 17 | 18 | 19 | bool file_exists(std::string const& pathname); 20 | bool is_directory(std::string const& pathname); 21 | uint64_t file_size(std::string const& file_pathname); 22 | std::string parse_name_in_pathname(std::string const& file_pathname); 23 | std::string parse_path_in_pathname(std::string const& file_pathname); 24 | std::string remove_extension(std::string const& filename); 25 | void create_directory(std::string const& pathname); 26 | std::string concatenate_file_paths(std::string const& left_path, std::string const& right_path); 27 | std::string absolute_path(std::string const& path); 28 | std::string normalise_path(std::string const& path); 29 | void split_pathname(std::string const& pathname, std::vector& output); 30 | std::string join_path_parts(std::vector const& parts); 31 | std::string get_common_preffix(std::string const& pathname1, std::string const& pathname2); 32 | std::string get_relative_path(std::string const& pathname, std::string const& directory); 33 | 34 | 35 | } 36 | 37 | #endif 38 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/invariants.hpp: -------------------------------------------------------------------------------- 1 | #ifndef INVARIANTS_HPP_INCLUDED 2 | # define INVARIANTS_HPP_INCLUDED 3 | 4 | # ifndef DISABLE_INVARIANT_CHECKING 5 | # include 6 | # define INVARIANT(C) assert(C) 7 | # define UNREACHABLE() do { assert(false); throw 0; } while (false) 8 | # else 9 | # define INVARIANT(C) {} 10 | # define UNREACHABLE() throw 0 11 | # endif 12 | 13 | #endif 14 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/msgstream.hpp: -------------------------------------------------------------------------------- 1 | #ifndef MSGSTREAM_HPP_INCLUDED 2 | # define MSGSTREAM_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | 8 | struct msgstream 9 | { 10 | msgstream() : m_buffer(new std::ostringstream) {} 11 | template 12 | msgstream operator<<(T const& value) const { *m_buffer << value; return *this;} 13 | std::ios_base::fmtflags flags() const { return m_buffer->flags(); } 14 | operator std::string() const { return str(); } 15 | std::string str() const { return m_buffer->str(); } 16 | struct end {}; 17 | std::string operator<<(end const) const { return str();} 18 | private: 19 | std::shared_ptr m_buffer; 20 | }; 21 | 22 | 23 | #endif 24 | -------------------------------------------------------------------------------- /tool/natexe/include/natexe/test.hpp: -------------------------------------------------------------------------------- 1 | #ifndef TEST_HPP_INCLUDED 2 | # define TETS_HPP_INCLUDED 3 | 4 | # include 5 | # include 6 | 7 | # define TEST_SUCCESS(C) do { if (!(C)) { assert(C); throw std::logic_error("TEST_SUCCESS has failed."); } } while (false) 8 | # define TEST_FAILURE(C) do { if (C) { assert(!(C)); throw std::logic_error("TEST_FAILURE has failed."); } } while (false) 9 | 10 | #endif 11 | --------------------------------------------------------------------------------