From dd8f1658c47db665481c725b9469408cf17e8c2e Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Sun, 19 Jun 2016 22:30:07 +0200 Subject: implements a LE file parser and bare outputter. --- binparse/binparse.hpp | 2 +- le/CMakeLists.txt | 13 +++++++++ le/le_file.cpp | 80 +++++++++++++++++++++++++++++++++++++++++++++++++++ le/le_file.hpp | 33 +++++++++++++++++++++ le/le_file_parser.cpp | 56 ++++++++++++++++++++++++++++++++++++ 5 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 le/le_file.cpp create mode 100644 le/le_file.hpp create mode 100644 le/le_file_parser.cpp diff --git a/binparse/binparse.hpp b/binparse/binparse.hpp index 5b21086..e649ce7 100644 --- a/binparse/binparse.hpp +++ b/binparse/binparse.hpp @@ -46,7 +46,7 @@ std::array parse>(std::istream& is, std::stri template<> std::array parse>(std::istream& is, std::string name); -void dump_bytes(std::istream& is, std::vector buffer, std::string name); +void dump_bytes(std::istream& is, std::vector& buffer, std::string name); std::string to_string(Magic16 magic); diff --git a/le/CMakeLists.txt b/le/CMakeLists.txt index 646f68b..5d849b3 100644 --- a/le/CMakeLists.txt +++ b/le/CMakeLists.txt @@ -29,5 +29,18 @@ target_include_directories(le_header_parser PRIVATE ${Boost_INCLUDE_DIRS} ) +add_executable(le_file_parser + le_file_parser.cpp +) + +target_link_libraries(le_file_parser + PRIVATE le + PRIVATE ${Boost_LIBRARIES} +) + +target_include_directories(le_file_parser + PRIVATE ${Boost_INCLUDE_DIRS} +) + diff --git a/le/le_file.cpp b/le/le_file.cpp new file mode 100644 index 0000000..3cec50c --- /dev/null +++ b/le/le_file.cpp @@ -0,0 +1,80 @@ +#include "le_file.hpp" + +#include "index_list.hpp" + +#include + +typedef std::array A1; +typedef std::array A2; + +BOOST_FUSION_ADAPT_STRUCT( + le::LEFile, + (mz::MZHeader, mz_header) + (A1, unused_1) + (binparse::Value16, OEM_id) + (A2, OEM_info) + (binparse::Offset32, le_offset) + (std::vector, dos_exe) + (le::LEHeader, le_header) + (std::vector, le_exe) +) + +namespace le { + +LEFile parse_file(std::istream& is) { + auto mz_h = mz::parse_header(is); + auto unused = parse>(is, "unused_1"); + auto OEM_id = parse(is, "OEM_id"); + auto OEM_info = parse>(is, "OEM_info"); + auto le_offset = parse(is, "le_offset"); + + size_t dos_exe_len = le_offset - 0x40; + std::vector dos_exe = std::vector(dos_exe_len, 0); + binparse::dump_bytes(is, dos_exe, "dos_exe"); + + auto le_h = le::parse_header(is); + std::string str(std::istreambuf_iterator(is), {}); + std::vector le_exe(str.begin(), str.end()); + + return { + mz_h, + unused, + OEM_id, + OEM_info, + le_offset, + dos_exe, + le_h, + le_exe + }; +} + +std::ostream& operator<<(std::ostream& os, std::array const& array) { + return os; +} + +std::ostream& operator<<(std::ostream& os, std::array const& array) { + return os; +} + +std::ostream& operator<<(std::ostream& os, std::vector vec) { + return os; +} + +std::ostream& output_impl(std::ostream& os, LEFile const&, indices<>) { + return os; +} + +template +std::ostream& output_impl(std::ostream& os, const LEFile& file, indices) { + os << boost::fusion::extension::struct_member_name::call() << ": " << boost::fusion::at_c(file) << std::endl; + return output_impl(os, file, indices{}); +} + +std::ostream&operator<<(std::ostream& os, LEFile const& file) +{ + typedef build_indices::value>::type indices; + + return output_impl(os, file, indices{}); +} + +} \ No newline at end of file diff --git a/le/le_file.hpp b/le/le_file.hpp new file mode 100644 index 0000000..010c49b --- /dev/null +++ b/le/le_file.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "binparse.hpp" +#include "mz_header.hpp" +#include "le_header.hpp" + +#include +#include +#include +#include +#include + +namespace le { + +using namespace binparse; + +struct LEFile +{ + mz::MZHeader mz_header; + std::array unused_1; + Value16 OEM_id; + std::array OEM_info; + Offset32 le_offset; + std::vector dos_exe; + LEHeader le_header; + std::vector le_exe; +}; + +LEFile parse_file(std::istream& is); + +std::ostream& operator<<(std::ostream& os, LEFile const& file); + +} diff --git a/le/le_file_parser.cpp b/le/le_file_parser.cpp new file mode 100644 index 0000000..2d5eed9 --- /dev/null +++ b/le/le_file_parser.cpp @@ -0,0 +1,56 @@ + +#include "le_file.hpp" + +#include +#include + +#include + +int main(int argc, char* argv[]) { + boost::program_options::options_description description; + description.add_options() + ("help,h", "produces this help message") + ("exe,e", boost::program_options::value(), "The LE executable to parse the header for.") + ; + + boost::program_options::variables_map vm; + boost::program_options::store(boost::program_options::parse_command_line(argc, argv, description), vm); + boost::program_options::notify(vm); + + if(vm.count("help")) { + std::cout << description << std::endl; + return 0; + } + + boost::filesystem::path file_path; + if(vm.count("exe")) { + std::string exe_file = vm["exe"].as(); + + if(boost::filesystem::exists(exe_file)) { + if(!boost::filesystem::is_directory(exe_file)) { + file_path = exe_file; + } else { + std::cerr << exe_file << " is a folder" << std::endl; + std::cerr << std::endl; + std::cerr << description << std::endl; + return -1; + } + } else { + std::cerr << "file: " << exe_file << " does not exist" << std::endl; + std::cerr << std::endl; + std::cerr << description << std::endl; + return -1; + } + } else { + std::cerr << "Option \"exe_file\" is required"; + std::cerr << std::endl; + std::cerr << description << std::endl; + return -1; + } + + std::ifstream file(file_path.string()); + auto x = le::parse_file(file); + std::cout << x << std::endl; + + return 0; +} -- cgit v1.2.3-70-g09d2