From 5bd1a582f9af1a27568b24f8245d4f47bbaa7f54 Mon Sep 17 00:00:00 2001 From: Redbeanw44602 Date: Sat, 1 Mar 2025 14:18:21 +0800 Subject: [PATCH] feat: complete blob-extractor. --- src/tools/blob-extractor/main.cpp | 136 +++++++++++------------------- xmake.lua | 8 +- 2 files changed, 53 insertions(+), 91 deletions(-) diff --git a/src/tools/blob-extractor/main.cpp b/src/tools/blob-extractor/main.cpp index 7e764cd..ff56590 100644 --- a/src/tools/blob-extractor/main.cpp +++ b/src/tools/blob-extractor/main.cpp @@ -1,107 +1,65 @@ +#include "data_format/magic_blob.h" -#define XXH_INLINE_ALL -#include "xxhash.h" +#include +#include -class File : public std::ifstream { -public: - using std::ifstream::basic_ifstream; +using namespace di; - template - inline T read() { - T value; - std::ifstream::read((char*)&value, sizeof(T)); - return value; - } +auto load_args(int argc, char* argv[]) { + argparse::ArgumentParser program("blob-extractor"); - template - inline T read_varint() { - T res = 0; - int shift = 0; - while (true) { - auto byte = std::ifstream::get(); - res |= static_cast(byte & 0x7F) << shift; - if ((byte & 0x80) == 0) break; - shift += 7; - } - return res; - } -}; + struct { + std::string m_magic_blob_path; + std::string m_output_path; + } args; -#define HIDWORD(x) (*((int32_t*)&(x) + 1)) + // clang-format off -uint64_t unk_hash(uint64_t a1) { - unsigned int v1; // eax - int v2; // edx - int64_t v3; // rdx + program.add_argument("magicblob") + .help("Path to magic blob.") + .store_into(args.m_magic_blob_path) + .required(); - v1 = ((33 - * ((4097 * HIDWORD(a1) + 2127912214) - ^ ((unsigned int)(4097 * HIDWORD(a1) + 2127912214) >> 19) - ^ 0xC761C23C) - + 374761393) - << 9) - ^ (33 - * ((4097 * HIDWORD(a1) + 2127912214) - ^ ((unsigned int)(4097 * HIDWORD(a1) + 2127912214) >> 19) - ^ 0xC761C23C) - - 369570787); - v2 = 33 - * ((4097 * a1 + 2127912214) - ^ ((unsigned int)(4097 * a1 + 2127912214) >> 19) ^ 0xC761C23C); - v3 = (((v2 + 374761393) << 9) ^ (v2 - 369570787)) - + 8 * (((v2 + 374761393) << 9) ^ (unsigned int)(v2 - 369570787)) - - 42973499; - return (v3 ^ (((unsigned int)v3 ^ 0xB55A4F090000uLL) >> 16)) - | ((((v1 + 8 * v1 - 42973499) & 0xFFFF0000) - ^ (((v1 + 8 * v1 - 42973499) ^ 0xFFFFFFFFB55A4F09uLL) << 16)) - << 16); + program.add_argument("--output", "-o") + .help("Path to output symlist.") + .store_into(args.m_output_path) + .required(); + + // clang-format on + + program.parse_args(argc, argv); + + return args; } -struct Entry { - std::bitset<64> flags; - uint32_t rva; - uint64_t hash; +int main(int argc, char* argv[]) try { - constexpr bool is_function() { return flags[0]; } - constexpr bool _unk2() { return flags[1]; } - constexpr bool is_verbose() { return flags[2]; } - constexpr bool _unk4() { return flags[3]; } -}; + auto args = load_args(argc, argv); -int main(int argc, char** argv) { - File data("bedrock_runtime_data", std::ios::binary); + data_format::MagicBlob blob; + blob.read(args.m_magic_blob_path); - uint32_t t_rva{}; - auto record_seed = data.read(); - auto twin_seed = unk_hash(record_seed); + nlohmann::json data; + blob.for_each([&data](hash_t hash, const MagicEntry& entry) { + data.emplace_back(nlohmann::json{ + {"hash", hash }, + {"rva", entry.rva }, + {"is_function", entry.is_function()}, + {"_unk2", entry._unk2() }, + {"is_verbose", entry.is_verbose() }, + {"_unk4", entry._unk4() } + }); + }); - std::println("Record seed: {:#x}", record_seed); - std::println("Twin seed: {:#x}", twin_seed); - - std::unordered_map map; - - while (data.peek() != EOF) { - Entry entry; - entry.flags = data.read_varint(); - entry.rva = data.read_varint(); - entry.hash = data.read(); - - t_rva += entry.rva; - entry.rva = t_rva; - - map.emplace(entry.hash, entry); - // entry.print_debug_string(); + std::ofstream ofs(args.m_output_path); + if (!ofs) { + throw std::runtime_error("Failed to open file!"); } - std::string_view test_query_name = "main"; - auto test_query_hash = - XXH64(test_query_name.data(), test_query_name.size(), twin_seed); - - if (map.contains(test_query_hash)) { - std::println("RVA of main(): {:#x}", map.at(test_query_hash).rva); - } else { - std::println("RVA of main(): INVALID."); - } + ofs << data.dump(4); return 0; +} catch (const std::exception& e) { + std::println("E: {}", e.what()); + return -1; } diff --git a/xmake.lua b/xmake.lua index b7daafd..6171117 100644 --- a/xmake.lua +++ b/xmake.lua @@ -48,14 +48,13 @@ target('libdi') add_files('src/**.cpp') set_pcxxheader('src/pch.h') + remove_files('src/tools/**') set_basename('di') add_packages( 'nlohmann_json' ) - remove_files('src/tools/**') - target('askrva') set_kind('binary') add_deps('libdi') @@ -78,6 +77,11 @@ target('blob-extractor') add_files('src/tools/blob-extractor/**.cpp') set_pcxxheader('src/pch.h') + add_packages( + 'nlohmann_json', + 'argparse' + ) + target('dumpsym') set_kind('shared') add_deps('libdi')