Thanks to visit codestin.com
Credit goes to github.com

Skip to content

feat(handler): add upx decompression to elf executable #1189

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

rxpha3l
Copy link
Contributor

@rxpha3l rxpha3l commented May 8, 2025

UPX is a free, secure, portable, extendable, high-performance
executable packer for several executable formats.

The UPX header is written after the elf header. The offset depends on how big the ELF is. Luckily UPX writes in the last 4 bytes of the compressed file the offet to the header.

Create UPX file :

upx --best foo.elf -ofoo.upx

Decompress UPX file:

upx -d foo.upx -ofoo.decompressed

Key notes:

  • UPX uses a lot of alignments, which is why computing the UPX header after the ELF header can cause discrepancies
  • The UPX header is called loader and is 12 bytes long, with UPX! as magic
  • File format is little endian
  • Supports 32 bit & 64 bit platforms
  • UPX uses stat to get information about the compressed file, which is why the total compressed file size is no where to be found
  • Checksum is calculated over the stubloader and uses adler32
  • Loader size is not the actual size, since it is aligned. The alignment must be subtracted. It will be used to determine the data length used in the checksum function

Header format :

4 bytes : Checksum
4 bytes : Magic
2 bytes : Loader size
1 byte : Version
1 byte : Format

Using python's lief library, it possible to get the offset of the last segment. Subtracting the loader size of it, returns the stub loader offset after alignment. Subtracting the alignment return the correct loader offset used for the checksum. Following the official UPX github repository, in src/p_lx_elf.cpp line 385 to 447 is where the alignment is done. Before calculating the total alignment, xct_off checks for shared android library in the section names of the elf header. If there is one present, this will change the total alignment afterwards. To summarize, UPX aligns the loader size to be a multiple of 4, with additional steps in between. The alignment is the difference between the loader size in the header and the value after the alignment calculation. The checksum size the loader size minus the alignment.

[Sources]
https://bbs.kanxue.com/thread-248779.htm
https://github.com/upx/upx/blob/devel/src/stub/src/include/linux.h
https://github.com/upx/upx/blob/devel/src/p_lx_elf.cpp
https://www.programmersought.com/article/58884806733/

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant