Skip to content

Commit

Permalink
Use struct for BLK header
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex committed Aug 9, 2021
1 parent fb9de91 commit 06da1c1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 40 deletions.
11 changes: 11 additions & 0 deletions blkstuff/magic_constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -692,3 +692,14 @@ static inline uint8_t gf256_mul(uint8_t a, uint8_t b)

return gf256_exp[(gf256_log[a] + gf256_log[b]) % 255];
}

#pragma pack(1)
struct blk_header
{
uint32_t magic; // "blk\0"
uint32_t version; // 0x10
uint8_t key1[16]; // Decryption key
uint8_t key2[16]; // Some other key
uint16_t block_size;
};
#pragma pack()
66 changes: 26 additions & 40 deletions blkstuff/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -318,68 +318,56 @@ void mhy0_extract(const char* out_format, int block_index, uint8_t* input, size_
}

int extract_blk(char* in_filename, const char* out_format) {
//auto* blk_file = fopen("D:\\genshinimpactre\\1.5-dev\\YuanShen_Data\\StreamingAssets\\20527480.blk", "rb");
//auto* blk_file = fopen("D:\\Games\\Genshin Impact\\Genshin Impact game\\GenshinImpact_Data\\StreamingAssets\\VideoAssets\\26236578.blk", "rb");
auto* blk_file = fopen(in_filename, "rb");

if (!blk_file) {
cout << "failed to open blk" << endl;
return 1;
}

{
uint32_t magic = 0;
fread(&magic, 4, 1, blk_file);
if (magic != 0x6B6C62) { // blk\x00
cout << "bad file magic" << endl;
return 1;
}
blk_header hdr;
bool fail = false;

if (fread(&hdr, sizeof(blk_header), 1, blk_file) < 1) {
cout << "Failed to read BLK header!" << endl;
fail = true;
}

{
uint32_t unk1 = 0;
fread(&unk1, 4, 1, blk_file);
if (unk1 != 0x10) {
cout << "unk1 is not 0x10" << endl;
return 1;
}
if (!fail && hdr.magic != 0x6B6C62) { // blk\x00
cout << "bad file magic" << endl;
fail = true;
}

if (!fail && hdr.version != 0x10) {
cout << "version is not 0x10" << endl;
fail = true;
}

if (fail) {
fclose(blk_file);
return 1;
}

uint8_t key[16] = {};
fread(key, sizeof(key), 1, blk_file);
fseek(blk_file, 16, SEEK_CUR); // skip the useless half of the key
//hexdump("encrypted blk key:", key, sizeof(key));
key_scramble1(key);
key_scramble2(key);
key_scramble1(hdr.key1);
key_scramble2(hdr.key1);
// this should also go into magic_constants.h, but it's small
// this value goes through a lot of computation to get generated, but is always the same
uint8_t hard_key[] = { 0xE3, 0xFC, 0x2D, 0x26, 0x9C, 0xC5, 0xA2, 0xEC, 0xD3, 0xF8, 0xC6, 0xD3, 0x77, 0xC2, 0x49, 0xB9 };
for (int i = 0; i < 16; i++)
key[i] ^= hard_key[i];
hdr.key1[i] ^= hard_key[i];
//hexdump("decrypted blk key:", key, sizeof(key));

uint16_t block_size = 0;
fread(&block_size, sizeof(block_size), 1, blk_file);
//cout << "0x" << hex << block_size << endl;

fseek(blk_file, 0, SEEK_END);
size_t size = ftell(blk_file);
fseek(blk_file, 0x2A, SEEK_SET); // skip xorpad size
size_t size = ftell(blk_file) - sizeof(blk_header);
fseek(blk_file, sizeof(blk_header), SEEK_SET); // skip header

auto* data = new uint8_t[size];
fread(data, size, 1, blk_file);
fclose(blk_file);

/*
uint8_t xorpad[4096] = {};
create_decrypt_vector(key, data, size, xorpad, sizeof(xorpad));
auto len = std::min((uint64_t)size, sizeof(xorpad));
for (int i = 0; i < len; i++)
data[i] ^= xorpad[i];
*/

uint8_t xorpad[4096] = {};
create_decrypt_vector(key, data, std::min((uint64_t)block_size, sizeof(xorpad)), xorpad, sizeof(xorpad));
create_decrypt_vector(hdr.key1, data, std::min((uint64_t)hdr.block_size, sizeof(xorpad)), xorpad, sizeof(xorpad));
for (int i = 0; i < size; i++)
data[i] ^= xorpad[i & 0xFFF];
//dump_to_file("decrypted.bin", data, size);
Expand All @@ -402,8 +390,6 @@ int extract_blk(char* in_filename, const char* out_format) {
}
}

//mhy0_extract(data, size);

delete[] data;

return 0;
Expand Down

0 comments on commit 06da1c1

Please sign in to comment.