YPF
Used in the following games:
- Eroge! ~Sex and Games Make Sexy Games~
Structure
Header | ||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Size | Content | Description | ||||||||||||
4Bytes | Magic/ID | "YPF/0" | ||||||||||||
4Bytes | Unknown1 | Static? | ||||||||||||
4Bytes | File Count | Number of Files in archive | ||||||||||||
4Bytes | Index Size | Size of Index | ||||||||||||
16Bytes | Padding | |||||||||||||
Index Entry | ||||||||||||||
Size | Content | Description | ||||||||||||
4Bytes | Unknown1 | |||||||||||||
1Bytes | Filename Length | XOR 0xFF, then table lookup. | ||||||||||||
?Bytes | Filename | XOR 0xFF then XOR 0x40 | ||||||||||||
2Bytes | Unknown2 | Static? | ||||||||||||
4Bytes | FileSize1 | |||||||||||||
4Bytes | FileSize2 | Suggests compression is supported | ||||||||||||
4Bytes | File Offset | |||||||||||||
4Bytes | Unknown3 |
Comments
To decode the filenames, each byte in the filename is XOR by 0xFF and then 0x40. However, the filenames are not null terminated so 1 byte is stored before the filename that represents the the filename's length. This value is protected like the filename but is slightly different (as far as I can tell). XOR by 0xFF and then do a table lookup. The table is generated at runtime and swaps around 38 values in the table.
unsigned char test[0xFF],
eax, ecx, edx;
for (int a = 0; a < 255; a++)
{
test[a] = a;
}
edx = test[0x09];
eax = test[0x0B];
test[0x09] = eax;
test[0x0B] = edx;
eax = test[0x0C];
ecx = test[0x10];
test[0x0C] = ecx;
test[0x10] = eax;
edx = test[0x0D];
eax = test[0x13];
test[0x0D] = eax;
test[0x13] = edx;
edx = test[0x11];
eax = test[0x19];
test[0x11] = eax;
test[0x19] = edx;
edx = test[0x15];
eax = test[0x1B];
test[0x15] = eax;
test[0x1B] = edx;
edx = test[0x1C];
eax = test[0x1E];
test[0x1C] = eax;
test[0x1E] = edx;
edx = test[0x20];
eax = test[0x23];
test[0x20] = eax;
test[0x23] = edx;
edx = test[0x26];
eax = test[0x29];
test[0x26] = eax;
test[0x29] = edx;
edx = test[0x2C];
eax = test[0x0F];
test[0x2C] = eax;
test[0x2F] = edx;
edx = test[0x2E];
eax = test[0x32];
Example: 0xEC ^ 0xFF = 0x13 Table lookup 0x13 -> 0x0D Which means the filename length is 13.