Get up to member reading - but haven't made sense of it yet;
This commit is contained in:
@ -6,62 +6,281 @@
|
||||
#include <malloc.h>
|
||||
#include <math.h>
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
typedef unsigned char byte;
|
||||
typedef unsigned short uint16;
|
||||
typedef unsigned int uint32;
|
||||
typedef __int64 int64;
|
||||
|
||||
static char const* FILE_NAME = "GAMEPROGRESS.broke.blob";
|
||||
|
||||
|
||||
byte* ReadFileToBuffer(char const* filename, size_t* file_len)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
static void FlipBytes(void* data, size_t buffer_len)
|
||||
{
|
||||
byte* buffer = (byte*)data;
|
||||
size_t flip_count = buffer_len >> 1;
|
||||
for (size_t i = 0; i < flip_count; ++i) {
|
||||
std::swap(buffer[i], buffer[buffer_len - i - 1]);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
struct type_info_t
|
||||
{
|
||||
std::string name;
|
||||
size_t byte_size;
|
||||
|
||||
inline bool is_valid() const { return byte_size > 0; }
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
class BinaryReader
|
||||
{
|
||||
public:
|
||||
BinaryReader(char const* filename);
|
||||
~BinaryReader();
|
||||
|
||||
bool is_valid() const { return (nullptr != m_buffer); }
|
||||
|
||||
public: // accessors
|
||||
size_t get_byte_size() const { return m_byte_size; }
|
||||
size_t get_read_offset() const { return m_offset; }
|
||||
size_t get_bytes_remaining() const { return get_byte_size() - get_read_offset(); }
|
||||
|
||||
byte* get_read_head() const { return m_buffer + m_offset; }
|
||||
|
||||
public: // functions
|
||||
bool skip(size_t num_bytes);
|
||||
bool read_bytes(void* dst, size_t num_bytes);
|
||||
|
||||
std::string read_string();
|
||||
|
||||
template <typename T>
|
||||
T read(T const& def_value)
|
||||
{
|
||||
T val;
|
||||
if (read_bytes(&val, sizeof(T))) {
|
||||
// FlipBytes(&val, sizeof(T));
|
||||
return val;
|
||||
} else {
|
||||
return def_value;
|
||||
}
|
||||
}
|
||||
|
||||
bool read_type_info(type_info_t* out);
|
||||
|
||||
|
||||
public: // operators
|
||||
byte operator[](size_t offset) const { return m_buffer[offset]; }
|
||||
|
||||
public:
|
||||
byte* m_buffer = nullptr;
|
||||
size_t m_byte_size = 0;
|
||||
size_t m_offset = 0;
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// BinearyReader implementation
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
BinaryReader::BinaryReader(char const* filename)
|
||||
{
|
||||
FILE* fp = nullptr;
|
||||
::fopen_s(&fp, filename, "r");
|
||||
::fopen_s(&fp, filename, "rb");
|
||||
if (nullptr == fp) {
|
||||
return nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
::fseek(fp, 0, SEEK_END);
|
||||
size_t eof = ::ftell(fp);
|
||||
::fseek(fp, 0, SEEK_SET);
|
||||
|
||||
byte* buffer = (byte*) ::malloc(eof);
|
||||
if (nullptr != buffer) {
|
||||
*file_len = ::fread(buffer, 1, eof, fp);
|
||||
m_buffer = (byte*) ::malloc(eof);
|
||||
if (nullptr != m_buffer) {
|
||||
m_byte_size = ::fread(m_buffer, 1, eof, fp);
|
||||
}
|
||||
|
||||
::fclose(fp);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void DisplayProgress(byte* buffer, size_t len, size_t offset)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
BinaryReader::~BinaryReader()
|
||||
{
|
||||
size_t bytes_to_show = len - offset;
|
||||
if (nullptr != m_buffer) {
|
||||
delete m_buffer;
|
||||
m_buffer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
bool BinaryReader::skip(size_t num_bytes)
|
||||
{
|
||||
if (get_bytes_remaining() < num_bytes) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_offset += num_bytes;
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
bool BinaryReader::read_bytes(void* dst, size_t num_bytes)
|
||||
{
|
||||
byte* src = get_read_head();
|
||||
if (!skip(num_bytes)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
::memcpy(dst, src, num_bytes);
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
std::string BinaryReader::read_string()
|
||||
{
|
||||
uint32 len = read<uint32>(0);
|
||||
std::string str;
|
||||
|
||||
if (len > 0) {
|
||||
str.resize(len + 1);
|
||||
read_bytes(&str[0], len);
|
||||
str[len] = 0;
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
bool BinaryReader::read_type_info(type_info_t* out)
|
||||
{
|
||||
read<uint32>(0); // offset to next
|
||||
read_string(); // "type"
|
||||
|
||||
out->name = read_string();
|
||||
out->byte_size = read<uint32>(0);
|
||||
|
||||
return out->is_valid();
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// termination function for file reading - just prints where we left off
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
static void DisplayProgress(BinaryReader const& reader)
|
||||
{
|
||||
size_t bytes_to_show = reader.get_bytes_remaining();
|
||||
bytes_to_show = std::min<size_t>(bytes_to_show, 16);
|
||||
printf("At %u (0x%08x) into buffer... Next %u byte(s) are...\n> ", offset, offset, bytes_to_show);
|
||||
size_t offset = reader.get_read_offset();
|
||||
printf("\nAt %u (0x%08x) into buffer... Next %u byte(s) are...\n> ", offset, offset, bytes_to_show);
|
||||
for (size_t i = 0; i < bytes_to_show; ++i) {
|
||||
byte b = buffer[offset + i];
|
||||
byte b = reader[offset + i];
|
||||
printf("%02X ", b);
|
||||
}
|
||||
printf("<\n");
|
||||
}
|
||||
|
||||
static void ParseBuffer(byte* buffer, size_t len)
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// main file reading function
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
static void ParseBuffer(BinaryReader& reader)
|
||||
{
|
||||
size_t offset = 0;
|
||||
DisplayProgress(buffer, len, offset);
|
||||
}
|
||||
uint32 version = reader.read<uint32>(0);
|
||||
printf("Version: %u\n", version);
|
||||
|
||||
int main()
|
||||
{
|
||||
size_t file_len;
|
||||
byte* buffer = ReadFileToBuffer(FILE_NAME, &file_len);
|
||||
if (nullptr == buffer) {
|
||||
printf("Failed to open file.\n");
|
||||
std::string streaminfo = reader.read_string();
|
||||
printf("Label: %s\n", streaminfo.c_str());
|
||||
|
||||
uint32 unknown0 = reader.read<uint32>(0); // 0x33
|
||||
uint32 unknown1 = reader.read<uint32>(0); // 0x01
|
||||
uint32 unknown2 = reader.read<uint32>(0); // 0x00
|
||||
|
||||
// reading a type infos
|
||||
uint32 type_block_size = reader.read<uint32>(0); // 0x02f4
|
||||
std::string typelist = reader.read_string();
|
||||
uint32 type_count = reader.read<uint32>(0); // 0x1A?std::vector<type_info_t> types;
|
||||
printf("\nType List (%u total types)...\n", type_count);
|
||||
|
||||
std::vector<type_info_t> types;
|
||||
for (uint32 i = 0; i < type_count; ++i) {
|
||||
type_info_t type;
|
||||
reader.read_type_info(&type);
|
||||
|
||||
// push even bad types in to keep the index
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
ParseBuffer(buffer, file_len);
|
||||
// read class infos
|
||||
uint32 class_block_size = reader.read<uint32>(0);
|
||||
std::string classlist = reader.read_string();
|
||||
uint32 class_count = reader.read<uint32>(0);
|
||||
|
||||
free(buffer);
|
||||
printf("\n\n\n");
|
||||
printf("\nClass List (%u total classes)...\n", class_count);
|
||||
for (uint32 i = 0; i < class_count; ++i) {
|
||||
uint32 class_size = reader.read<uint32>(0); // to skip to end of this class
|
||||
std::string class_id = reader.read_string(); // "Class"
|
||||
std::string class_name = reader.read_string();
|
||||
printf("> Class: %s\n:", class_name.c_str());
|
||||
|
||||
uint32 some_count = reader.read<uint32>(0);
|
||||
std::string ver_str = reader.read_string(); // "Version"
|
||||
uint32 ver_num_maybe = reader.read<uint32>(0);
|
||||
uint32 offset_maybe = reader.read<uint32>(0);
|
||||
|
||||
std::string types_str = reader.read_string(); // "Types"
|
||||
|
||||
reader.skip(1); // 0
|
||||
uint32 mem_count = reader.read<uint32>(0); // 0x07 ?
|
||||
printf(">> member count: %u\n", mem_count);
|
||||
|
||||
for (uint32 mi = 0; mi < mem_count; ++mi) {
|
||||
uint32 type_idx = reader.read<uint32>(0); // 0x02 ?
|
||||
type_info_t const& type = types[mi];
|
||||
|
||||
std::string mem_name = reader.read_string();
|
||||
printf(">> %s : %s;\n", mem_name.c_str(), type.name.c_str());
|
||||
|
||||
// uint16 skip_to_next = reader.read<uint16>(0);
|
||||
|
||||
/*
|
||||
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<uint32>(STOP_VALUE);
|
||||
while (val != STOP_VALUE) {
|
||||
val = reader.read<uint32>(STOP_VALUE);
|
||||
}
|
||||
reader.skip(8); // usually (0, 0), or (0, -1)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DisplayProgress(reader);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
// main
|
||||
//--------------------------------------------------------------------------------------------------------
|
||||
int main()
|
||||
{
|
||||
BinaryReader reader(FILE_NAME);
|
||||
if (reader.is_valid()) {
|
||||
ParseBuffer(reader);
|
||||
}
|
||||
|
||||
printf("\n\n\nPress Any Key...\n");
|
||||
_getch();
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user