feat: complete blob-extractor.

This commit is contained in:
2025-03-01 14:18:21 +08:00
parent f5cd2cd886
commit 5bd1a582f9
2 changed files with 53 additions and 91 deletions

View File

@@ -1,107 +1,65 @@
#include "data_format/magic_blob.h"
#define XXH_INLINE_ALL
#include "xxhash.h"
#include <argparse/argparse.hpp>
#include <nlohmann/json.hpp>
class File : public std::ifstream {
public:
using std::ifstream::basic_ifstream;
using namespace di;
template <typename T>
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 <std::unsigned_integral T>
inline T read_varint() {
T res = 0;
int shift = 0;
while (true) {
auto byte = std::ifstream::get();
res |= static_cast<T>(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<uint64_t>();
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<uint64_t, Entry> map;
while (data.peek() != EOF) {
Entry entry;
entry.flags = data.read_varint<uint64_t>();
entry.rva = data.read_varint<uint32_t>();
entry.hash = data.read<uint64_t>();
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;
}

View File

@@ -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')