How to make smaller executables with upx

UPX (Ultimate Packer for eXecutables) is a popular open-source executable packer that compresses and reduces the size of executable files…

How to make smaller executables with upx
Photo by Liana S on Unsplash

UPX (Ultimate Packer for eXecutables) is a popular open-source executable packer that compresses and reduces the size of executable files while allowing them to remain runnable. UPX achieves this by compressing the original file and attaching a decompression stub to the compressed file. When the compressed executable is run, the stub decompresses the original file into memory and then executes it. In this article i will do a real life example with a go executable, lets start!

What you will need

You will need a Linux setup with golang, vim (or your editor of choice) and upx, i will provide instructions on how to install them only for alpine Linux since i run those examples in a container, but it should be fairly easy to install them to any popular Linux distro such as ubuntu or centos.

apk update && apk add --no-cache vim upx golang

Creating the executable

Now we are ready we need to create some code that we will compile to an executable, create the following file and save it as main.go

package main 
 
import "fmt" 
 
func main() { 
    fmt.Println("Hello UPX!") 
}

Now lets proceed to compilation

8b8b0303f4a3:/workspace# go build main.go 
8b8b0303f4a3:/workspace# ls -ltrh 
total 2M 
-rw-r--r--    1 root     root          75 Aug 25 17:20 main.go 
-rwxr-xr-x    1 root     root        1.8M Aug 25 17:35 main

We can see that it created an executable named main which has a size of 1.8M and is a very simple program that prints a message on screen and exits!

upx at work!

Lets see how upx can compress our executable

8b8b0303f4a3:/workspace# upx --best main 
                       Ultimate Packer for eXecutables 
                          Copyright (C) 1996 - 2023 
UPX 4.2.1       Markus Oberhumer, Laszlo Molnar & John Reiser    Nov 1st 2023 
 
        File size         Ratio      Format      Name 
   --------------------   ------   -----------   ----------- 
   1906861 ->   1088560   57.09%   linux/arm64   main 
 
Packed 1 file. 
8b8b0303f4a3:/workspace# ls -ltrh 
total 1M 
-rw-r--r--    1 root     root          75 Aug 25 17:20 main.go 
-rwxr-xr-x    1 root     root        1.0M Aug 25 17:35 main

Using upx --best we can see that we have a reduction in size of 43% which is very good! but does this compression has any penalty in program startup? still needs to be decompressed on each run.. in very small executables like this testing has no point you will not see any actual difference.

Conclusion

Knowing how to use upx with executables can be super useful, can save you precious disk space and impove upload times in case of deploying the executable in devices with slow networks, but all of this comes to cost of decompression, which might not be significant in small executables