diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-19 22:30:07 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-19 22:30:07 +0200 |
| commit | dd8f1658c47db665481c725b9469408cf17e8c2e (patch) | |
| tree | 185d0354c57f717068e348b322482dd4f826b77d | |
| parent | de95ca22ec87cc8b79ceb7beba475301461713a6 (diff) | |
| download | openwar-dd8f1658c47db665481c725b9469408cf17e8c2e.tar.gz openwar-dd8f1658c47db665481c725b9469408cf17e8c2e.tar.bz2 openwar-dd8f1658c47db665481c725b9469408cf17e8c2e.zip | |
implements a LE file parser and bare outputter.
| -rw-r--r-- | binparse/binparse.hpp | 2 | ||||
| -rw-r--r-- | le/CMakeLists.txt | 13 | ||||
| -rw-r--r-- | le/le_file.cpp | 80 | ||||
| -rw-r--r-- | le/le_file.hpp | 33 | ||||
| -rw-r--r-- | le/le_file_parser.cpp | 56 |
5 files changed, 183 insertions, 1 deletions
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<uint8_t, 8> parse<std::array<uint8_t, 8>>(std::istream& is, std::stri template<> std::array<uint8_t, 22> parse<std::array<uint8_t, 22>>(std::istream& is, std::string name); -void dump_bytes(std::istream& is, std::vector<uint8_t> buffer, std::string name); +void dump_bytes(std::istream& is, std::vector<uint8_t>& 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 <boost/fusion/adapted/struct.hpp> + +typedef std::array<uint8_t, 8> A1; +typedef std::array<uint8_t, 22> 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<uint8_t>, dos_exe) + (le::LEHeader, le_header) + (std::vector<uint8_t>, le_exe) +) + +namespace le { + +LEFile parse_file(std::istream& is) { + auto mz_h = mz::parse_header(is); + auto unused = parse<std::array<uint8_t, 8>>(is, "unused_1"); + auto OEM_id = parse<binparse::Value16>(is, "OEM_id"); + auto OEM_info = parse<std::array<uint8_t, 22>>(is, "OEM_info"); + auto le_offset = parse<binparse::Offset32>(is, "le_offset"); + + size_t dos_exe_len = le_offset - 0x40; + std::vector<uint8_t> dos_exe = std::vector<uint8_t>(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<char>(is), {}); + std::vector<uint8_t> 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<uint8_t, 8> const& array) { + return os; +} + +std::ostream& operator<<(std::ostream& os, std::array<uint8_t, 22> const& array) { + return os; +} + +std::ostream& operator<<(std::ostream& os, std::vector<uint8_t> vec) { + return os; +} + +std::ostream& output_impl(std::ostream& os, LEFile const&, indices<>) { + return os; +} + +template <int I, int... Indices> +std::ostream& output_impl(std::ostream& os, const LEFile& file, indices<I, Indices...>) { + os << boost::fusion::extension::struct_member_name<LEFile, I>::call() << ": " << boost::fusion::at_c<I>(file) << std::endl; + return output_impl(os, file, indices<Indices...>{}); +} + +std::ostream&operator<<(std::ostream& os, LEFile const& file) +{ + typedef build_indices<boost::fusion::result_of::size<LEFile>::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 <cstdint> +#include <cstddef> +#include <memory> +#include <array> +#include <vector> + +namespace le { + +using namespace binparse; + +struct LEFile +{ + mz::MZHeader mz_header; + std::array<uint8_t, 8> unused_1; + Value16 OEM_id; + std::array<uint8_t, 22> OEM_info; + Offset32 le_offset; + std::vector<uint8_t> dos_exe; + LEHeader le_header; + std::vector<uint8_t> 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 <boost/program_options.hpp> +#include <boost/filesystem.hpp> + +#include <iostream> + +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<std::string>(), "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<std::string>(); + + 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; +} |
