Closed dtlnor closed 2 years ago
Code to look at
https://github.com/wwylele/mhrice/blob/8a162889ef22096628198a829308936295c62835/src/pak.rs#L144-L159
ummm, maybe because I'm not familiar to rust, I can't figure out why it report err and how to fix it. during the process, I got these err message:
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: Unknown frame descriptor', src/main.rs:653:49
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: invalid block code', src/main.rs:653:49
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: invalid static size', src/main.rs:653:49
thread '<unnamed>' panicked at 'called `Result::unwrap()` on an `Err` value: huffman tree too large', src/main.rs:653:49
For the pak format, it seems remain the same as switch version, 0 for uncompress, 1 for deflate, 2 for zstd
Edit: ah, I get what you mean now. I am trying to look at it
edit: there are some file has a special flag which casue ERR. Those file has a flag like 02 00 01 00 00 00 00 00
,
While other files are just fine to decode in deflate or zstd
index:2412, Offset:980358075, flag:02-01
index:3777, Offset:980041051, flag:02-01
index:4084, Offset:985410023, flag:02-01
index:5189, Offset:985331799, flag:02-01
index:7295, Offset:979554907, flag:02-01
index:7874, Offset:979913915, flag:02-01
index:9305, Offset:979843883, flag:02-01
index:9320, Offset:980216971, flag:02-01
index:9926, Offset:985285839, flag:01-01
index:10739, Offset:985135007, flag:02-01
index:10893, Offset:980072035, flag:02-01
index:11833, Offset:980161787, flag:02-01
index:12813, Offset:980185219, flag:02-01
index:13474, Offset:979700355, flag:02-01
index:14089, Offset:979759763, flag:02-01
index:14836, Offset:979884467, flag:02-01
index:15871, Offset:980405707, flag:02-01
index:17621, Offset:985247919, flag:02-01
index:17923, Offset:985056023, flag:02-01
index:20715, Offset:979631731, flag:02-01
index:20777, Offset:979579875, flag:02-01
index:21134, Offset:985356767, flag:01-01
index:21146, Offset:979612779, flag:02-01
index:21456, Offset:979730187, flag:02-01
index:22296, Offset:980001875, flag:02-01
index:23793, Offset:985462135, flag:02-01
index:23904, Offset:980103275, flag:02-01
index:24150, Offset:980132083, flag:02-01
index:24556, Offset:980335667, flag:02-01
index:25116, Offset:979941827, flag:02-01
index:27777, Offset:979786267, flag:02-01
index:28275, Offset:979661307, flag:02-01
index:28582, Offset:980287779, flag:02-01
index:28987, Offset:980311979, flag:02-01
index:30731, Offset:985269311, flag:01-01
index:34248, Offset:980263323, flag:02-01
index:34898, Offset:985438575, flag:02-01
index:34947, Offset:985257655, flag:02-01
index:36916, Offset:980240019, flag:02-01
index:37388, Offset:985271367, flag:02-01
index:37669, Offset:979970123, flag:02-01
index:38773, Offset:1034348893, flag:01-01
index:38845, Offset:985212199, flag:02-01
index:38850, Offset:980381635, flag:02-01
index:39769, Offset:979814179, flag:02-01
This is either a variant of zstd, or a different compression method...
So I am getting back to this. This actually looks more like a encryption layer...
Just to keep you up to date with what we've found, this is almost definitely an encryption layer. The encrypted paks store their key using the same method (the 128 bytes following the table of contents becomes the 32 byte key). Once the files are decrypted, they're regular zstd (confirmed looking at it in memory).
To add to that: The 32-byte key (recovered from the 128bytes) is a SHA3 hash of the unencrypted TOC data.
I believe the first initial function of it is at MonsterHunterRise.exe+2C638D0.
Thank you for the information. Are you saying that the encryption key/algorithm for the individual files is the same as the one for the content table at the beginning of the pak file?
No, the key for the pak file is stored in the same "obfuscated" format as the individual files (it takes 128 bytes and produces a 32 byte output from that somehow). So solving one will solve both.
Oh I see. That's good to know. Are they also using the same algorithm (the decryption algorithm using a known key), though?
The individual files are not encrypted, just "obfuscated" through this method. The resulting data from it is a valid zstd/deflate stream.
I kinda doubt you want a Windows only black-box dependency in mhrice, but I feel like I should mentioned that I've isolated the decryption functionality and have it building with masm on Windows, wrapped in a small DLL: https://github.com/Andoryuuta/MHRPakDecrypt
haha, I was thinking about this kind of solution just now. Thank you for providing this.
The CRYPTO_HASH_KEY_0 "01h, 00h, 01h" (0x10001) reminds me of the common RSA public key exponent. If this is RSA-like, the other CRYPTO_HASH_KEY_1 would be the modulus part of the public key. Could this be RSA algorithm?
OK yep, this is a bare bone RSA. To recover the key, you just plug in your favorite big int library, and compute
key = pow(the_128_byte_after_TOC, CRYPTO_HASH_KEY_0) % CRYPTO_HASH_KEY_1;
And as for individual sub files, the decryption procedure seems to be like
d = b / (pow(a, e) % m)
. Here e and m are two byte sequences that can be dumped from the memory.Should be fixed in https://github.com/wwylele/mhrice/commit/9d927ad8044b512fdba45bc04240338304a43cfc . I will close this once I verify path searching works
when I do path search, it panic (WSL ubuntu)