diff options
| author | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-23 18:07:42 +0200 |
|---|---|---|
| committer | Dennis Brentjes <d.brentjes@gmail.com> | 2016-06-23 18:07:42 +0200 |
| commit | a7bcede17b4c10e172c7877fc2ce89862dc454af (patch) | |
| tree | d89b8ff274d18d67d695c5f320a1d079e1bb26b6 | |
| parent | 0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b (diff) | |
| download | openwar-a7bcede17b4c10e172c7877fc2ce89862dc454af.tar.gz openwar-a7bcede17b4c10e172c7877fc2ce89862dc454af.tar.bz2 openwar-a7bcede17b4c10e172c7877fc2ce89862dc454af.zip | |
adds alot more binary parsing.
| -rw-r--r-- | binparse/otreestream.hpp | 7 | ||||
| -rw-r--r-- | binparse/output.cpp | 5 | ||||
| -rw-r--r-- | binparse/output.hpp | 26 | ||||
| -rw-r--r-- | binparse/parse.cpp | 8 | ||||
| -rw-r--r-- | binparse/parse.hpp | 4 | ||||
| -rw-r--r-- | binparse/types.hpp | 2 | ||||
| -rw-r--r-- | le/CMakeLists.txt | 6 | ||||
| -rw-r--r-- | le/le_entry_table.cpp | 27 | ||||
| -rw-r--r-- | le/le_entry_table.hpp | 19 | ||||
| -rw-r--r-- | le/le_entry_table_entry.cpp | 55 | ||||
| -rw-r--r-- | le/le_entry_table_entry.hpp | 33 | ||||
| -rw-r--r-- | le/le_file.cpp | 12 | ||||
| -rw-r--r-- | le/le_file.hpp | 6 | ||||
| -rw-r--r-- | le/le_object_page_table.cpp | 27 | ||||
| -rw-r--r-- | le/le_object_page_table.hpp | 23 | ||||
| -rw-r--r-- | le/le_object_page_table_entry.cpp | 27 | ||||
| -rw-r--r-- | le/le_object_page_table_entry.hpp | 28 | ||||
| -rw-r--r-- | le/le_object_table_entry.cpp | 2 | ||||
| -rw-r--r-- | le/le_object_table_entry.hpp | 2 | ||||
| -rw-r--r-- | le/le_resident_name_table.cpp | 26 | ||||
| -rw-r--r-- | le/le_resident_name_table.hpp | 19 | ||||
| -rw-r--r-- | le/le_resident_name_table_entry.cpp | 26 | ||||
| -rw-r--r-- | le/le_resident_name_table_entry.hpp | 21 |
23 files changed, 407 insertions, 4 deletions
diff --git a/binparse/otreestream.hpp b/binparse/otreestream.hpp index 3f57d4e..f7795e3 100644 --- a/binparse/otreestream.hpp +++ b/binparse/otreestream.hpp @@ -36,6 +36,13 @@ class indent { public: indent(std::ostream& os); + indent() = delete; + indent(indent const&) = delete; + indent(indent&&) = delete; + + indent& operator=(indent const&) = delete; + indent& operator=(indent&&) = delete; + ~indent(); }; diff --git a/binparse/output.cpp b/binparse/output.cpp index 78babd8..16447a7 100644 --- a/binparse/output.cpp +++ b/binparse/output.cpp @@ -43,6 +43,11 @@ std::ostream& operator<<(std::ostream& os, Offset32 o) { return os << std::hex << std::setw(sizeof(o) * 2) << std::setfill('0') << static_cast<uint32_t>(o); } +std::ostream&operator<<(std::ostream& os, PString8 s) +{ + return os << "(" << std::string(s).size() << ") " << std::string(s); +} + std::ostream&operator<<(std::ostream& os, std::array<uint8_t, 8> a) { return os; diff --git a/binparse/output.hpp b/binparse/output.hpp index 705a380..c5db2da 100644 --- a/binparse/output.hpp +++ b/binparse/output.hpp @@ -13,6 +13,7 @@ #include <vector> #include <map> #include <streambuf> +#include <typeinfo> namespace binparse { @@ -31,6 +32,8 @@ std::ostream& operator<<(std::ostream& os, Offset16 o); std::ostream& operator<<(std::ostream& os, Value32 v); std::ostream& operator<<(std::ostream& os, Offset32 o); +std::ostream& operator<<(std::ostream& os, PString8 s); + std::ostream& operator<<(std::ostream& os, std::array<uint8_t, 8> a); std::ostream& operator<<(std::ostream& os, std::array<uint8_t, 22> a); @@ -47,7 +50,7 @@ std::ostream& operator<<(std::ostream& os, std::map<Key, Value> const& map) { for(auto&& entry : map) { os << entry.first << ": " << entry.second << std::endl; } - } catch(std::exception&) { + } catch(std::bad_cast&) { os << std::endl; for(auto&& entry : map) { os << entry.first << ": " << entry.second << std::endl; @@ -57,6 +60,25 @@ std::ostream& operator<<(std::ostream& os, std::map<Key, Value> const& map) { return os; } +template <typename ValueType> +std::ostream& operator<<(std::ostream& os, std::vector<ValueType> const& vec) { + try { + indent scoped(os); + os << std::endl; + for(auto&& entry : vec) { + os << entry << std::endl; + } + } catch(std::bad_cast&) { + os << std::endl; + for(auto&& entry : vec) { + os << entry << std::endl; + } + } + return os; +} + + + template<typename T> std::ostream& output_impl(std::ostream& os, T const&, indices<>) { return os; @@ -78,7 +100,7 @@ std::ostream& operator<<(std::ostream& os, T const& t) { indent scoped(os); os << std::endl; output_impl<T>(os, t, indices{}); - } catch(std::exception&) { + } catch(std::bad_cast&) { os << std::endl; output_impl<T>(os, t, indices{}); } diff --git a/binparse/parse.cpp b/binparse/parse.cpp index cf7c0be..a26e72e 100644 --- a/binparse/parse.cpp +++ b/binparse/parse.cpp @@ -90,6 +90,14 @@ Offset32 parse<Offset32>(std::istream& is, std::string name) { } template<> +PString8 parse<PString8>(std::istream& is, std::string name) { + uint8_t len = parse<uint8_t>(is, name + "_len"); + std::vector<char> data(len, 0); + is.read(data.data(), len); + return PString8(std::string(data.begin(), data.end())); +} + +template<> std::array<uint8_t, 8> parse<std::array<uint8_t, 8>>(std::istream& is, std::string name) { if(!is) { throw UnexpectedEOS(); diff --git a/binparse/parse.hpp b/binparse/parse.hpp index 8015ba3..2103177 100644 --- a/binparse/parse.hpp +++ b/binparse/parse.hpp @@ -11,6 +11,7 @@ #include <stdexcept> #include <array> #include <vector> +#include <string> namespace binparse { @@ -48,6 +49,9 @@ template<> Offset32 parse<Offset32>(std::istream& is, std::string name); template<> +PString8 parse<PString8>(std::istream& is, std::string name); + +template<> std::array<uint8_t, 8> parse<std::array<uint8_t, 8>>(std::istream& is, std::string name); template<> diff --git a/binparse/types.hpp b/binparse/types.hpp index 9b6c4a6..d1b1910 100644 --- a/binparse/types.hpp +++ b/binparse/types.hpp @@ -17,6 +17,8 @@ BOOST_STRONG_TYPEDEF(uint16_t, Value16) BOOST_STRONG_TYPEDEF(uint32_t, Offset32) BOOST_STRONG_TYPEDEF(uint32_t, Value32) +BOOST_STRONG_TYPEDEF(std::string, PString8); + template <typename T> T operator+(T const lh, T const rh) { return T(0 + lh + rh); diff --git a/le/CMakeLists.txt b/le/CMakeLists.txt index c41d730..a135f8b 100644 --- a/le/CMakeLists.txt +++ b/le/CMakeLists.txt @@ -4,6 +4,12 @@ add_library(le STATIC le_file.hpp le_file.cpp le_object_table.hpp le_object_table.cpp le_object_table_entry.hpp le_object_table_entry.cpp + le_object_page_table.hpp le_object_page_table.cpp + le_object_page_table_entry.hpp le_object_page_table_entry.cpp + le_resident_name_table.hpp le_resident_name_table.cpp + le_resident_name_table_entry.hpp le_resident_name_table_entry.cpp + le_entry_table.hpp le_entry_table.cpp + le_entry_table_entry.hpp le_entry_table_entry.cpp ) target_include_directories(le diff --git a/le/le_entry_table.cpp b/le/le_entry_table.cpp new file mode 100644 index 0000000..28f901d --- /dev/null +++ b/le/le_entry_table.cpp @@ -0,0 +1,27 @@ +#include "le_entry_table.hpp" + +#include "output.hpp" + +namespace le { + +EntryTable parse_entry_table(std::istream& is, binparse::Offset32 offset) +{ + is.seekg(0, std::ios::beg); + is.ignore(offset); + + EntryTable table; + + uint32_t i = 1; + while(is.peek()) { + table.entries.emplace(i++, parse_entry_table_entry(is)); + } + + return table; +} + +std::ostream&operator<<(std::ostream& os, const EntryTable& table) +{ + return binparse::operator<<(os, table.entries); +} + +}
\ No newline at end of file diff --git a/le/le_entry_table.hpp b/le/le_entry_table.hpp new file mode 100644 index 0000000..f31f542 --- /dev/null +++ b/le/le_entry_table.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "le_entry_table_entry.hpp" + +#include <map> +#include <iostream> + +namespace le { + +struct EntryTable +{ + std::map<uint32_t, EntryTableEntry> entries; +}; + +EntryTable parse_entry_table(std::istream& is, binparse::Offset32 offset); + +std::ostream& operator<<(std::ostream& os, EntryTable const& table); + +}
\ No newline at end of file diff --git a/le/le_entry_table_entry.cpp b/le/le_entry_table_entry.cpp new file mode 100644 index 0000000..4894ec0 --- /dev/null +++ b/le/le_entry_table_entry.cpp @@ -0,0 +1,55 @@ +#include "le_entry_table_entry.hpp" + +#include "parse.hpp" +#include "output.hpp" + +#include <boost/fusion/adapted/struct.hpp> + +typedef boost::variant<binparse::Offset16, binparse::Offset32> EntryT; + +BOOST_FUSION_ADAPT_STRUCT( + le::EntryPoint, + (binparse::Value8, flags) + (EntryT, entry) +) + +BOOST_FUSION_ADAPT_STRUCT( + le::EntryTableEntry, + (binparse::Value8, nr_entries) + (binparse::Value8, flags) + (binparse::Value16, object_index) + (std::vector<le::EntryPoint>, entries) +) + +namespace le { + +EntryTableEntry parse_entry_table_entry(std::istream& is) { + EntryTableEntry entry; + + entry.nr_entries = binparse::parse<binparse::Value8>(is, "nr_entries"); + entry.flags = binparse::parse<binparse::Value8>(is, "flags"); + entry.object_index = binparse::parse<binparse::Value16>(is, "object_index"); + + for(Value8 i = Value8(0); i < entry.nr_entries; i++) { + if(entry.flags & 2) { + entry.entries.push_back({ + binparse::parse<Value8>(is, "flags"), + binparse::parse<Offset32>(is, "entry") + }); + } else { + entry.entries.push_back({ + binparse::parse<Value8>(is, "flags"), + binparse::parse<Offset16>(is, "entry") + }); + } + } + + return entry; +} + +std::ostream&operator<<(std::ostream& os, const EntryTableEntry& entry) +{ + return binparse::operator<<(os, entry); +} + +}
\ No newline at end of file diff --git a/le/le_entry_table_entry.hpp b/le/le_entry_table_entry.hpp new file mode 100644 index 0000000..209c1bb --- /dev/null +++ b/le/le_entry_table_entry.hpp @@ -0,0 +1,33 @@ +#pragma once + +#include "types.hpp" + +#include <boost/variant.hpp> + +#include <vector> + +namespace le { + +using binparse::Value8; +using binparse::Value16; +using binparse::Offset16; +using binparse::Offset32; + +struct EntryPoint { + binparse::Value8 flags; + boost::variant<Offset16, Offset32> entry; +}; + +struct EntryTableEntry { + + Value8 nr_entries; + Value8 flags; + Value16 object_index; + std::vector<EntryPoint> entries; +}; + +EntryTableEntry parse_entry_table_entry(std::istream& is); + +std::ostream& operator<<(std::ostream& os, EntryTableEntry const& entry); + +} diff --git a/le/le_file.cpp b/le/le_file.cpp index 4a9f57e..b6aa54f 100644 --- a/le/le_file.cpp +++ b/le/le_file.cpp @@ -18,6 +18,9 @@ BOOST_FUSION_ADAPT_STRUCT( (std::vector<uint8_t>, dos_exe) (le::Header, le_header) (le::ObjectTable, object_table) + (le::ObjectPageTable, object_page_table) + (le::ResidentNameTable, resident_name_table) + (le::EntryTable, entry_table) ) namespace le { @@ -39,6 +42,12 @@ File parse_file(std::istream& is) { auto object_table = parse_object_table(is, le_offset + le_h.object_table_offset, le_h.nr_objects_in_module); + auto object_page_table = parse_object_page_table(is, le_offset + le_h.object_page_table_offset, le_h.module_nr_of_pages); + + auto resident_name_table = parse_resident_name_table(is, le_offset + le_h.resident_name_table_offset); + + auto entry_table = parse_entry_table(is, le_offset + le_h.entry_table_offset); + return { mz_h, unused, @@ -48,6 +57,9 @@ File parse_file(std::istream& is) { dos_exe, le_h, object_table, + object_page_table, + resident_name_table, + entry_table }; } diff --git a/le/le_file.hpp b/le/le_file.hpp index 56857c5..f66bd36 100644 --- a/le/le_file.hpp +++ b/le/le_file.hpp @@ -5,6 +5,9 @@ #include "mz_header.hpp" #include "le_header.hpp" #include "le_object_table.hpp" +#include "le_object_page_table.hpp" +#include "le_resident_name_table.hpp" +#include "le_entry_table.hpp" #include <cstdint> #include <cstddef> @@ -27,6 +30,9 @@ struct File std::vector<uint8_t> dos_exe; Header le_header; ObjectTable object_table; + ObjectPageTable object_page_table; + ResidentNameTable resident_name_table; + EntryTable entry_table; }; File parse_file(std::istream& is); diff --git a/le/le_object_page_table.cpp b/le/le_object_page_table.cpp new file mode 100644 index 0000000..d8fd290 --- /dev/null +++ b/le/le_object_page_table.cpp @@ -0,0 +1,27 @@ +#include "le_object_page_table.hpp" + +#include "parse.hpp" +#include "output.hpp" + +namespace le { + +ObjectPageTable parse_object_page_table(std::istream& is, binparse::Offset32 offset, binparse::Value32 nr_pages) +{ + is.seekg(0, std::ios::beg); + is.ignore(offset); + + ObjectPageTable table; + + for(binparse::Value32 i = binparse::Value32(0); i < nr_pages; i++) { + table.entries.emplace(i+1, parse_object_page_table_entry(is)); + } + + return table; +} + +std::ostream&operator<<(std::ostream& os, const ObjectPageTable& table) +{ + return binparse::operator<<(os, table.entries); +} + +}
\ No newline at end of file diff --git a/le/le_object_page_table.hpp b/le/le_object_page_table.hpp new file mode 100644 index 0000000..08a67e6 --- /dev/null +++ b/le/le_object_page_table.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "types.hpp" + +#include "le_object_page_table_entry.hpp" + +#include <map> + +namespace le { + +using binparse::Value32; +using binparse::Offset32; + +struct ObjectPageTable +{ + std::map<Value32, ObjectPageTableEntry> entries; +}; + +ObjectPageTable parse_object_page_table(std::istream& is, Offset32 offset, Value32 nr_pages); + +std::ostream& operator<<(std::ostream& os, ObjectPageTable const& table); + +}
\ No newline at end of file diff --git a/le/le_object_page_table_entry.cpp b/le/le_object_page_table_entry.cpp new file mode 100644 index 0000000..73bdb61 --- /dev/null +++ b/le/le_object_page_table_entry.cpp @@ -0,0 +1,27 @@ +#include "le_object_page_table_entry.hpp" + +#include "parse.hpp" +#include "output.hpp" + +#include <boost/fusion/adapted/struct.hpp> + +BOOST_FUSION_ADAPT_STRUCT( + le::ObjectPageTableEntry, + (binparse::Offset16, high_page_number) + (binparse::Value8, low_page_number) + (binparse::Value8, flags) +) + +namespace le { + +ObjectPageTableEntry parse_object_page_table_entry(std::istream& is) +{ + return binparse::parse<ObjectPageTableEntry>(is); +} + +std::ostream& operator<<(std::ostream& os, const ObjectPageTableEntry& entry) +{ + return binparse::operator<<(os, entry); +} + +}
\ No newline at end of file diff --git a/le/le_object_page_table_entry.hpp b/le/le_object_page_table_entry.hpp new file mode 100644 index 0000000..3254365 --- /dev/null +++ b/le/le_object_page_table_entry.hpp @@ -0,0 +1,28 @@ +#pragma once + +#include "types.hpp" + +namespace le { + +using binparse::Offset16; +using binparse::Value8; + +enum class object_page_flags { + legal_physical = 0, + iteration_data = 1, + invalid = 2, + zero_filled = 3, + range_of = 4 +}; + +struct ObjectPageTableEntry { + Offset16 high_page_number; + Value8 low_page_number; + Value8 flags; +}; + +ObjectPageTableEntry parse_object_page_table_entry(std::istream& is); + +std::ostream& operator<<(std::ostream& os, ObjectPageTableEntry const& entry); + +} diff --git a/le/le_object_table_entry.cpp b/le/le_object_table_entry.cpp index 92810aa..68e77ba 100644 --- a/le/le_object_table_entry.cpp +++ b/le/le_object_table_entry.cpp @@ -9,7 +9,7 @@ BOOST_FUSION_ADAPT_STRUCT( le::ObjectTableEntry, (binparse::Value32, virtual_size) (binparse::Offset32, reloc_base_address) - (binparse::Value32, ojbect_flags) + (binparse::Value32, object_flags) (binparse::Value32, page_table_index) (binparse::Value32, nr_page_table_entries) (binparse::Value32, reserved) diff --git a/le/le_object_table_entry.hpp b/le/le_object_table_entry.hpp index 7b97873..c456a15 100644 --- a/le/le_object_table_entry.hpp +++ b/le/le_object_table_entry.hpp @@ -29,7 +29,7 @@ enum class ObjectFlags { struct ObjectTableEntry { Value32 virtual_size; Offset32 reloc_base_address; - Value32 ojbect_flags; + Value32 object_flags; Value32 page_table_index; Value32 nr_page_table_entries; Value32 reserved; diff --git a/le/le_resident_name_table.cpp b/le/le_resident_name_table.cpp new file mode 100644 index 0000000..bc34999 --- /dev/null +++ b/le/le_resident_name_table.cpp @@ -0,0 +1,26 @@ +#include "le_resident_name_table.hpp" + +#include "output.hpp" + +namespace le { + +ResidentNameTable parse_resident_name_table(std::istream& is, binparse::Offset32 offset) +{ + is.seekg(0, std::ios::beg); + is.ignore(offset); + + ResidentNameTable table; + + while(is.peek()) { + table.entries.push_back(parse_resident_name_table_entry(is)); + } + + return table; +} + +std::ostream&operator<<(std::ostream& os, const ResidentNameTable& table) +{ + return binparse::operator<<(os, table.entries); +} + +} diff --git a/le/le_resident_name_table.hpp b/le/le_resident_name_table.hpp new file mode 100644 index 0000000..aa81577 --- /dev/null +++ b/le/le_resident_name_table.hpp @@ -0,0 +1,19 @@ +#pragma once + +#include "le_resident_name_table_entry.hpp" + +#include <vector> +#include <iostream> + +namespace le { + +struct ResidentNameTable { + std::vector<ResidentNameTableEntry> entries; +}; + +ResidentNameTable parse_resident_name_table(std::istream& is, binparse::Offset32 offset); + +std::ostream& operator<<(std::ostream& os, ResidentNameTable const& table); + +} + diff --git a/le/le_resident_name_table_entry.cpp b/le/le_resident_name_table_entry.cpp new file mode 100644 index 0000000..a82cbeb --- /dev/null +++ b/le/le_resident_name_table_entry.cpp @@ -0,0 +1,26 @@ +#include "le_resident_name_table_entry.hpp" + +#include "parse.hpp" +#include "output.hpp" + +#include <boost/fusion/adapted/struct.hpp> + +BOOST_FUSION_ADAPT_STRUCT( + le::ResidentNameTableEntry, + (binparse::PString8, string) + (binparse::Value16, index) +) + +namespace le { + +ResidentNameTableEntry parse_resident_name_table_entry(std::istream& is) +{ + return binparse::parse<ResidentNameTableEntry>(is); +} + +std::ostream&operator<<(std::ostream& os, ResidentNameTableEntry const& entry) +{ + return binparse::operator<<(os, entry); +} + +}
\ No newline at end of file diff --git a/le/le_resident_name_table_entry.hpp b/le/le_resident_name_table_entry.hpp new file mode 100644 index 0000000..95c83bc --- /dev/null +++ b/le/le_resident_name_table_entry.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "types.hpp" + +#include <string> + +namespace le { + +using binparse::PString8; +using binparse::Value16; + +struct ResidentNameTableEntry { + PString8 string; + Value16 index; +}; + +ResidentNameTableEntry parse_resident_name_table_entry(std::istream& is); + +std::ostream& operator<<(std::ostream& os, ResidentNameTableEntry const& entry); + +}
\ No newline at end of file |
