Monday, January 31, 2011

IDA Pro: universal Unpacker

Since some people wrote to me in the past days saying they are interested on IDA Pro, I decided to follow a little bit on this topic. Today I want to show you how to use the IDA pro universal unpacker.

There are many ways to confuse (or to sidetrack) the reverse engineer, but I will cover this topic later in the following posts. One of these many ways is to use a packer and/or encrpter. Packing and Encrypting are two different math functions, the first one is oriented on saving space the second one oriented on making secret the code, but in both ways they are a good to obfuscate the original code. Obviously unpacking is easier then decrypting, in many situations in order to unpack a program is enough to figure out what type of packer has been used, after that many IDA plugins help us in the unpacking procedures. On the other hand if the program has been encrypted we need to figure out the math (and frequently the key too), and this procedure becomes pretty hard.

Fortunately there are many different ways to unpack/decrypt a code; two techniques overall are: (1) the static techniques and (2) the dynamic + dumping code techniques (again I will cover this topic in the next posts). Today I wanna show you how to use the default IDA Pro unpacker plugin (belonging to the (2) techniques set) to find out the Original Entry Point (OEP). The OEP is the original address of the main. Every packer/crypter puts a new Entry Point referring to the unpacking/decrypting function (often added to the header of the binary) which reading directly from itself unpacks/decrypts the further bytes.

As shown in figure the packer/crypter wraps the original PE header with a self routine able to unpack/decrypt the original PE file. Our goal is to find the original "main", in such a way there is no need to understand how the packing/crypting algorithm works. In the above example UPX packer (UPX is a great packer, pretty easy to detect and to bypass but still very interesting since it is opensource. There are many variants of packers, ASPack is only another great one. For a more complete list of packer here) has been used.

The main question when you are decompiling a binary is how can I recognize that this binary has been packed/encrypted ? Again there are at least two ways to do so, but for now I am going to answer using signature detection. Each packer/encryptor has a unpack/decrypt routine which a specified signature. PEID is, probably, the most famous tool able to recognize the used packed. This is possible thanks to the huge community behind the software who writes signatures for each new packer, something like signature based AV.

Under the IDA point of view, when you open a packet/encrypted binary you may see in the import table dynamic-links library functions like the following ones:

Dynamic-link libraries are very commonly used from packers to restore the original executable's import table. Once we recognize the presence of packers lets run the IDA pro unpacker plugin.

Immediately after the execution of the plugin IDA Pro will ask where it has to stop the plugin execution. The plugin calculates the stopping memory area by itself but if you need to modify it (for example you recognized a multi thread packer/crypter) a dialog box appears next to the main window.
Fix your breakpoints on the code dynamically, once the plugin reaches your break points, it will create a new segment refilled with the unpacked code. The unpacked code is basically a representation of what the original code have executed until the breakpoints, it is not the real (or even the original) code at all. You will see something like :

Which is much better than the previous one ;), but still no perfect at all. PEID and yourself (if you keep time to investigate into the strings) after the unpacker/decrypter procedure, will figure what kind of complier has been used.

IDA FLIRT libraries help you to rebuild the original binary knowing the used compiler. Lets apply the right FLIRT and see how better is the resulting code :D

Isn't pretty code ? :D


Anonymous said...

You should at least tell the sources you needed to write that article, instead of acting like a pro.

Anonymous said...

thanks very usefull link

Hex-Rays said...

Wow nice attempt at stealing our freely accessible documentation Marco! We at Hex-Rays applaud your stupidity.