Reversing Unpacking UPX

12 Comments

Previously I wrote a post about unpacking ASPack, before I move on to unpacking some of the commonly used protectors(and the uncommon ones), I wanted to mention how to unpack UPX as it is considered one of the easiest packers to unpack.
You can download UPX from its official site at http://upx.sourceforge.net.

Tools we’ll need:
1. PEiD.
2. OllyDbg.
3. OllyDump plugin.

Let’s get started, firstly we should scan our file with PEiD to check it’s actually packed with UPX…

UPX 0.89.6 – 1.02 / 1.05 – 1.24 -> Markus & Laszlo

And it is.

UPX’s entrypoint looks similar to this:

PUSHAD
MOV ESI, Server.00408000
LEA EDI, DWORD PTR DS:[ESI+FFFF9000]
PUSH EDI
OR EBP, FFFFFFFF
JMP SHORT Server.0040BA82

The PUSHAD instruction is of interest to us in this case, it does the following:

PUSHAD – Push All General Purpose Registers.

We can use what is known as the ESP trick to find OEP(Original-Entry-Point)… Step over(F8) the PUSHAD instruction and you’ll notice the ESP register’s contents changes, proceed by following its contents in the dump, set a hardware breakpoint(Size: dword. Type: on access) on followed byte.

Run(F9) until you hit the hardware breakpoint, you should land on a JMP instruction which leads to our OEP, step over it(F8).

You should now be at OEP. The IAT(Import Address Table) is basically intact so there’s no need to launch ImpRec and attempt to rebuild it(Most protectors tend to destroy the IAT to complicate our job).

All that’s left to do is dumping, launch the OllyDump plugin, leave the rebuild imports option on (method 1) and continue dumping the file.

You’ve now unpacked a UPX compressed file, I bet that was easier than you imagined?

Don’t forget to test your dumped file, if you did everything correctly it should execute without problems.

KOrUPt.

Stumble it!

Tags: , ,

12 Responses to “Unpacking UPX”

  1. meh Says:

    IIRC the popad matching that pushad is typically just at the bottom of the code section. slightly unencrypted.

  2. metr0 Says:

    Thus it’s sometimes just faster to do a binary search for several 00-bytes. The first occurance should be right below the jump to OEP. ;)

  3. KOrUPt Says:

    Thanks for the feedback everyone.

    Metr0: I’ll keep that in mind next time I’m messing around with a UPX compressed file :) . Thanks for the tip!

    KOrUPt.

  4. fiction Says:

    I am not really familiar with Windows stuff. What is ImpRec and how does it work under the hood?
    Beside that it restores the PE import table.

    AFAIK IDA Pro already has an automatism for what you call “the ESP trick”. I’d call it PUSHAD, POPAD trick. The problem is that you know where the unpacking code has the “state” stored and assume the next read of it will be the reconstruction of the state if got it correctly. So that the decrypted code gets the same state as before (as if the decryption code never ran).

    Knowing you will use the trick enables an attacker to exploit it. For instance by doing PUSHAD and never really carring for that stuff that gets written to the stack. Or artificially moving stuff around and messing with it. Sometimes you just won’t get around analyzing the code instruction by instruction. And that’s the boring part of RE.

  5. KOrUPt Says:

    Well, in most cases if the ESP Trick doesn’t work I’ll step through the code myself…

    As far as I know ImpRec rebuilds the Import Address Table in memory and sets up the directory structures inside the PE header, it then dumps that image from memory… I’ve not looked into it in too much depth.

    I wasn’t aware that IDA had automation for the ESP trick, I’ll check it out later tonight sometime.

    Thanks for the feedback.

    KOrUPt.

  6. meh Says:

    fiction, yeah the windows stuff has the disadvantage that a lot of it is closed source, so “how” it works isn’t always entirely clear…

    however it, or one of it’s plugins (several out there with source) will try a bunch of tricks to link the imports back up. If the automatic things fail it will resort to providing you with a manual dialog where you just get to choose what a certain rva should link to.

    Perhaps it’s instrumental to understand that the dynamic linking, and hence the IAT is done based on readable text. The IAT would contain the text strings “kernel32.dll” and for example “GetModuleAdressA”. After loading and dynamic linking these texts are no longer useful and hence trivially deleted or KorUPted. However when you get to the point where you dump the executable The code is supposed to be linked. And hence you could follow some function call to some dll’s address space. (and then compare with it’s exports which function it probably is). (which is one of the methods ollydump uses, when dumping)

    Imprec takes a dump of a program and a running process in memory to attach to… And of course a bit of magix. To try to do the same thing but with more trix.

    This description is not entire accurate, but i hope it’s close enough and gets you an idea. I’m not terribly involved in this stuff right now either.

  7. Pernat1y Says:

    upx.exe -d file.exe
    =\

  8. KOrUPt Says:

    I wrote this to teach a newbie some general unpacking techniques.

    Also UPX cannot always unpack the files it compresses.

    KOrUPt.

  9. Adrellias Says:

    Hey :D

    Didnt know where else to contact you. Wanted to know if this would work on a linux binary ? Packed by upx. I have no idea how to start with the header rebuilt on some malware i got a hold off :P

  10. KOrUPt Says:

    I imagine the UPX unpacking stub would be very similar to its Win32 companion. You should be able to step through the code with GDB(could be awkward) or IDA, which I’m fairly sure has the feature of automating the ESP trick somewhere within its menu’s, from there…

    …I’m not sure how you’d go about dumping the target and rebuilding the IAT/GOT :( … I don’t work with packed ELF binaries much(hardly ever).

    Perhaps someone more qualified in this area can drop us a line? Thanks in advance :) .

    KOrUPt.

  11. beach Says:

    Dear KOrUPt,

    I have a program that is UPX packed, after I unpack it the program doesn’t seem to start, I’m surely doing something wrong. Could you drop me a mail if you have time to help me out with it ? I also would like to ask you something else.

  12. KOrUPt Says:

    If it is UPX you shouldn’t have much trouble unpacking it.

    Did you check the IAT was intact once you reached OEP? Perhaps the PE headers were erased at runtime(could be a modified version of UPX).

    Trace through it and find out why it doesn’t run, it’s likely an issue with an unresolved API in the IAT.

    I don’t have time to attempt unpacking the file myself at the moment, I’m very busy with real life issues this month :/.

    Hope this helps.

    KOrUPt.

Leave a Reply