Here we are going to talk about files from Legend Of Silkroad (LOS) with extension *.fpk.
You can find those files in:
- Legend of Silkroad\temp: related to patch
- Legend of Silkroad\Data: related to game resources
Code: Select all
> md5sum LOS-1.1.81-to-1.1.82-patch.fpk
4efc826aba299132af5c3ea223d1e3c7 LOS-1.1.81-to-1.1.82-patch.fpk
> sha1sum LOS-1.1.81-to-1.1.82-patch.fpk
3a90a419e7653b7f05c4bd66d42e1833ef26bf04 LOS-1.1.81-to-1.1.82-patch.fpk
> ls -l LOS-1.1.81-to-1.1.82-patch.fpk
-rw-r--r-- 1 XXX XXX 2628801 Aug 28 09:23 LOS-1.1.81-to-1.1.82-patch.fpk
We look at the hexdump of first 0xE0 bytes:
Code: Select all
00000000 46 50 4b 00 d0 00 00 00 c1 00 28 1c 03 00 05 00 |FPK.......(.....|
00000010 41 00 28 19 41 00 28 1b 20 00 00 00 18 00 00 00 |A.(.A.(. .......|
00000020 00 00 00 00 00 00 00 00 00 00 00 00 c1 00 28 1c |..............(.|
00000030 00 00 00 00 5d 00 28 17 00 00 00 00 e0 00 28 16 |....].(.......(.|
00000040 00 00 00 00 00 00 00 02 00 00 00 00 80 00 00 01 |................|
00000050 00 00 00 00 00 00 00 00 00 00 00 00 6d 00 00 00 |............m...|
00000060 00 00 00 00 d4 00 00 01 00 00 00 00 00 00 00 40 |...............@|
00000070 be 81 93 2f dc 1b eb a6 7d 70 1c 1d 46 f5 9e 76 |.../....}p..F..v|
00000080 65 99 44 fe bf ff fc 47 f9 09 d8 e2 b8 d7 15 ca |e.D....G........|
00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
000000a0 7c 78 a0 b4 b9 71 ed ee f9 2e f5 88 f4 31 68 3b ||x...q.......1h;|
000000b0 ed 46 27 91 af 37 02 27 28 a4 65 d5 da 51 d3 c0 |.F'..7.'(.e..Q..|
000000c0 7a b1 94 b1 e3 ad 90 fc 9d 6c eb a9 56 3e 92 aa |z........l..V>..|
000000d0 08 00 00 00 c2 05 00 00 02 58 85 ad 57 5d 6f 1b |.........X..W]o.|
We can recognize the signature "FPK", and nothing much ... But if you are familiar
with MPQ format (http://www.zezula.net/en/mpq/mpqformat.html). You will think it's
a kind of fork.
Code: Select all
+ 0x00 : dwID
+ 0x04 : dwHeaderSize
+ 0x08 : ArchiveSize
...
But if we try to read the ArchiveSize we got 0x1C2800C1 (472383681), which is totally
different from the size's result of the command "ls" (2628801).
In fact inside the "OgreMain.dll" file you can find a C++ method called Ogre::FPKArchive::load,
if you reverse engineer this method, you will recognize lots of part of the Stormlib library (http://www.zezula.net/en/mpq/stormlib.html).
But when reading the header of the file (size 0x0D), they will swap byte 0x01 and 0x03
for each dword and patch the signature with "\x4D\x50\x51\x1A".
Pseudo C code (swap stuff):
Code: Select all
unsigned int pos;
unsigned char *buf;
unsigned char saved_byte;
buf = buf_header + 4;
pos = 0;
do
{
saved_byte = *(buf + pos + 1);
*(buf + pos + 1) = *(buf + pos + 3);
*(buf + pos + 3) = saved_byte;
pos += 4;
} while (pos < 0xCC);
Or you can use this python script to convert file directly to "patched" MPQ:
Code: Select all
FILE_NAME = "LOS-1.1.81-to-1.1.82-patch.fpk"
FILE_NAME_OUT = "TEST.MPQ"
fd_in = open(FILE_NAME, "rb")
buf = fd_in.read(0xD0)
buf = buf[4:]
buf = ''.join([(a + d + c + b) for a, b, c, d in zip(buf[0::4], buf[1::4], buf[2::4], buf[3::4])]) # swap byte 1 and 3
buf = "\x4D\x50\x51\x1A" + buf # add MPQ sig
fd_out = open(FILE_NAME_OUT, "wb")
fd_out.write(buf) # write "fixed" header
fd_out.write(fd_in.read()) # write rest of the file
fd_out.close()
fd_in.close()
You can now use MPQ editor (http://www.zezula.net/en/mpq/download.html), to extract the content of the "patched" file.
Enjoy!