summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDennis Brentjes <d.brentjes@gmail.com>2016-06-23 18:07:42 +0200
committerDennis Brentjes <d.brentjes@gmail.com>2016-06-23 18:07:42 +0200
commita7bcede17b4c10e172c7877fc2ce89862dc454af (patch)
treed89b8ff274d18d67d695c5f320a1d079e1bb26b6
parent0f2d7c9ed9dfa3716840fc112bd53e5ec6b6315b (diff)
downloadopenwar-a7bcede17b4c10e172c7877fc2ce89862dc454af.tar.gz
openwar-a7bcede17b4c10e172c7877fc2ce89862dc454af.tar.bz2
openwar-a7bcede17b4c10e172c7877fc2ce89862dc454af.zip
adds alot more binary parsing.
-rw-r--r--binparse/otreestream.hpp7
-rw-r--r--binparse/output.cpp5
-rw-r--r--binparse/output.hpp26
-rw-r--r--binparse/parse.cpp8
-rw-r--r--binparse/parse.hpp4
-rw-r--r--binparse/types.hpp2
-rw-r--r--le/CMakeLists.txt6
-rw-r--r--le/le_entry_table.cpp27
-rw-r--r--le/le_entry_table.hpp19
-rw-r--r--le/le_entry_table_entry.cpp55
-rw-r--r--le/le_entry_table_entry.hpp33
-rw-r--r--le/le_file.cpp12
-rw-r--r--le/le_file.hpp6
-rw-r--r--le/le_object_page_table.cpp27
-rw-r--r--le/le_object_page_table.hpp23
-rw-r--r--le/le_object_page_table_entry.cpp27
-rw-r--r--le/le_object_page_table_entry.hpp28
-rw-r--r--le/le_object_table_entry.cpp2
-rw-r--r--le/le_object_table_entry.hpp2
-rw-r--r--le/le_resident_name_table.cpp26
-rw-r--r--le/le_resident_name_table.hpp19
-rw-r--r--le/le_resident_name_table_entry.cpp26
-rw-r--r--le/le_resident_name_table_entry.hpp21
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