5

Still on my way to understand how to prevent the usage of the -d (decompress) option of UPX (see this question), I try to identify the header file of UPX in ELF executable files.

Looking at the code, all the sources seems to be in the files lx_elf.h and lx_elf.cpp (stands for Linux Elf). I tried to follow the code but I got lost in it...

I also did take a look at the beginning of an UPX compressed executable file (amd64), visualized in 8-bytes per line mode for more clarity (and thanks to Corkami ELF-101):

00000000: 7f45 4c46 0201 0103  .ELF....
00000008: 0000 0000 0000 0000  ........
00000010: 0200 3e00 0100 0000  ..>.....
00000018: 0831 4200 0000 0000  .1B.....    ELF HEADER
00000020: 4000 0000 0000 0000  @.......
00000028: 0000 0000 0000 0000  ........
00000030: 0000 0000 4000 3800  [email protected].
00000038: 0200 4000 0000 0000  ..@.....

00000040: 0100 0000 0500 0000  ........
00000048: 0000 0000 0000 0000  ........
00000050: 0000 4000 0000 0000  ..@.....
00000058: 0000 4000 0000 0000  ..@.....    PROGRAM HEADER TABLE
00000060: f438 0200 0000 0000  .8......
00000068: f438 0200 0000 0000  .8......
00000070: 0000 2000 0000 0000  .. .....
00000078: 0100 0000 0600 0000  ........

00000080: 487d 0500 0000 0000  H}......
00000088: 487d 6500 0000 0000  H}e.....
00000090: 487d 6500 0000 0000  H}e.....
00000098: 0000 0000 0000 0000  ........
000000a0: 0000 0000 0000 0000  ........    UPX HEADER (???)
000000a8: 0000 2000 0000 0000  .. .....
000000b0: a298 b634 5550 5821  ...4UPX!
000000b8: f407 0d16 0000 0000  ........
000000c0: 1676 0500 1676 0500  .v...v..
000000c8: 0002 0000 bd00 0000  ........
000000d0: 0200 0000 fbfb 21ff  ......!.

000000d8: 7f45 4c46 0201 0100  .ELF....
000000e0: 0200 3e00 0d70 2840  ..>..p(@
000000e8: 0f1b f26d 1605 00e8  ...m....   ELF HEADER (again)
000000f0: 6d05 0013 01eb be7b  m......{
000000f8: 3800 0805 1c00 1b00  8.......
00000100: 060f 0527 9b90 27ec  ...'..'.
00000108: 4000 4007 c001 0008  @.@.....
....8<....

My guess is that the second ELF header (always located at an offset of 0xd8) is the header of the compressed executable. And indeed, when looking at the original ELF header of the executable (before applying upx) we find:

00000000: 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010: 0200 3e00 0100 0000 7028 4000 0000 0000  ..>.....p(@.....
00000020: 4000 0000 0000 0000 e86d 0500 0000 0000  @........m......
00000030: 0000 0000 4000 3800 0800 4000 1c00 1b00  [email protected]...@.....
00000040: 0600 0000 0500 0000 4000 0000 0000 0000  ........@.......
00000050: 4000 4000 0000 0000 4000 4000 0000 0000  @.@.....@.@.....
00000060: c001 0000 0000 0000 c001 0000 0000 0000  ................
00000070: 0800 0000 0000 0000 0300 0000 0400 0000  ................
00000080: 0002 0000 0000 0000 0002 4000 0000 0000  ..........@.....

A few fields have been omitted in the compressed version but the header is mainly preserved. So, lets assume this is just a short version of the original ELF header.

But, what I would like to understand are the fields of the first header:

00000080: 487d 0500 0000 0000  H}......
00000088: 487d 6500 0000 0000  H}e.....
00000090: 487d 6500 0000 0000  H}e.....
00000098: 0000 0000 0000 0000  ........
000000a0: 0000 0000 0000 0000  ........    UPX HEADER (???)
000000a8: 0000 2000 0000 0000  .. .....
000000b0: a298 b634 5550 5821  ...4UPX!
000000b8: f407 0d16 0000 0000  ........
000000c0: 1676 0500 1676 0500  .v...v..
000000c8: 0002 0000 bd00 0000  ........
000000d0: 0200 0000 fbfb 21ff  ......!.

So, my question is about discovering the location and the meaning of the fields of the UPX header. If somebody knows about UPX internals any hint would be appreciated.

2
  • Check out src/stub/src/include/linux.h (search for UPX_MAGIC_LE32) and header.S in the same directory. Don't have time to investigate beyond that, but if I was you I'd attach GDB and step through the disassembly line by line.
    – 0xC0000022L
    Feb 6, 2014 at 13:53
  • Thanks for the hint, I was really lost in this code ! I will take a deeper look (and take the time to write down a proper answer if nobody dare to do it before me ;-)).
    – perror
    Feb 6, 2014 at 21:27

2 Answers 2

12
+50

It's very easy to prevent the UPX tool to unpack an UPX compressed file. If you take a look to the source code you will see that it checks for the magic string UPX_MAGIC_LE32 in p_lx_interp.cpp. So, I simply changed all matches of the string (in binary chunks) "UPX!" to "AAA!". I copied /bin/ls (ELF64) to another folder and packed with UPX. Then I edited it like this:

$ pyew ls
ELF Information
(...)
[0x00000000]> /s UPX # Search for the string UPX
HINT[0x000000b4]: UPX!........p...p...8.............!..ELF......>[email protected]
HINT[0x0000abcc]: UPX!.........S...USQRH..VH..H..1.1.H....P.....t.....H.......
HINT[0x0000ad3b]: UPX executable packer http://upx.sf.net $..$Id: UPX 3.07 Cop
HINT[0x0000ad6b]: UPX 3.07 Copyright (C) 1996-2010 the UPX Team. All Rights Re
HINT[0x0000ad90]: UPX Team. All Rights Reserved. $....^j._j.X..j._j....N...p...I.......
[0x00000000]> s 0xb4 # Seek to the specified offset in the file
[0x000000b4:0x000000b4]> edit # Open the file for editing
[0x000000b4:0x000000b4]> wx 414141 # Patch in hexadecimal
[0x000000b4:0x000000b4]> s 0xabcc
[0x0000abcc:0x0000abcc]> wx 414141
[0x0000abcc:0x0000abcc]> s 0xafe7
[0x0000afe7:0x0000afe7]> wx 414141
[0x0000afe7:0x0000afe7]> s 0xb3ac
[0x0000b3ac:0x0000b3ac]> wx 414141
[0x0000b3ac:0x0000b3ac]> q # And quit
$ ./ls
(...lots of files...)
$ upx -d ./ls
                       Ultimate Packer for eXecutables
                          Copyright (C) 1996 - 2010
UPX 3.07        Markus Oberhumer, Laszlo Molnar & John Reiser   Sep 08th 2010
        File size         Ratio      Format      Name
   --------------------   ------   -----------   -----------
upx: ls: NotPackedException: not packed by UPX

Unpacked 0 files.

That's all. Anyway, remember that you're only preventing this tool to unpack UPX compressed files. UPX is a compressor that anyone with basic knowledge about packers can uncompress with little to no effort.

3
  • I am just surprised that it is so simple... In fact, your answer does not totally match with the question but it answer totally my overall goal. So, thanks a lot !
    – perror
    Feb 11, 2014 at 10:13
  • 2
    this answer exactly echoes what i posted to your old question simply changing the STRING UPX to XPX prevents upx -d from working
    – blabb
    Feb 11, 2014 at 18:37
  • 3
    And funnily enough, he did exactly what we suggested the OP do: read the source code.
    – fileoffset
    Feb 13, 2014 at 5:13
-3

As answered in response to your previous question, UPX is open-source, so you can read the commented code to understand the headers: http://upx.sourceforge.net/download/upx-3.91-src.tar.bz2

8
  • 1
    First, your comment is not an answer. And, second, previous answer didn't give any practical way to achieve this because the proof of concept of Ange was done for the PE format of UPX, I'm now asking for ELF format.
    – perror
    Feb 5, 2014 at 20:40
  • 1
    My answer is that you should look at the documentation in the ELF-specific UPX code :) Feb 5, 2014 at 21:10
  • 1
    I'm with Jason on this: it seems simple, all you have to do is read the decompression code (ELF-specific) and find a way to break it. What better place to start than the source code?
    – fileoffset
    Feb 6, 2014 at 6:15
  • 1
    @fileoffset: And I am with perror. See, the header files even get mentioned in the question. It's not like the author didn't do his homework. Jason's comment doesn't answer the question, it tells the author to go find the answer in a heap of (yes, commented) code. I value Jason as a member of the RCE community and I did before RE.SE even existed. But I hope this does not become the standard of answers on here for the future. And yes, the downvote is from me, but I figured from the debate and Jason's own comments that it might make sense to elaborate why I downvoted.
    – 0xC0000022L
    Feb 6, 2014 at 13:42
  • 2
    To be fair, this is a reverse engineering forum. This question doesn't even require reverse engineering, just reading source code and some coding and testing. You don't need to reverse engineer open source software :)
    – fileoffset
    Feb 7, 2014 at 1:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.