Packed w/ UPX - can see 0/1 in sections

The malware is packed w/ UPX - can see 0/1 in sections.

Sure, I can can a tool or even use UPX -d -o flags .exe to create an unpacked copy with a >97% ratio, however I want to MANUALLY unpack it to keep practicing my skills and to get better.

Opening the .exe (MD5 for malware: 9fbdc5eca123e81571e8966b9b4e4a1e) with OllyDbg brings us right to the POPAD instruction and several usual follow-on calls on the stack that also let us know it's typical UPX stuff.

The problem is, when I step-over the PUSHAD and land on the MOV instruction, if I follow the ESP register through the dump, the first four hex dump bytes are zeroed out.

Zeroed bytes.

With this said, I still set the HWBP on access just to see what it would lead me to, and it brings me to this:

After hardware breakpoint

And this is where I get stumped. If I try and step through to the JUMP instruction, it will only go to the conditional jump (JNZ) before it falls back to the PUSH instruction. I can manually click my way to the JMP instruction and run the program again, which leads me to the CMP ESP, EAX. If I run the program one more time, it brings me to 0139BC0E which looks like this:

After CMP instruction

There's a few kernel32 function calls that you might see at the beginning of a program, but honestly I am not sure if I am where I need to be for this unpacking. I doubt it.

All in all, I could use some help.

2 Answers 2


This may either be packed multiple times or contain additional obfuscations or anti-analysis. Use the "PUSHAD, breakpoint on ESP, run" method to find the tail transition, as you have. Then set a breakpoint on the tail transition (in your case, JMP 0002A99E) and run to that. The single-step to take the jmp and you'll be at the OEP, or the next stage of packing.

One way to figure out if you have it unpacked is to dump at this point (using OllyDumpEx, for example) and load it in your typical tools (IDA, exeinfo, PEiD, etc) to see what it looks like.

When I do this with your binary, I'm seeing what looks like some typical setup code, but then after the call to initterm, at 0040A7F2 there is a call using a memory address that contains zeros (hover over the dword_xxxx value to see). If you look back just a little bit, you'll see a call to a sub_xxxx that takes as an argument that dword_xxxx address. Diving into that function and the functions it calls, it looks like there is some parsing of the PE header (see cmp's with immediate values 5A4Dh and 4550h). In malware, this is typically done to find where kernel32 or other modules are in memory.

In addition to that, look at the Imports and you can see that there are references to LoadLibrary and GetProcAddress. If you look for those cross-references (aka xrefs), then you'll find functions that look like they have encoded values (a bunch of xor instructions in a row with immediates), so possibly dynamically rebuilding the IAT.

That's more info than you need to get past the UPX unpacking stage, but this malware has more anti-analysis techniques than just UPX packing, so you might have additional questions. The Practical Malware Analysis book has a good description of what you'll want to do next, and is generally a good reference, but feel free to start more questions on stackexchange if you want more help!


So to your first problem, the last two elements of the stack are 0 because PUSHAD pushes the registers in the following order on the stack. EAX, ECX, EDX, EBX, EBP, ESP, EBP, ESI, EDI

Since ESI and EDI are both 0 in your case, the two values on top of the stack are also 0.

In general, UPX is one of the easier ones to unpack, because it was not designed for security but compression.

So the way to go here, is to find the tail jump. This one can be recognized by the following zeroes and the jump to a far address.

I don't get your problem exactly, because you found the tail jump already. See at address 001026B1 the jump to 0002A99E. Consequently, your program starts at 0002A99E and this is your OEP. You can then remove the hardware breakpoint, set a breakpoint at the jump, continue running until it stops at the JMP and then step with F7, to debug the unpacked program.

  • Sorry for any confusion. What I am trying to find out is, how do I know when the program is unpacked and ready to be dumped to be rebuilt with Import Reconstructor? For example, I tried following your advice of setting a breakpoint on the JMP instruction after clearing the prior breakpoint, but what type of breakpoint do I set on that JMP instruction? Options are: Toggle, conditional, conditional log, run to selection, memory (on access), memory (on write), and hardware (on execution). Dec 8, 2018 at 7:35
  • The program is ready when it hits the breakpoint on the jmp. You don't need necessarily Import Reconstructor, OllyDbg is able to dump the process and create the import table with a plugin called 'OllyDump'. A simple breakpoint is enough, so either press F2 when the targeted line is highlighted oder right click and choose toggle breakpoint.
    – pudi
    Dec 8, 2018 at 11:01
  • Thank you for your knowledge so far, I am learning quite a bit. So I toggled the breakpoint on the JMP instruction and then pressed F7 to step into it, and it leads me to the condition jump (JNZ) right above that you can see in that image. At this point, what do I do? I tried dumping the program using OllyDump from this highlighted conditional jump, and it states that it's unable to read the memory of the debugging process, and a bad DOS signature. Are we dealing with more obfuscation than UPX within the program, or is the conditional jmp just not the correct place to dump the program? Dec 8, 2018 at 17:12
  • Probably the problem is, that your instruction pointer is not pointing to the instruction with the unconditional jump. After your program stops because of the hardware breakpoint, you need to set the breakpoint at the JMP and then continue running (F9) until your program stops again at the JMP. Then you can press F7 or F8, to get to the first instruction of the unpacked program. Btw, google "ollydbg upx unpack" or something similar, there are some good tutorials outside that should clear your problems.
    – pudi
    Dec 8, 2018 at 17:33
  • I think this malware in particular is using anti-VM/debug. I followed your instructions yet I continue to get bad dos/unable to get memory for dumping the process. I tried dumping it automatically also using UPX in cmd and it throws an access violation upon execution. Strange... not really sure how to proceed. Dec 11, 2018 at 8:36

Your Answer

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

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