YPF

From Game Research Wiki
Revision as of 06:04, 16 March 2015 by Orin (talk | contribs) (→‎Comments)
Jump to navigation Jump to search

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.

char lookup(char incoming)
{
	switch (incoming)
	{
	case 0x09:
		return 0x0B;
	case 0x0B:
		return 0x09;
	case 0x0C:
		return 0x10;
	case 0x10:
		return 0x0C;
	case 0x11:
		return 0x19;
	case 0x13:
		return 0x0D;
	case 0x15:
		return 0x1B;
	case 0x19:
		return 0x11;
	case 0x1b:
		return 0x15;
	case 0x1C:
		return 0x1E;
	case 0x1E:
		return 0x1C;
	case 0x20:
		return 0x23;
	case 0x23:
		return 0x20;
	case 0x26:
		return 0x29;
	case 0x29:
		return 0x26;
	case 0x2C:
		return 0x2F;
	case 0x2F:
		return 0x2C;
	default:
		return incoming;
	}
}

Example: 0xEC ^ 0xFF = 0x13 Table lookup 0x13 -> 0x0D Which means the filename length is 13.

Nothing else appears protected (file sizes and offset) however there is still a few unknown values that will need to be researched if a packing tool is to be made.

Not the most optimized method and I could still be overlooking something or not realizing something important... oh well. It works, right? ^^;