(for archives in full version of ef) most of the first 32 bytes seems to be garbage (but i'm not sure), but you want to notice the byte at 0x08, that's the byte you'll be xoring with before you get to BlowfishDecrypt.
so, you'd:
> read in the first 32 bytes in the archive, save the byte at offset 0x08, and then dump the rest of them
> xor this "key byte" with a 4-byte integer at offset 0x20, and that's the length of index
> read in the index, xor it with the "key byte", then BlowfishDecrypt it with the first set of Blowfish key. now you've got the index ready to use
> to extract files from the rest of the archive, xor with the "key byte" first and then BlowfishDecrypt.
just to mention that, in full version of ef, the initialization of pbox is somehow different from standard Blowfish and from ef_trial. in ef_trial, you have to negate every key byte before it's used in an otherwise standard Blowfish init.
so if you had a standard implementation of Blowfish, in ef_trial you'd: (in pseudo code)
negateAllBytes(key1);
BlowfishInit(key1);
now in full version you have to do something tricky, so let's get more into the details of what would be a part of BlowfishInit. the code snippet below should replace the round of xoring pbox with the key for Blowfish: (in C++)
suppose:
unsigned int pbox[18]; // the pbox of Blowfish
byte* key; // pointer to the key for Blowfish, and that the length of key is always 0x20 in minori's games
then,
- unsigned int ofs = 0; // offset of current byte in key
- for (int i = 0; i < 18; ++i) { // iterate though pbox
- unsigned int build = 0;
- for (int j = 0; j < 4; ++j) { // retrieve 4 bytes from the key at a time
- byte currentByte = key[ofs];
- /////////////////////////////////////////////////////////////
- // this switch is what's different from the standard Blowfish
- switch (ofs % 6) {
- case 0:
- currentByte ^= 0x6D;
- break;
- case 1: case 5:
- currentByte ^= 0x69;
- break;
- case 2:
- currentByte ^= 0x6E;
- break;
- case 3:
- currentByte ^= 0x6F;
- break;
- case 4:
- currentByte ^= 0x72;
- break;
- }
- /////////////////////////////////////////////////////////////
- build <<= 8;
- build |= currentByte;
- ofs++;
- ofs &= 31; // ensure ofs doesn't go beyond 0x20
- }
- pbox[i] ^= build;
- }
and that's about it...