アンパック

解析

const COMPRESS_NONE:i32 = 0;
const COMPRESS_ZLIB:i32 = 1;
const COMPRESS_GZIP:i32 = 2;

struct PakEntry {
    file_name: FString,
    offset: u64,
    size: u64,
    uncompressed_size: u64,
    compression_method: i32,
    hash: [u8; 20],
    compression_blocks: Vec<PakCompressedBlock>,
    bencrypted: u8,
    compression_block_size: u32,
}

struct PakCompressedBlock {
    compressed_start: u64,
    compressed_end: u64,
}

entry[0]

2A 00 00 00
45 6E 67 69 6E 65 2F 50 6C 75 67 69 6E 73 2F 32
44 2F 50 61 70 65 72 32 44 2F 50 61 70 65 72 32
44 2E 75 70 6C 75 67 69 6E 00
FileName = "Engine/Plugins/2D/Paper2D/Paper2D.uplugin"

00 00 00 00 00 00 00 00
Offset = 0x0

7E 01 00 00 00 00 00 00
Size = 0x17E

72 03 00 00 00 00 00 00
UncompressedSize = 0x372

01 00 00 00
CompressionMethod = 0x1 (COMPRESS_ZLIB)

D3 1C F0 F0 1B 02 64 78 9C B5 D6 B8 35 45 82 86 CE 4E 38 D4
Hash

01 00 00 00
TArray.ArrayNum = 1
49 00 00 00 00 00 00 00
PakCompressedBlock.CompressedStart = 0x49
C7 01 00 00 00 00 00 00
PakCompressedBlock.CompressedEnd = 0x1C7

00
bEncrypted=0x0

72 03 00 00
CompressionBlockSize=0x372

まず CompressionMethod をみると 0x1 これは COMPRESS_ZLIB なので ZLIB 圧縮されている。
シー ク CompressedStart から CompressedEnd - CompressedStart これがサイズになるのでこの分読み込む。読み込んだものを ZLIB で復元しファイルに出力する。これを ArrayNum 分繰り返す。出力ファイルは FileName

以上でアンパックできます。

このフォーマットを見る限り pak は
bEncrypted = 0x0 (false) つまり非暗号で圧縮無し・ZLIB圧縮・GZIP圧縮
bEncrypted = 0x1 (true) 暗号化されている(AES)で圧縮無し・ZLIB圧縮・GZIP圧縮
のパターンが出てくるかもしれません。
(UE4.9.1時の情報)
AES暗号済みのも出現しました。