The concept of executable compression has been around for many years. Packing tools can be used to compress the size of an executable file to save storage space. A compressed executable includes the code required to decompress itself and run, so it can be distributed without the need to include any other software.
There are many different companies and projects which provide tools to compress executable files.
Advantages of Compression
- Smaller executable image size.
- Faster load times over networks.
- Can be used to deter reverse engineering of the software.
Disadvantages of Compression
- The image must be decompressed before it is used and adds to the load time.
- A non-compressed image can be read from the storage medium without loading the whole image into memory, whereas a compressed image will be loaded into memory in its entirety as part of the decompression.
- Some utilities may not be able to determine the dependencies of a compressed image.
Research Problem
I wanted to investigate the possibilities of executable packers and I was particularly interested in improvements in load times over a network. My company has many customers using software developed in Delphi, which we develop and maintain. One of our customers has a very large system with hundreds of individual executable images. These images are stored on a shared network and loaded very frequently by users.
Research Question
To what extent can executable compression improve load times over a network?
Tool Selection
For the system described above, FinalBuilder is used to build the software. As a starting point, I looked for packing tools which are supported by the build tools.
There are two tools with specific build actions in FinalBuilder:
- UPX - https://upx.github.io/
- ASPack - http://www.aspack.com/
UPX is a well known project with a GPL licence. ASPack is proprietary software.
I wanted to test with more than two tools. By searching the FinalBuilder forums, I could see that there were requests to add actions for this tool, used by Delphi developers:
- PECompact - https://bitsum.com/portfolio/pecompact/
I selected a fourth test tool from the list of tools on Wikipedia1, based on the latest release date. I choose Alienyze, but this did not appear to have any documentation. I could not determine how to run this tool from the command line, which was a required when using the tool within FinalBuilder. It was also blocked by my anti-virus software, so I decided to proceed with only three tools.
Research Method
To carry out this research, I wanted to record two measurements: file size and load time. I wrote a simple Delphi application which would load a set of executable files, recording the size and the time it took to load for each test case.
The executable files under test already included a command line parameter which can be used to tell the program to quit immediately after use. This had previously been added to test that the programs are built correctly. By using this parameter, the test harness can launch a program, which will immediately quit. The time taken to do this is then measurable.
Using this tool, I was able to record a set of measurements for a sample of 483 separate executable images of various sizes, between 0.5 Mb and 13 Mb. I started by recording these measurements for the images in their uncompressed state. I then made recordings with the images compressed by each of the three tools.
For each compression tool, I only used the default options in FinalBuilder, or in the case of PECompact, the default options in the tool itself. I did not vary any of these options.
Test Environment
The test programs were built on Windows 10. The tests themselves were run in a network environment on a Windows 2003 Server.
Test Results
All three tools performed well when compressing the executable images. All the images compressed to below 45% of their original size. Of the three tools under study, PECompact had the best compression ratio.
Executable images compressed with UPX performed the least well in terms of load time. In most cases, it took longer to load the compressed executable than the uncompressed one. Additionally, some of the UPX-compressed programs failed to load at all. These are the blue data points at the bottom of the chart.
PECompact performed better in this respect, but the results were inconsistent. The majority of the sample programs loaded more quickly when compressed with PECompact, but there was a wide variation in the speed improvements. It is possible that this variation is caused by factors such as program structure or resources, but further analysis is outside the scope of this research.
The best performer here was ASPack. Only 23 of the 483 programs loaded more slowly when compressed with ASPack. The vast majority loaded in around 40% of the time taken to load their uncompressed versions.
Conclusions
If your primary reason for using these tools is a reduced file size, then all three tools perform well, with PECompact producing the best results.
If you are more interested in load times over network, then the best performer in my limited tests was the ASPack software.
It is also a major concern that some of the programs packed by UPX were no longer executable.
Opportunities for Further Study
This was a limited study into these tools and there are plenty of opportunities for further study.
- Why do some programs load more slowly when packed with ASPack?
- Why do some programs fail when packed with UPX?
- What is the cause of the large variation in performance with programs packed with PECompact?
- What are the options available in these packing tools and what effect do they have?
- What is the effect on memory consumption when using packed programs?
[1] Wikipedia - Executable Compression - https://en.wikipedia.org/wiki/Executable_compression#Portable_Executable