From ff5d48c471c6fbf3e8a68519acd3a37396c4f7b0 Mon Sep 17 00:00:00 2001 From: "Chris Forseth (C4)" Date: Thu, 19 May 2022 10:50:32 -0500 Subject: [PATCH] Start reading out sections; Fixed an error in how I was calculating section offets (its an offset from the head BEFORE the read of the offset) --- LegoBlobReader/LegoBlobReader.cpp | 146 +++++++++++++++++++++--------- 1 file changed, 105 insertions(+), 41 deletions(-) diff --git a/LegoBlobReader/LegoBlobReader.cpp b/LegoBlobReader/LegoBlobReader.cpp index ce3558f..06a4f2c 100644 --- a/LegoBlobReader/LegoBlobReader.cpp +++ b/LegoBlobReader/LegoBlobReader.cpp @@ -14,7 +14,8 @@ typedef unsigned short uint16; typedef unsigned int uint32; typedef __int64 int64; -static char const* FILE_NAME = "GAMEPROGRESS.broke.blob"; +static char const* FILE_NAME = "GAMEPROGRESS.BLOB"; + //-------------------------------------------------------------------------------------------------------- @@ -36,6 +37,28 @@ struct type_info_t inline bool is_valid() const { return byte_size > 0; } }; +//-------------------------------------------------------------------------------------------------------- +struct class_member_info_t +{ + std::string name; + type_info_t const* type; +}; + +//-------------------------------------------------------------------------------------------------------- +struct class_info_t +{ + std::string name; + + std::vector members; +}; + +//-------------------------------------------------------------------------------------------------------- +// Globals +//-------------------------------------------------------------------------------------------------------- + +std::vector Types; +std::vector Classes; + //-------------------------------------------------------------------------------------------------------- //-------------------------------------------------------------------------------------------------------- class BinaryReader @@ -45,6 +68,7 @@ class BinaryReader ~BinaryReader(); bool is_valid() const { return (nullptr != m_buffer); } + bool is_finished() const { return m_offset >= m_byte_size; } public: // accessors size_t get_byte_size() const { return m_byte_size; } @@ -53,6 +77,8 @@ class BinaryReader byte* get_read_head() const { return m_buffer + m_offset; } + void set_read_offset(size_t offset) { m_offset = offset; } + public: // functions bool skip(size_t num_bytes); bool read_bytes(void* dst, size_t num_bytes); @@ -167,6 +193,7 @@ bool BinaryReader::read_type_info(type_info_t* out) } + //-------------------------------------------------------------------------------------------------------- // termination function for file reading - just prints where we left off //-------------------------------------------------------------------------------------------------------- @@ -184,52 +211,47 @@ static void DisplayProgress(BinaryReader const& reader) } //-------------------------------------------------------------------------------------------------------- -// main file reading function //-------------------------------------------------------------------------------------------------------- -static void ParseBuffer(BinaryReader& reader) +static void ParseTypes(BinaryReader& reader) { - uint32 version = reader.read(0); - printf("Version: %u\n", version); - - std::string streaminfo = reader.read_string(); - printf("Label: %s\n", streaminfo.c_str()); - - uint32 unknown0 = reader.read(0); // 0x33 - uint32 unknown1 = reader.read(0); // 0x01 - uint32 unknown2 = reader.read(0); // 0x00 - - // reading a type infos uint32 type_block_size = reader.read(0); // 0x02f4 std::string typelist = reader.read_string(); uint32 type_count = reader.read(0); // 0x1A?std::vector types; printf("\n======\nType List (%u total types)...\n", type_count); - std::vector types; + for (uint32 i = 0; i < type_count; ++i) { - type_info_t type; - reader.read_type_info(&type); - + type_info_t type; + reader.read_type_info(&type); + // push even bad types in to keep the index - types.push_back(type); + Types.push_back(type); if (type.is_valid()) { printf("> Type [%02u]: %s (%u B)\n", i, type.name.c_str(), type.byte_size); - } else { - printf("> Type [%02u]: REDACTED\n", i); + } + else { + printf("> Type [%02u]: REDACTED\n", i); } } +} - // read class infos - uint32 class_block_size = reader.read(0); - uint32 end_of_class = reader.get_read_offset() + class_block_size; - std::string classlist = reader.read_string(); - uint32 class_count = reader.read(0); +//-------------------------------------------------------------------------------------------------------- +//-------------------------------------------------------------------------------------------------------- +static void ParseClasses(BinaryReader& reader) +{ + uint32 class_block_size = reader.read(0); + uint32 end_of_class = reader.get_read_offset() + class_block_size - sizeof(uint32); + std::string classlist = reader.read_string(); + uint32 class_count = reader.read(0); - printf("\n======\nClass List (%u total classes)...\n", class_count); + printf("\n======\nClass List (%u total classes)...\n", class_count); for (uint32 i = 0; i < class_count; ++i) { + class_info_t class_info; + uint32 class_size = reader.read(0); // to skip to end of this class std::string class_id = reader.read_string(); // "Class" - std::string class_name = reader.read_string(); - printf("\n> Class: %s\n:", class_name.c_str()); + class_info.name = reader.read_string(); + printf("\n> Class: %s\n:", class_info.name.c_str()); uint32 some_count = reader.read(0); std::string ver_str = reader.read_string(); // "Version" @@ -244,25 +266,30 @@ static void ParseBuffer(BinaryReader& reader) for (uint32 mi = 0; mi < mem_count; ++mi) { uint32 type_idx = reader.read(0); // 0x02 ? - type_info_t const& type = types[type_idx]; + type_info_t const& type = Types[type_idx]; - std::string mem_name = reader.read_string(); - printf(">> %s : %s;\n", mem_name.c_str(), type.name.c_str()); + std::string mem_name = reader.read_string(); + printf(">> %s : %s;\n", mem_name.c_str(), type.name.c_str()); + + class_member_info_t mem_info; + mem_info.name = mem_name; + mem_info.type = &type; + class_info.members.push_back(mem_info); // uint16 skip_to_next = reader.read(0); - + /* - uint32 type_size = type.byte_size; + uint32 type_size = type.byte_size; if (type_size != ~0U) { reader.skip(type_size); // def value - based on type } */ /* - uint32 const STOP_VALUE = 0x80'00'00'00; - uint32 val = reader.read(STOP_VALUE); + uint32 const STOP_VALUE = 0x80'00'00'00; + uint32 val = reader.read(STOP_VALUE); while (val != STOP_VALUE) { - val = reader.read(STOP_VALUE); + val = reader.read(STOP_VALUE); } */ @@ -272,16 +299,53 @@ static void ParseBuffer(BinaryReader& reader) uint32 v3 = reader.read(0); uint32 v4 = reader.read(0); - printf(" %08X %08X %08X %08X %08X (%s)\n", v0, v1, v2, v3, v4, type.name.c_str()); + printf(" %08X %08X %08X %08X %08X (%s)\n", v0, v1, v2, v3, v4, type.name.c_str()); + + Classes.push_back(class_info); } } +} - uint32 end_of_classes = reader.read(0); // 1? Not sure what this is, but need it to match the offset the class block - // if this was the start of another class - it would be the class size, which I take to mean '1' means stop +//-------------------------------------------------------------------------------------------------------- +// main file reading function +//-------------------------------------------------------------------------------------------------------- +static void ParseBuffer(BinaryReader& reader) +{ + uint32 version = reader.read(0); + printf("Version: %u\n", version); - printf("\n\n-=-=-=-=-\nSANITY - %u == %u\n-=-=-=-=-\n\n", reader.get_read_offset(), end_of_class); + std::string streaminfo = reader.read_string(); + printf("Label: %s\n", streaminfo.c_str()); + + uint32 unknown0 = reader.read(0); // 0x33 + uint32 unknown1 = reader.read(0); // 0x01 + uint32 unknown2 = reader.read(0); // 0x00 + ParseTypes(reader); + ParseClasses(reader); + // print the sections + printf("\n\n\n----------------------------\nReading Sections\n----------------------------\n"); + size_t num_sections = reader.read(0); + size_t sections_read = 0; + while (!reader.is_finished()) + { + uint32 section_len = reader.read(0); + if (section_len == 0) { + break; + } + + uint32 end_of_section = reader.get_read_offset() - sizeof(uint32) + section_len; + std::string section_name = reader.read_string(); // "OLST" + ++sections_read; + + printf("Section '%s' at 0x%08x.\n", section_name.c_str(), end_of_section - section_len); + + reader.set_read_offset(end_of_section); // this is taking me past the end by 4; + } + printf("\nRead %u out of %u sections.", sections_read, num_sections); + + printf("\n\n"); DisplayProgress(reader); }