[Tutorial] Unpacking the pak

Results 1 to 1 of 1
  1. #1
    Proficient Member StingerOne is offline
    MemberRank
    Aug 2021 Join Date
    AltgardLocation
    160Posts

    cool [Tutorial] Unpacking the pak

    Overview
    In this tutorial, we'll be taking a look at how to extract data from a CryPak file in the Aion Online game directory. This post will only include theory about how this can be accomplished, there will be no code implementations in this unfortunately. This document will be broken up into multiple sections, the sub sections are as follows:

    • Datatypes
    • Footer
    • External Headers
    • Internal Headers
    • Decoding
    • Decompression
    • Links

    Datatypes
    The datatypes you will need are int16 and int32 and a byte array, in most high level languages this will simply be a byte[] or in low languages like C or C++ this will be a char * bytes;

    There are 8 bits in a byte.

    int16 can hold 2 bytes
    int32 can hold 4 bytes

    When reading an int16 and an int32 from the buffer, you will read 2 and 4 bytes respectively.

    Footer

    The footer is the main entry point of the .pak file, this is what you will read first, it is exactly 22 bytes long and it's located at the bottom of the file. You can calculate the start of the footer by taking the length of the data and minus 22. for eg. 1024 bytes is the pak size, 1024 - 22 = 1002 is the start of the footer.

    here is what's in the footer:

    • int16 - first signature
    • int16 - second signature
    • int16 - number of disks
    • int16 - first disk number
    • int16 - current disk file count
    • int16 - total disk file count
    • int32 - file count
    • int32 - offset for the start of external headers.
    • int16 - unknown

    You can check if the footer is valid by comparing the signatures. The first signature should equal 0xB4AF and the second signature should equal 0xF9FA If those previous signatures fail, you can then check against 0x4B50 and 0x0605 respectively.
    If those fail as well, the footer is incorrect.

    External Headers

    The external header gives information about the file such as when it was created, file signatures, compressed and uncompressed size etc.. You typically only need a few values from this but I will list all the data anyway.

    Here is what's in the external header:

    • int16 - first signature
    • int16 - second signature
    • int16 - version when created
    • int16 - version when extracted
    • int16 - unknown
    • int16 - whether this data is compressed or not (0 = uncompressed, 8 = compressed)
    • int16 - time when created
    • int16 - date when created
    • int32 - unknown
    • int32 - compressed size in bytes
    • int32 - uncompressed size in bytes
    • int16 - file name length in bytes
    • int16 - unknown
    • int16 - unknown
    • int16 - disk number for this file
    • int16 - unknown
    • int32 - unknown
    • int32 - internal header offset

    The length of the external header not including the file name length is 46 bytes.

    There is one external and one internal header for each file in the .pak.
    The file name is X amount of bytes directly after the internal header offset. Use the file name length to determine the length of bytes to read.

    You can check if the header is valid by comparing the signatures. The first signature should equal 0xB4AF and the second signature should equal 0xF9FA If those previous signatures fail, you can then check against 0x4B50 and 0x0605 respectively.
    If those fail as well, the header is incorrect.

    Internal Headers

    The internal header is the final header to read before reaching the the file data and the information contained in this one is similar to what is in the external header.

    Here is what's in the internal header:

    • int16 - first signature
    • int16 - second signature
    • int16 - version when extracted
    • int16 - unknown
    • int16 - whether this data is compressed or not (0 = uncompressed, 8 = compressed)
    • int16 - time when created
    • int16 - date when created
    • int32 - unknown
    • int32 - compressed size in bytes
    • int32 - uncompressed size in bytes
    • int16 - file name length
    • int16 - unknown

    The size of the header not including the file name length is 30 bytes. The start of the compressed or uncompressed data is after the file name at the end of this header.

    You can check if the header is valid by comparing the signatures. The first signature should equal 0xB4AF and the second signature should equal 0xF9FA If those previous signatures fail, you can then check against 0x4B50 and 0x0605 respectively.
    If those fail as well, the header is incorrect.


    Decoding

    Once you have the data from the end of the internal header, you will need to decode the first 32 bytes or if the file length is < 32 you will need to decode all the data.

    First you will need an offset, this is equal to the external header compressed size bitwise AND with 0x3FF

    For each of the first 32 bytes you need to bitwise XOR the byte with a constant from the table below. The index is the previous offset you calculated with 0x3FF + the current index.

    This is the decode values, you can store them in an array or some other storage mechanism.

    Code:
    0x86, 0xFA, 0x1A, 0x1C, 0x07, 0xBD, 0xD8, 0x64,0xCE, 0xEE, 0x59, 0x88, 0xCD,0xA9, 0x1D, 0x06, 0xF7, 0x3D,
    0x31, 0x58, 0x83, 0xA1, 0x5C,0x7E, 0xDF, 0xA6, 0x50, 0x9E,0x89, 0xA8, 0x12, 0xD2, 0x25,0x49, 0x75, 0xE2, 0x07, 0x0F,
    0xEB, 0x01, 0x97, 0x4A, 0x66,0x35, 0xAB, 0x32, 0x9D, 0xA7,0x4E, 0xA2, 0x89, 0x62, 0x0F,0x55, 0x41, 0xC5, 0x52, 0x10,
    0x1F, 0x47, 0xB0, 0xA0, 0x63,0xA6, 0xF0, 0x1C, 0x1C, 0x4C,0x9B, 0x3C, 0xAC, 0xE2, 0xB3,0x4E, 0x9F, 0xF1, 0xA4, 0x91,
    0x29, 0x82, 0xE4, 0x76, 0x0D,0x8D, 0x4F, 0xA3, 0x34, 0x4A,0xCC, 0x1C, 0xC7, 0x18, 0x48,0x8E, 0xFE, 0x18, 0x79, 0x08,
    0x87, 0x28, 0x8E, 0x24, 0xB7,0x6B, 0x38, 0xF2, 0x58, 0x01,0x2D, 0xA8, 0x58, 0x0E, 0x9C,0x54, 0x29, 0xCF, 0xA1, 0xAE,
    0x0A, 0xD2, 0x3B, 0x4A, 0x10,0xF8, 0xD8, 0x19, 0x31, 0x7D,0xF3, 0xAE, 0x1B, 0x90, 0xD2,0x2F, 0x16, 0xC7, 0xE5, 0x3B,
    0xCC, 0xEF, 0xE1, 0xE1, 0x2C,0x86, 0x00, 0xDD, 0x35, 0x67,0x8D, 0x25, 0xFC, 0xED, 0x32,0x1F, 0xA9, 0x1A, 0x12, 0x6D,
    0xB0, 0xF7, 0x3D, 0xB6, 0x1F,0xE8, 0x81, 0x4D, 0x36, 0xE7,0x25, 0x30, 0x21, 0x90, 0x86,0x30, 0x0E, 0xEE, 0x40, 0xBE,
    0x6E, 0xDA, 0xC1, 0x3A, 0xAF,0xF2, 0xEC, 0x28, 0x2C, 0xF1,0xCD, 0x44, 0x98, 0x72, 0xDA,0xCD, 0xC6, 0xD9, 0xDF, 0xF7,
    0xEE, 0x88, 0x04, 0xE1, 0x62,0x00, 0x08, 0x0E, 0xCD, 0x16,0x37, 0xAB, 0xF9, 0xF5, 0x14,0xAA, 0x2E, 0x00, 0x4E, 0xF8,
    0x18, 0x41, 0x0B, 0xD9, 0x6F,0x9B, 0xFA, 0xAD, 0x2B, 0x54,0x56, 0x2E, 0x7F, 0x2C, 0x3B,0x6A, 0x82, 0xA1, 0x7C, 0x7C,
    0xA6, 0x8F, 0x66, 0x5E, 0xE7,0xCF, 0x83, 0xB9, 0xEA, 0xFC,0xE2, 0x31, 0xD4, 0x10, 0xF3,0xF4, 0x22, 0xEC, 0x73, 0x14,
    0x4F, 0x94, 0x78, 0x79, 0x8F,0x1E, 0x29, 0xEA, 0x5F, 0x21,0x1E, 0x08, 0x37, 0xB8, 0xF6,0x9A, 0x2D, 0xC5, 0x36, 0x34,
    0xC1, 0x97, 0xDC, 0x75, 0xB2,0xAD, 0xD7, 0xE3, 0x04, 0xA7,0xC0, 0xC9, 0x1C, 0x1A, 0x00,0xE9, 0x2D, 0x6F, 0xD6, 0x8D,
    0xBC, 0x73, 0x52, 0xC0, 0x8A,0xB6, 0xBA, 0x2C, 0xA6, 0x7D,0x7B, 0x6F, 0xF4, 0x47, 0x1A,0x72, 0xE9, 0xB2, 0x30, 0x7D,
    0xD4, 0xD3, 0x09, 0x9C, 0x65,0xB0, 0xD0, 0x17, 0xCF, 0xFC,0xF2, 0xFF, 0x46, 0xD2, 0xA6,0x43, 0x11, 0x76, 0x2B, 0xE5,
    0x1D, 0xE5, 0xC9, 0x47, 0x2F,0x4B, 0x1B, 0xDD, 0x9A, 0xFD,0x9D, 0x20, 0xB6, 0x43, 0x1A,0x64, 0xE3, 0x68, 0xF3, 0x21,
    0x57, 0x68, 0xD4, 0x04, 0x8F,0xC3, 0xCE, 0xAF, 0xA3, 0xAB,0x69, 0xA3, 0x3C, 0x34, 0xBE,0x1F, 0x84, 0xA8, 0x0E, 0x74,
    0xCB, 0xB7, 0xE6, 0xB1, 0x39,0x8D, 0x68, 0x00, 0x3A, 0x9B,0x9C, 0xB1, 0x09, 0x1C, 0x7D,0x52, 0x15, 0x12, 0xA6, 0xB0,
    0x83, 0xD3, 0x40, 0x47, 0x9B,0xE4, 0x22, 0xE3, 0x6E, 0x30,0xC4, 0xFC, 0x6F, 0x4F, 0xFE,0x9F, 0x51, 0x14, 0x13, 0x57,
    0xF1, 0xEB, 0x25, 0xF7, 0x95,0x4C, 0x92, 0xB6, 0x3C, 0xD0,0x34, 0x79, 0x59, 0x33, 0x20,0xBE, 0xB8, 0xBF, 0xE0, 0x0A,
    0xD2, 0x77, 0xBC, 0x43, 0x5C,0x7D, 0xFC, 0xE1, 0x59, 0x00,0xDE, 0x5A, 0x7D, 0x44, 0x11,0xAC, 0x13, 0xF2, 0x64, 0x84,
    0x4F, 0x5D, 0xA2, 0xC4, 0x36,0xD7, 0x23, 0xFA, 0xF8, 0xD1,0x14, 0x8D, 0xF9, 0xDD, 0x17,0x1D, 0x52, 0x41, 0x22, 0xF5,
    0x1A, 0x42, 0x39, 0xFE, 0x36,0xD5, 0x0A, 0x10, 0x01, 0xD2,0xEA, 0x12, 0x82, 0x5A, 0x48,0xD2, 0x94, 0x95, 0x0A, 0xF7,
    0xAB, 0x70, 0xF7, 0xF2, 0x98,0x89, 0xA1, 0x68, 0xF9, 0xE1,0xD6, 0xE1, 0xBD, 0x92, 0x38,0x45, 0x5F, 0x19, 0xE2, 0xEA,
    0x46, 0x76, 0xC5, 0xC3, 0xF2,0xB4, 0x9F, 0x70, 0x53, 0x09,0x3F, 0xB8, 0x06, 0x3A, 0xF3,0x46, 0xC8, 0x6A, 0xCD, 0x0A,
    0xE3, 0xF0, 0xAA, 0x34, 0xD9,0x72, 0x98, 0x34, 0x23, 0xD1,0x96, 0x8C, 0x32, 0x32, 0x3B,0x00, 0xA3, 0x9E, 0x4F, 0xED,
    0xBC, 0x97, 0xD4, 0x4A, 0x26,0x15, 0x96, 0x1D, 0x0E, 0x36,0xB8, 0xEE, 0x86, 0x45, 0x57,0x04, 0x6D, 0x2B, 0xC0, 0xDB,
    0x91, 0x0A, 0x46, 0xCE, 0x7C,0x1F, 0x3C, 0x3A, 0x81, 0x94,0x22, 0x26, 0x82, 0x6D, 0x83,0xBD, 0x13, 0x2D, 0x96, 0x91,
    0x53, 0x6C, 0x26, 0x0C, 0x44,0xFE, 0xBD, 0xEE, 0xDA, 0xCC,0xBD, 0x52, 0xA6, 0x11, 0x3E,0x10, 0x42, 0x20, 0x60, 0xEB,
    0x5F, 0x5B, 0x0D, 0x7C, 0xBB,0x80, 0xAC, 0x2F, 0xB9, 0xF9,0xD2, 0x4A, 0xEB, 0x54, 0x80,0x60, 0x62, 0x85, 0xE5, 0x1A,
    0xF0, 0x30, 0x45, 0xB7, 0x44,0x82, 0xEF, 0x3A, 0x0C, 0xE0,0xE5, 0x94, 0xFA, 0xFD, 0x2E,0xD9, 0xEB, 0x8D, 0x5A, 0xC2,
    0xEF, 0x39, 0x51, 0x71, 0x92,0xFA, 0xDB, 0xEF, 0x14, 0x88,0x00, 0xFF, 0xE3, 0xF6, 0xB5,0x34, 0x34, 0x40, 0xF5, 0xBB,
    0xC8, 0xD3, 0xB5, 0xBD, 0xF6,0xCF, 0xC7, 0xB1, 0xF9, 0x18,0x3D, 0xA2, 0x74, 0xEF, 0x40,0xBC, 0x6B, 0x39, 0xF2, 0xC8,
    0x6E, 0x00, 0x64, 0x78, 0x52,0x88, 0x13, 0xF4, 0x27, 0x74,0x14, 0x8F, 0xCE, 0x34, 0x5E,0xF9, 0xE0, 0x6D, 0x47, 0xFC,
    0x38, 0x6D, 0xB0, 0x03, 0xED,0x6C, 0xF6, 0x68, 0x00, 0xAC,0x2B, 0xFE, 0x73, 0x2C, 0x94,0x9E, 0x3F, 0x17, 0x0C, 0x33,
    0xB9, 0x8F, 0x33, 0x34, 0xDE,0x05, 0x18, 0xE1, 0x2B, 0xB9,0x42, 0x3F, 0x5F, 0xA2, 0xB4,0x1E, 0xE9, 0x45, 0xF3, 0x38,
    0x43, 0xBB, 0x8E, 0xB0, 0x0A,0x94, 0x39, 0xEE, 0xFF, 0x9A,0xF4, 0x2D, 0x6C, 0x4B, 0x66,0xB1, 0x1E, 0x0F, 0xC2, 0x18,
    0x32, 0xE1, 0x74, 0xFF, 0x90,0x94, 0xF2, 0x38, 0xDD, 0x56,0xDC, 0x78, 0x91, 0x96, 0xD1,0x04, 0x03, 0x09, 0x21, 0x39,
    0xB2, 0xD4, 0xCC, 0x2A, 0xA8,0xAB, 0xE8, 0x99, 0x1C, 0xE7,0xE4, 0x43, 0x3B, 0x58, 0xC1,0x59, 0x54, 0xE8, 0xBD, 0x9C,
    0x28, 0xC6, 0x81, 0xFC, 0xAD,0x33, 0x4F, 0x24, 0x16, 0xA0,0x47, 0xD1, 0x4C, 0x4D, 0x39,0x7A, 0xC1, 0xF7, 0x1D, 0x04,
    0xCF, 0xE7, 0xAE, 0x17, 0x71,0xD9, 0x37, 0xDC, 0x9C, 0x0A,0x0E, 0x9D, 0x0E, 0x04, 0xD7,0x24, 0xC1, 0x50, 0x0C, 0x49,
    0xE3, 0xBC, 0xCA, 0x98, 0x89,0x55, 0x86, 0x73, 0xF1, 0xC3,0x8D, 0x8F, 0x99, 0x34, 0xF7,0x4B, 0xE7, 0x69, 0x0A, 0xB0,
    0xC1, 0x2F, 0x85, 0x97, 0xBF,0xC3, 0xFD, 0xD0, 0x62, 0x75,0xB1, 0xAD, 0xF3, 0x04, 0xF3,0xF3, 0x77, 0x06, 0xAA, 0x77,
    0x5A, 0xE7, 0xEB, 0x67, 0x3F,0xB5, 0x40, 0xA1, 0x9C, 0x53,0x96, 0xFD, 0x85, 0x53, 0x6E,0xED, 0x52, 0x05, 0x3B, 0x6E,
    0x89, 0xEF, 0x95, 0x98, 0xB6,0x66, 0x34, 0xD0, 0x8A, 0x3F,0x44, 0xEA, 0x06, 0x86, 0x13,0x39, 0xEF, 0x20, 0xAD, 0xE4,
    0x73, 0x2C, 0x61, 0x77, 0x10,0x3D, 0xB9, 0x0B, 0xC2, 0x0C,0xFD, 0xF2, 0x99, 0xD8, 0xB1,0x57, 0x83, 0x1B, 0x24, 0xA6,
    0xA0, 0xAB, 0x97, 0x3E, 0xE5,0x09, 0x07, 0x3F, 0x43, 0xED,0x12, 0xE3, 0x36, 0xCE, 0x16,0x58, 0xF2, 0x78, 0x00, 0x63,
    0xF7, 0x67, 0xDC, 0xD9, 0x5F,0x0D, 0xAA, 0x3E, 0x9A, 0xA3,0x83, 0x72, 0xFE, 0xBA, 0x92,0xE9, 0xD4, 0x22, 0xF0, 0x38,
    0x38, 0x61, 0xE2, 0x79, 0x9B,0x5E, 0x8A, 0x62, 0x27, 0x59,0x84, 0x71, 0xC0, 0xEB, 0x95,0x28, 0x0D, 0x34, 0xCB, 0xAB,
    0x25, 0xC6, 0x3B, 0xBC, 0x52,0xA5, 0xCA, 0x6B, 0x93, 0xCA,0x23, 0x6D, 0x35, 0x87, 0x41,0x87, 0x3E, 0x48, 0xB9, 0xDF,
    0x0E, 0xFD, 0x30, 0xB8, 0xD1,0xB8, 0x10, 0x68, 0x3D, 0xBC,0x09, 0x04, 0x31, 0x94, 0x5C,0x91, 0xAF, 0x6C

    Decompression


    Decompression is simple, the data uses a RAW inflate with -15 window bit. Libraries like ZLIB can help with decompressing the data. You will only need to inflate the data if the compression is 8. If it's 0, you can skip this step.


    Links

    A list of links to help:



    Last edited by StingerOne; 26-06-22 at 02:40 PM.




Advertisement