Manual unpacking of UPX 3 04
I will use this post to demonstrate how to manually unpack a program which was packed with UPX 3.04 packer using Ollydbg. The packed executable can be downloaded from the LINK. It is a very simple program that only shows a message box with some text in it.
Packers
Packers are programs that take an executable file as input and produce a new executable file as output. The new executable contains the original executable as data and an unpacking stub which is called by the OS. Malware authors use packers because they help malware hide from antivirus software, complicate malware analysis and shrink the size of a malicious executable.
When dealing with a packed program, the unpacking stub is loaded by the OS, and then the unpacking stub loads the original program. The unpacking stub is often small and it can be viewed by the malware analyst. Understanding how the unpacking stub operates is very important to unpacking the original executable. The unpacking stub performs three steps:
- Unpack the original executable into memory
- Resolve all the imports of the original executable
- Transfer execution to the original entry point (OEP)
The entire packing and unpacking process can be seen on pictures 1 to 4:
- Picture 1 shows the original executable. All the sections and the header are visible and the starting point points to the OEP.
![]() | ||||
Picture 1. The original executable before the packing |
- Picture 2 shows the packed executable. The unpacking stub is added and the entry point is set to the unpacking stub.
![]() | ||
Picture 2. The packed executable |
- Picture 3 shows the program after it has been unpacked and loaded into memory. The programs starting point still points to the unpacking stub.
Picture 3. Program after being unpacked and loaded into memory - Picture 4 shows the fully unpacked program. The starting point is back to the OEP and the import table is reconstructed.
Picture 4. The fully unpacked program
This was a brief overview of how packers work. In the next chapter a practical example of unpacking will be demonstrated.
Unpacking UPX 3.04
Before loading the packed executable to Ollydbg, download the Ollydump plug-in and extract it to Ollydbgs plug-in directory.
When this is done, load the packed executable to Ollydbg. The program is paused at the unpacking stub entry point at 0046DD50 as shown in picture 5.
![]() |
Picture 5. Entry point of unpacking stub |
The PUSHAD instruction at this address is of great value to the unpacking process. This instruction is used to push all 8 general purpose registers onto the stack and it is likely that the packing program will restore all the registers immediately before it jumps to the OEP. Knowing this we can try to find OEP by setting an access breakpoint on the stack:
- Step over the PUSHAD instruction and right click on the ESP register to follow its value in memory dump (Picture 6).
![]() |
Picture 6. Stack address from which the registers are stored |
2. Highlight the first 4 bytes in the dump and set a hardware breakpoint on access on them (Picture 7).
![]() |
Picture 7. Setting the hardware breakpoint |
After the breakpoint is set, run the program by pressing F9. The execution will hit the breakpoint at 0046DEE5. As mentioned earlier, the registers will probably be restored before the jump to OEP is taken. Having that in mind observe the jump instruction at 0046DEFC. This is a rather big jump and it could be the tail jump to the OEP so step over to the jump instruction and execute it.
![]() |
Picture 8. The tail jump |
The execution is now paused at 004271B0. As shown in Picture 9 there are calls to GetVersion() and GetCommandLineA() functions which are common functions at the beginning of a program and that means that the OEP has been found.
![]() |
Picture 9. Unpacked code of the executable |
Next step is to dump the process using Ollydump plug-in. The main window of the plug-in is shown in picture 10.
![]() |
Picture 10. Ollydump plug-in window |
If you look at the sections, you will notice that they are marked as UPX packed so unselect the "Rebuild Import" option. Save the dump by pressing the "Dump" key and open the saved file with PEid tool to check if the file has been successfully unpacked (Picture 11).
![]() |
Picture 11. Unpacked executable checked with PEid |
The last thing that needs to be done is to fix the import address table (IAT) by using Import Reconstructor. In picture 12 you can see that the OEP is not correct (0006DD50). The correct value is 271B0 which is the offset to the OEP that we got from Ollydump.
![]() |
Picture 12. Wrong OEP in ImpRec tool |
Copy the correct value, paste it to Import Reconstructor and select "IAT AutoSearch" button. Next select the "Get Imports" option and as you can see in picture 13 all the imports have been successfully found. The last thing to do is to click the "Fix dump" button and select the dumped executable on the disk to save the repaired and unpacked executable. If you try to run the executable it will work normally.
![]() |
Picture 13. Reconstructed import address table |
For any questions or whatsoever leave a comment.
download file now
alternative link download