Microsoft EXEPACK

From ModdingWiki
Jump to: navigation, search
Microsoft EXEPACK
Format typeCompression algorithm
I/O unit size1-bit

Microsoft EXEPACK is a an executable file compressor used by several classic games.

EXEPACK compression could be added to a program by LINK.EXE /EXEPACK switch or by invoking EXEPACK.EXE utility, that was distributed with MASM.

Games using EXEPACK

Some games utilize EXEPACK as an inner layer of their compression:

Games packed with EXEPACK

File Format

offset     length    purpose
0          0x1C      DOS exe header
???        ???       packed exe
           0x12      unpacker vars (EXEPACK variables, see below)
           0x105     unpacker code
           0x16      string "Packed file is corrupt"
           ???       packed reloc table (see below for more information)

offset to packed exe = header * 16 (from exe header)
length of packed exe = CS:IP (from exe header)
length of packed reloc table = exepack_size - dest_len (from exepack variables)

EXEPACK variables

Variables used by the exepack unpacker (all except mem_start are pre-initialized):

Data type Name Description
UINT16LE real_IP real start address (offset)
UINT16LE real_CS real start address (offset)
UINT16LE mem_start start of the exe in memory (segment)
UINT16LE exepack_size size of unpacker vars + unpacker code + error string + packed reloc table in bytes
UINT16LE real_SP real stack (offset)
UINT16LE real_SS real stack (segment)
UINT16LE dest_len destination of the unpacker code (in paragraphs, relative to start of exe in memory)
UINT16LE skip_len number of paragraphs between packed exe and unpacker variables + 1
UINT16LE signature "RB" (magic number of exepacked files)

Relocation Table

packed relocation table = section_0, section_1, ..., section_0xf
section = number_of_entries [can be zero], set of entry [can be empty]
number_of_entries = unsigned word (16 bits)
entry = unsigned word (16 bits)

An entry in section n patches the segment value at:
0x1000*n + entry (relative to the start of the exe in memory)

Decompression algorithm

The exepack unpacker first copies itself to the location stored in dest_len. (the value in dest_len also equals the unpacked exe's size in paragraphs). It then executes a retf to the new location and starts unpacking. The unpacking algorithm works like this:

  int srcPos; /* start at the end of the packed exe, because the unpacker works downwards */
  int dstPos;
  int commandByte, lengthWord, fillByte;
  /* skip all 0xff bytes (they're just padding to make the packed exe's size a multiple of 16 */
  while (*srcPos == 0xff) {
  /* unpack */
  do {
    commandByte = *(srcPos--);
    switch (commandByte & 0xFE) {
      /* (byte)value (word)length (byte)0xb0 */
      /* writes a run of <length> bytes with a value of <value> */
      case 0xb0:
        lengthWord = (*(srcPos--))*0x100;
        lengthWord += *(srcPos--);
        fillByte = *(srcPos--);
        for (i = 0; i < lengthWord; i++) {
          *(dstPos--) = fillByte;
      /* (word)length (byte)0xb2 */
      /* copies the next <length> bytes */
      case 0xb2:
        lengthWord = (*(srcPos--))*0x100;
        lengthWord += *(srcPos--);
        for (i = 0; i < lengthWord; i++) {
          *(dstPos--) = *(srcPos--);
      /* unknown command */
        printf("Unknown command %x at position %x\n", commandByte, srcPos);
  } while ((commandByte & 1) != 1); /* lowest bit set => last block */


  • The sizes of both the packed exe and the unpacked exe are multiples of 16
  • The unpacker code unpacks the exe onto itself, i.e. the unpacked exe has the same starting address (in memory) as the packed exe (in memory).


This information was adopted from by aowen. The source page said:

Please send additions, corrections and feedback to this e-mail address: Remove space + vowels from "marc winterrowd" and append "at yahoo dot com"

Tools UNPACK, a DOS program written by Clive Turvey, that decompresses files packed with Microsoft EXEPACK. unexepack, open-source / public domain exepack decompressor