Unpacking with OllyBonE

This is a brief tutorial giving the basic steps to unpack code using the OllyBonE plugin.

Theory

OllyBonE takes advantage of the split TLB architecture of Intel processors to protect memory pages from execution but still allow read/write access. For more information on how this works, see the grsecurity PaX project's documentation describing PAGEEXEC at http://pax.grsecurity.net/docs/pageexec.txt

Basically OllyBonE consists of a Windows kernel driver that implements the page protection for arbitrary memory pages, and an OllyDbg plugin that communicates with the driver. When the protected page is accessed by the CPU for execution, the INT1 handler is called, returning control to OllyDbg.

The normal method of use is to load a packed program, making note of which section in the memory map will be executing when the unpacking is finished, then setting the break-on-execute flag for that section. This loads the kernel driver into memory and protects the desired physical memory pages from being executed. (Note that only one instance of OllyDbg can use the kernel driver at a time, if you try to load a second instance, you will get an error message "Kernel driver load returned status 5"). When the program is run, OllyDbg will (hopefully) break on the first instruction, which would be our original entry point (OEP).

This technique generally only works with packers that append their unpacking code as a stub section to the PE file, then restore the unpacked code into its original sections. In many cases, packers may employ anti-debugging tricks during the execution of the stub code, which must still be worked around. OllyBonE isn't going to work in all cases, but it can be a shortcut for quickly unpacking the most common packer code.

Installing OllyBonE

Example: UPX

Let's look at an app packed by UPX. In the OllyDbg memory map window, we see:
00400000   00001000   test     0             PE header     Imag   R         RWE
00401000   00040000   test     0  UPX0                     Imag   R         RWE
00441000   0002A000   test     0  UPX1       code          Imag   R         RWE
0046B000   00001000   test     0  .rsrc      data,imports  Imag   R         RWE
Our entrypoint in this program is at 0046A350, which is in the UPX1 section. If you've ever manually unpacked a UPX program before, you know that typically the stub code in UPX1 will unpack the real program code to the UPX0 section, before jumping to it at the bottom of the stub code. So, we select the UPX0 section in the memory map window, choose "Set break-on-execute", and then run the program by hitting the "play" button or F9.

OllyDbg then stops due to a single-step break at the OEP, the first instruction executed in the protected UPX0 section. We are unpacked and can now analyze the program or dump it using OllyDump.

Example: ASProtect

Sometimes, a program isn't so straightforward - load up a program packed by ASProtect and you'll see that although there are new sections added to the PE file, execution begins at the start of the first section after the PE header (EIP is 401000).
00400000   00001000   test              PE header     Imag   R         RWE
00401000   00001000   test              code          Imag   R         RWE
00402000   00001000   test              data          Imag   R         RWE
00403000   00001000   test                            Imag   R         RWE
00404000   00001000   test                            Imag   R         RWE
00405000   00036000   test   .data      imports,relo  Imag   R         RWE
0043B000   00001000   test   .adata                   Imag   R         RWE
This is the same section we'll be running after the code is unpacked, so we can't simply set a break-on-execute here. Fortunately, ASProtect doesn't spend long in this section - there is a PUSH/CALL/RETN/RETN and then we jump to the unpacking stub in another section. So, hitting F7 four times brings us to a place where we can now right-click in the memory map, choose the first section after the PE header, and set break-on-execute.

But, depending on how the program was packed, there may be more in store for us. For example, ASProtect can perform a simple well-known anti-debugging trick, checking the value of the IsBeingDebugged variable in the PEB. Before we can successfully unpack the program, we'll have to bypass that check, either by toggling the value in the PEB manually, or by using a plugin that does it for us.

Once that's out of the way, we can run the program with F9. We land with an INT1 break in the first section, but we're not at the OEP yet. ASProtect has us executing a RETN call in the code section. Go back to the memory map and right-click on the section and choose "Remove break-on-execute" so that we can single-step and follow the return back to unpacking code. Once that is done, we can once again choose "Set break-on-execute" on the code section and hit F9. This time, when the program stops, we are at the OEP. Remember to remove the break-on-execute in order to step through the program for analysis.

Caveats

Since OllyBonE fiddles with the memory page permissions, other kernel drivers which might affect memory pages might conflict with OllyBonE. One thing known not to get along with OllyBonE is DEP, the Microsoft protection built in to XP SP2. DEP can be disabled - if you experience blue-screening when setting a break-on-execute, this is probably what you need to do.

You can change the DEP settings under:

Control Panel->System->Advanced->Performance->Settings->Data Execution Prevention. 
If that doesn't work, you may need to add
/noexecute=AlwaysOff
to your Windows partition in boot.ini.

Of course, this makes your system more vulnerable to buffer overflow exploits, so using OllyBonE on production systems is not advised. OllyBonE will work under VMWare, so this may be a preferred method for its use. However, note that some packers actively refuse to run under virtual machines, so it may not be the best solution in every case.

OllyBonE isn't a magic-bullet unpacker for all cases, and certainly has its flaws. During the time that the program is running before the breakpoint is reached, the unpacking code can be doing anything, including detecting OllyBonE and subverting it, using the driver to even crash the system by execute-protecting random pages of memory. For now OllyBonE is more of a proof-of-concept than a finished program - keep that in mind as you use it.


Jan 3, 2007 - Joe Stewart