feat: add blob-extractor.
This commit is contained in:
45
BlobExtractor/.clang-format
Normal file
45
BlobExtractor/.clang-format
Normal file
@@ -0,0 +1,45 @@
|
||||
BasedOnStyle: LLVM
|
||||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: BlockIndent
|
||||
AlignArrayOfStructures: Left
|
||||
AlignConsecutiveDeclarations:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignConsecutiveAssignments:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AlignCompound: true
|
||||
PadOperators: true
|
||||
AlignConsecutiveMacros:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowAllArgumentsOnNextLine: false
|
||||
AlignOperands: AlignAfterOperator
|
||||
AlignConsecutiveBitFields:
|
||||
Enabled: true
|
||||
AcrossEmptyLines: false
|
||||
AcrossComments: false
|
||||
AllowShortLambdasOnASingleLine: All
|
||||
AllowShortBlocksOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: AllIfsAndElse
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AlwaysBreakTemplateDeclarations: "Yes"
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BreakBeforeBraces: Custom
|
||||
BreakBeforeBinaryOperators: NonAssignment
|
||||
CommentPragmas: "^ IWYU pragma:"
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
IndentWidth: 4
|
||||
Language: Cpp
|
||||
MaxEmptyLinesToKeep: 2
|
||||
PackConstructorInitializers: CurrentLine
|
||||
PointerAlignment: Left
|
||||
TabWidth: 4
|
||||
UseTab: Never
|
||||
SortIncludes: CaseSensitive
|
||||
9
BlobExtractor/.gitignore
vendored
Normal file
9
BlobExtractor/.gitignore
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
# VSCode
|
||||
.vscode
|
||||
|
||||
# XMake
|
||||
.xmake
|
||||
build
|
||||
|
||||
# ClangD
|
||||
.cache
|
||||
1
BlobExtractor/README.md
Normal file
1
BlobExtractor/README.md
Normal file
@@ -0,0 +1 @@
|
||||
# BlobExtractor
|
||||
112
BlobExtractor/src/main.cpp
Normal file
112
BlobExtractor/src/main.cpp
Normal file
@@ -0,0 +1,112 @@
|
||||
#include <bitset>
|
||||
#include <cstdint>
|
||||
#include <fstream>
|
||||
#include <print>
|
||||
#include <unordered_map>
|
||||
|
||||
#define XXH_INLINE_ALL
|
||||
#include "xxhash.h"
|
||||
|
||||
class File : public std::ifstream {
|
||||
public:
|
||||
using std::ifstream::basic_ifstream;
|
||||
|
||||
template <typename T>
|
||||
inline T read() {
|
||||
T value;
|
||||
std::ifstream::read((char*)&value, sizeof(T));
|
||||
return value;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
};
|
||||
|
||||
#define HIDWORD(x) (*((int32_t*)&(x) + 1))
|
||||
|
||||
uint64_t unk_hash(uint64_t a1) {
|
||||
unsigned int v1; // eax
|
||||
int v2; // edx
|
||||
int64_t v3; // rdx
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct Entry {
|
||||
std::bitset<64> flags;
|
||||
uint32_t rva;
|
||||
uint64_t hash;
|
||||
|
||||
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]; }
|
||||
};
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
File data("bedrock_runtime_data", std::ios::binary);
|
||||
|
||||
uint32_t t_rva{};
|
||||
auto record_seed = data.read<uint64_t>();
|
||||
auto twin_seed = unk_hash(record_seed);
|
||||
|
||||
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::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.");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
14
BlobExtractor/xmake.lua
Normal file
14
BlobExtractor/xmake.lua
Normal file
@@ -0,0 +1,14 @@
|
||||
add_rules('mode.debug', 'mode.release')
|
||||
|
||||
add_requires('xxhash')
|
||||
|
||||
target('blob-extractor')
|
||||
set_kind('binary')
|
||||
add_files('src/**.cpp')
|
||||
add_includedirs('src')
|
||||
set_warnings('all')
|
||||
set_languages('c23', 'c++23')
|
||||
|
||||
if is_mode('debug') then
|
||||
add_defines('DEBUG')
|
||||
end
|
||||
Reference in New Issue
Block a user