Notes on PKLITE format, Part 6

This post will explain the important differences between compressed EXE files made by the v1.00beta version of PKLITE, and those made by release versions. It is a continuation of Part 5 — please read that first.

For an introduction to PKLITE, and a list of the other posts in this series, see Part 1.

History

There was no public beta version of PKLITE. The version I’m referring to was apparently a private beta test version that was unfortunately leaked to the public. It gives its date as 1990-05-29, and its version number as “1.00β”. One place to get a copy is here: PKLITE.ZIP.

Files made by it are not commonly encountered, but if you’re going to go to the trouble of writing a PKLITE decompressor, you may as well support the beta version. It doesn’t take much extra work.

File layout

A normal PKLITE-compressed file is organized like this:

  • Headers
  • [start-of-DOS-code-image, entry point] Decompressor
  • Compressed code image
  • Compressed relocation table
  • Footer
  • [start of custom-data-3] Overlay segment

But for the beta version, the decompressor appears after the compressed code image:

  • Headers
  • [start-of-DOS-code-image] Compressed code image
  • Compressed relocation table
  • Footer
  • [entry point] Decompressor
  • [start of custom-data-3] Overlay segment

Here’s an annotated partial hex dump of a typical file compressed with PKLITE v1.00beta:

(Incidentally, the file I compressed for these diagrams is PKPAK.EXE, usually found in a file named PK361.EXE or PK361.ZIP.)

The load-high option

The beta version has a “load-high” option not seen in any other version.

 -l = make a load-high .EXE file

What it does is not very important, and it has barely any effect on the decompression strategy. But you may have to be aware of it in order to correctly detect beta files.

In pristine files, use of this option is reflected in the “info bytes”: the 0x40 bit of the byte at offset 29 will be set.

The “shape” of the decompressor

You can add the following to the list of fingerprint patterns to look for, starting at the entry point.

v1.00beta (default)
 2E 8C 1E ?? ?? 8B 1E 02 00 8C DA 81 C2 00 07 3B 
 DA 72 04 81 EB 00 06 83 EB 40 FA 8E D3 BC 00 01 
 FB FD BE FE

v1.00beta with load-high
 2E 8C 1E ?? ?? FC 8C C8 2E 2B 06 ?? ?? 8E D8 BF
 00 01 33 F6 AD 95 BA 10 00 EB ?? AD 95 B2 10 EB
 ?? AD 95 B2

But you shouldn’t require a complete match of these patterns, in order to classify a file as beta.

There are many ways to distinguish beta files from every other PKLITE format that I know about. But given that there could be unknown formats out there, it’s hard to decide what method to use. Note that what you really need to detect is not the beta version per se, but whether the decoder appears after the compressed data.

What I tentatively suggest is that if the entry point is larger than the start-of-DOS-code-image, and the byte at the entry point is 2E, then assume the decoder appears after the compressed data. Additionally, if the first 6 bytes of the “with load-high” pattern are matched, assume the load-high option was used.

The “tables” section

The tables section appears in beta files, the same as any other PKLITE-compressed files. Note that due to the different layout, it will usually be close to the end of the file.

You should still use it to detect large vs. small compression mode, but for the beta version, it is not used to find the offset of the compressed code image. That offset is always equal to start-of-DOS-code-image.

Detecting extra compression

The beta version is a prototype for the freely-distributable version, and does not support creating files with “extra compression”. However, the PKLITE.EXE file itself is compressed with what seems to be the same extra compression supported by later registered versions, so you should assume that extra compression is possible.

I can’t offer a foolproof way to detect extra compression. But, given the presumed rarity of such files, you could use the last-resort methods suggested in Part 5. They can be slightly refined for the beta version:

  1. If the start-of-DOS-code-image is 80, then extra compression is used. If it is 112 or higher, then it is not used. (If it is 96, or less than 80, this test fails.)
  2. Trust the “info bytes”: If the info bytes are valid for the beta version, and the 0x10 bit in the byte at offset 29 is set, then extra compression is used.

Putting it together

Having collected the compression parameters, the process of decompression, and of constructing the decompressed file, is the same as for other versions of PKLITE.

Or very close to the same. In the interest of completeness, there is a potential issue if both of the following are true:

  • The load-high option is used
  • The copy-of-original-EXE-header is not present or not valid

The number of such files in the wild is probably zero, but anyway… In a load-high file, the max-memory-requested field (offset 12) is always set to 0. So, maybe you shouldn’t copy it to the decompressed file. I don’t know what you should do instead, but setting it to the maximum (65535) is one possibility.

Concluding remarks and future directions

That pretty much exhausts my knowledge of the PKLITE DOS formats. There is more to learn, though. Here are some topics that could be investigated:

  • How to decompress the special PKLITE formats labeled v1.10 or v1.20, and used by PKWARE for some of its own products (e.g., some versions of PKLITE, PKZIP, PKZMENU), and for files produced by ZIP2EXE from PKZIP 2.04+.
  • The “uncompressed area” (-g) feature in v2.01. Files that use this feature should contain the byte pattern “PKLITE\x26\xA3”.
  • PKLITE possibly does special things with certain types of driver files (.DRV, .SYS).
  • What’s the best way to reconstruct the min-memory-needed and max-memory-requested fields? The optimal algorithm probably depends on the version of PKLITE, and there may be special cases for very small or very large files.
  • Design an efficient, accurate algorithm for detecting whether a file is PKLITE-compressed.
  • Design a good way to classify and detect the different versions of PKLITE format
  • Make a substantially complete list of all PKLITE “protector” and patcher utilities, so they can be evaluated.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s