unpacking unpackme2 by ellvis

8
1 Unpacking UnpackMe2 by Ellvis A tutorial by Saduff In this paper, I’m going to show you my “crazy” method of unpacking this UnpackMe. I did not dig too deep into this, so I’m not surprised if there are better solutions. Still, this method worked for me and it’s pretty “decent” I think, so enjoy. :D Contents 1) Preliminary study of the target ........................................................................................................... 2 2) Unpacking the UnpackMe ................................................................................................................... 2 Finding OEP.......................................................................................................................................... 2 Restoring OEP ...................................................................................................................................... 3 Dumping the target with fixed OEP..................................................................................................... 4 Fixing the Import Table ....................................................................................................................... 5 “Cleaning” the dump with LordPE....................................................................................................... 5 Testing the dump ................................................................................................................................ 5 Finding the cause of the problem ....................................................................................................... 5 The more „elegant“ solution ............................................................................................................... 7 Manually creating a TLSTable .............................................................................................................. 7 Creating a TLS Callback ........................................................................................................................ 7 Testing the final unpacked executable................................................................................................ 8 Conclusion ........................................................................................................................................... 8

Upload: andres-liiver

Post on 28-Apr-2015

50 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Unpacking UnpackMe2 by Ellvis

1

UnpackingUnpackMe2byEllvis

A tutorial by Saduff

In this paper, I’m going to show you my “crazy” method of unpacking this UnpackMe. I did not dig

too deep into this, so I’m not surprised if there are better solutions. Still, this method worked for me

and it’s pretty “decent” I think, so enjoy. :D

Contents

1) Preliminary study of the target ........................................................................................................... 2

2) Unpacking the UnpackMe ................................................................................................................... 2

Finding OEP.......................................................................................................................................... 2

Restoring OEP ...................................................................................................................................... 3

Dumping the target with fixed OEP ..................................................................................................... 4

Fixing the Import Table ....................................................................................................................... 5

“Cleaning” the dump with LordPE ....................................................................................................... 5

Testing the dump ................................................................................................................................ 5

Finding the cause of the problem ....................................................................................................... 5

The more „elegant“ solution ............................................................................................................... 7

Manually creating a TLSTable .............................................................................................................. 7

Creating a TLS Callback ........................................................................................................................ 7

Testing the final unpacked executable ................................................................................................ 8

Conclusion ........................................................................................................................................... 8

Page 2: Unpacking UnpackMe2 by Ellvis

2

1) Preliminary study of the target

So, before we do anything else, let’s scan the target with PEiD:

So PEiD confirms it is packed with UPX. Also have a look at the EP section’s name. That’s all we need

to know. Now let’s unpack it.

2) Unpacking the UnpackMe

Finding OEP

So, open the UnpackMe in Olly and you’ll see a standard UPX stub for VB6. As always with UPX, the

quickest way to find OEP is to simply scroll down until the jump to OEP (the last jump before 0 bytes).

You could also use the ‘standard’ methods of unpacking like the ESP trick, or simply tracing your way

to OEP. So set a breakpoint on the jump to OEP and follow the jump to get to OEP:

Page 3: Unpacking UnpackMe2 by Ellvis

3

But where does this jump lead to? Directly to the jump to MSVBVM60.ThunRTMain. That’s definitely

not a valid VB6 OEP. So what’s going on here? Stolen bytes/commands are what this is. Some

commands have been “stolen” from the OEP and are executed in the packer’s stub before the jump

to OEP. A valid VB6 EP looks like this:

PUSH XXXXXXXX

CALL <JMP.&MSVBVM60.ThunRTMain>

So to properly unpack, that’s how the unpacked file’s EP should look like. Let’s start fixing the OEP.

Restoring OEP

Before the jump to OEP, we can see that 2 instructions are executed that are not part of the UPX

stub:

PUSH 004011FE

MOV DWORD PTR DS:[ESP+4],00401400

The first PUSH could be the missing push from the OEP, but then what is the 2nd

instruction for?

Actually, the first push is not necessary at all. It’s there only to balance the stack, since there is no

call. A call would push the return address to stack. So that means the OEP should look like this:

PUSH 00401400

CALL 004011EE

I hope you understand why the OEP should look like this.

Page 4: Unpacking UnpackMe2 by Ellvis

4

Dumping the target with fixed OEP

So, now that we know how the OEP should look like, we need to find some free bytes where to write

it. This is where we’re going to write the fixed OEP:

This is where you should be after following the jump to OEP from the UPX stub. So write the fixed

OEP there and then right click on the push and select “New origin here” (so that the OllyDump plugin

will automatically fill in the OEP). When that is done dump the target with “Rebuild Import”

unchecked. Here’s how the fixed OEP should look like:

Page 5: Unpacking UnpackMe2 by Ellvis

5

Fixing the Import Table

Now it’s time to fix the Import Table. I’m using Scylla to do that. If you’re on Windows 7, you should

be using Scylla too. Scylla should find all imports without any problems, so I will not discuss this

further.

“Cleaning” the dump with LordPE

Now load the dump into LordPE’s PE Editor. First click on “Sections” and then wipe the “UPX1”

section header. Now close the section table and change “BaseofCode” from 00006000 to 00001000.

We wipe the “UPX1” section, because it is no longer needed, since it contains only packer’s code.

“BaseOfCode” means the RVA of the beginning of the code section. After you’ve done this, save the

file and rebuild it with LordPE’s PE Rebuilder.

Testing the dump

Now the UnpackMe should be unpacked. All that remains is to test it, so run it and see what

happens. If you did everything correctly so far, then the dump should run fine! But wait… where is

the window? We must have missed something, because when running the UnpackMe, a window is

displayed. So let’s go back into the UPX stub and see what we missed.

Finding the cause of the problem

You can skip the part of the UPX stub where stuff gets unpacked and the IAT gets restored, so we

land here:

Page 6: Unpacking UnpackMe2 by Ellvis

6

At that point, the target is unpacked. We can skip the VirtualProtect calls, as they are not important.

So that leaves us with this code:

MOV EAX,FS:[18]

MOV EAX,[EAX+30]

MOV DWORD PTR [EAX+2],1

The segment register FS is used to access the Thread Information Block (TIB), which is a data

structure that stores info about the currently running thread. FS:[18] points to the linear address of

TIB. Now that the address of TIB is in EAX, [EAX+30] or FS:[30] is moved into EAX, which contains the

linear address of the Process Environment Block (PEB). By looking at the PEB structure on MSDN, it

seems that the next line of code moves 1 into “BeingDebugged”, though I’m not so sure about that,

because “BeingDebugged” is a byte, but the instruction overwrites a dword. 1 = debugged, 0 = not

debugged. After some trial and error, I found out that these 3 lines of code must be executed for the

window to be displayed. And it must be 1 and not 0. 0 does not work, only 1 works. I did not dig

deeper into this to find out why exactly the window does not get displayed when 1 is not written to

that address in the PEB, I just know that it must be done. You could assemble these instructions

before the EP and it would work, although you would need to find another location for the EP (not

enough space there, target will crash when you write these instructions there), but let’s try a more

“elegant” solution.

Page 7: Unpacking UnpackMe2 by Ellvis

7

The more „elegant“ solution

This more “elegant” solution I’m talking about relies on the fact that code gets executed before the

entry point. We could write a DLL and as the Windows Loader loads the DLL, we can execute code

before the EP of the main program is reached, but there is another way – using Thread Local Storage

(TLS) callbacks.

Manually creating a TLSTable

Before we can create any callbacks, we must create a TLSTable. We will use LordPE and Olly to do

that. First we must find some empty space in the target. VA 00401500 will do just fine. Now open the

dump in LordPE’s PE Editor and click on “Directories”. There you will see a “TlsTable” entry. Fill in the

RVA with 00001500 and Size with 00000018. Now save and close LordPE. Now reopen the dump with

the PE Editor (yes, you have to save and then reopen, otherwise it will not work), click on

“Directories” and then click on the “…” button next to the “TlsTable” entry. Here we need to fix the

“IndexVariableVA” and “CallBackTableVA” value, the rest is not important. Fill in “CallBackTableVA”

with TlsTable VA + Size (= 00401518) and “IndexVariableVA” with CallBackTableVA + 8 (= 00401520).

Now save and close LordPE and we should have a working TLSTable.

Creating a TLS Callback

Now that we have a working TLSTable, we can create a TLS callback. So open Olly and go to

“CallBackTableVA” (00401518). We will create our TLS callback at IndexVariableVA + 8 (= 00401528),

so when you’re at “CallBackTableVA”, assemble “dd 00401528” (pointer to TLS callback) there. Now

go to 00401528, which is where we will create the actual code. Assemble the following code there:

PUSH EBP

MOV EBP,ESP

MOV EAX,FS:[18]

MOV EAX,[EAX+30]

MOV DWORD PTR [EAX+2],1

LEAVE

RET 0C

When that’s done, copy the changes to executable.

Page 8: Unpacking UnpackMe2 by Ellvis

8

Testing the final unpacked executable

Now let’s test if it works, so run it. If you did everything correctly, the executable should run fine and

the window should be displayed. Congratulations, the UnpackMe is unpacked! ☺

Conclusion

It’s not always so simple to unpack. Sometimes you need to trace the packer’s stub. Anyway, I hope

you learned something from this tutorial. That’s it, see you in another tutorial! ;)