views:

1863

answers:

11

I've used UPX before to reduce the size of my Windows executables, but I must admit that I am naive to any negative side effects this could have. What's the downside to all of this packing/unpacking?

Are there scenarios in which anyone would recommend NOT UPX-ing an executable (e.g. when writing a DLL, Windows Service, or when targeting Vista or Win7)? I write most of my code in Delphi, but I've used UPX to compress C/C++ executables as well.

On a side note, I'm not running UPX in some attempt to protect my exe from disassemblers, only to reduce the size of the executable and prevent cursory tampering.

A: 

The last time I tried to use it on a managed assembly, it munged it so bad that the runtime refused to load it. That's the only time I can think of that you wouldn't want to use it (and, really, it's been so long since I tried that that the situation may even be better now). I've used it extensively in the past on all types of unmanaged binaries, and never had an issue.

DannySmurf
+2  A: 

The final size of the executable on disk is largely irrelevant these days. Your program may load a few milliseconds faster, but once it starts running the difference is indistinguishable.

Some people may be more suspicious of your executable just because it is compressed with UPX. Depending on your end users, this may or may not be an important consideration.

Greg Hewgill
+1 I'm always suspicious of packed executables / DLLs, especially if I can't unpack them.
Hugh Allen
+20  A: 

The reason is there are downsides to using EXE compressors. Most notably:

Upon startup of a compressed EXE/DLL, all of the code is decompressed from the disk image into memory in one pass, which can cause disk thrashing if the system is low on memory and is forced to access the swap file. In contrast, with uncompressed EXE/DLLs, the OS allocates memory for code pages on demand (i.e. when they are executed).

Multiple instances of a compressed EXE/DLL create multiple instances of the code in memory. If you have a compressed EXE that contains 1 MB of code (before compression) and the user starts 5 instances of it, approximately 4 MB of memory is wasted. Likewise, if you have a DLL that is 1 MB and it is used by 5 running applications, approximately 4 MB of memory is wasted. With uncompressed EXE/DLLs, code is only stored in memory once and is shared between instances.

http://www.jrsoftware.org/striprlc.php#execomp

Lars Truijens
+5  A: 

The only time size matters is during download off the Internet. If you are using UPX then you actually get worse performance then if you use 7-zip (based on my testing 7-Zip is twice as good as UPX). Then when it is actually left compressed on the target computer your performance is decreased (see Lars' answer). So UPX is not a good solution for file size. Just 7zip the whole thing.

As far as to prevent tampering, it is a FAIL as well. UPX supports decompressing too. If someone wants to modify the EXE then they will see it is compress with UPX and then uncompress it. The percentage of possible crackers you might slow down does not justify the effort and performance loss.

A better solution would be to use binary signing or at least just a hash. A simple hash verification system is to take a hash of your binary and a secret value (usually a guid). Only your EXE knows the secret value, so when it recalculates the hash for verification it can use it again. This isn't perfect (the secret value can be retrieved). The ideal situation would be to use a certificate and a signature.

Jim McKeeth
Size matters on USB stick. Portable apps are one case where it'd make sense.
niXar
Given the current prices of multi-gigabyte sticks, I'm not sure size matters there anymore either. Unless you are storing HD video, of course.
RBerteig
A: 

I believe there is a possibility that it might not work on computers that have DEP (Data Execution Prevention) turned on.

Slapout
+1  A: 

If your only interest is in decreasing the size of the executables, then have you tried comparing the size of the executable with and without runtime packages? Granted you will have to also include the sizes of the packages overall along with your executable, but if you have multiple executables which use the same base packages, then your savings would be rather high.

Another thing to look at would be the graphics/glyphs you use in your program. You can save quite a bit of space by consolidating them to a single Timagelist included in a global data module rather than have them repeated on each form. I believe each image is stored in the form resource as hex, so that would mean that each byte takes up two bytes...you can shrink this a bit by loading the image from a RCData resource using a TResourceStream.

skamradt
+4  A: 

I'm surprised this hasn't been mentioned yet but using UPX-packed executables also increases the risk of producing false-positives from heuristic anti-virus software because statistically a lot of malware also uses UPX.

Oliver Giesen
UPX is not for protection. Just packing.
abababa22
Sorry, I slurred that a bit. Changed the wording now.
Oliver Giesen
Fully agree. At Free Pascal we get a few such reports (that one or the other binary in the distro triggers some avirus) an year. We then stopped routinely upxing.
Marco van de Voort
+4  A: 

There are three drawbacks:

  1. The whole code will be fully uncompressed in virtual memory, while in a regular EXE or DLL, only the code actually used is loaded in memory. This is especially relevant if only a small portion of the code in your EXE/DLL is used at each run.
  2. If there are multiple instances of your DLL and EXE running, their code can't be shared across the instances, so you'll be using more memory.
  3. If your EXE/DLL is already in cache, or on a very fast storage medium, or if the CPU you're running on is slow, you will experience reduced startup speed as decompression will still have to take place, and you won't benefit from the reduced size. This is especially true for an EXE that will be invoked multiple times repeatedly.

Thus the above drawbacks are more of an issue if your EXE or DLLs contains lots of resources, but otherwise, they may not be much of a factor in practice, given the relative size of executables and available memory, unless you're talking of DLLs used by lots of executables (like system DLLs).

To dispell some incorrect information in other answers:

  • UPX will not affect your ability to run on DEP-protected machines.
  • UPX will not affect the ability of major anti-virus software, as they support UPX-compressed executables (as well as other executable compression formats).
  • UPX has been able to use LZMA compression for some time now (7zip's compression algorithm), use the --lzma switch.
A: 

IMHO routinely UPXing is pointless, but the reasons are spelled above, mostly, memory is more expensive than disk.

Erik: the LZMA stub might be bigger. Even if the algorithm is better, it does not always be a net plus.

A: 

Virus scanners that look for 'unknown' viruses can flag UPX compressed executables as having a virus. I have been told this is because several viruses use UPX to hide themselves. I have used UPX on software and McAfee will flag the file as having a virus.

McAfee? It's the most terrible antivirus software I've ever used. Stay away!
ya23
In fact, stay away from any virus scanner that is stupid enough to mark every upx compressed file as a virus.
Wouter van Nifterick
A: 

The reason UPX has so many false alarms is because its open licensing allows malware authors to use and modify it with impunity. Of course, this issue is inherent to the industry, but sadly the great UPX project is plagued by this problem.

Jeremy Collake