2009
09.28

Its a beautiful Monday once again. What is special about this Monday is that it has its rather long introduction story. Here is what you don't know about ReversingLabs. At the end of each week we go through preparation for Monday blog. So the team decides and creates a sample code for our blog. This was also the case last week and we picked to do a blog about using TitanEngine as static library and creating a PeID plugin for handling overlay. It a small plugin called TitaniumOverlay with options to add, remove, copy and extract overlay. But... in the last minute we found a rather obvious bug inside RemoveOverlay and decided not to use this in our blog. Then another team member decided to code an unpacker for PackMan a simple PE32 packer which packs ExE and DLL files. Which seemed like a good idea until we found that with the current debugger design you can't SingleStep after hardware breakpoints. And that once again meant that this won't get on the blog. In another try to do a sample of using TitanEngine as a static library we made an OllyDBG plugin named TitaniumHandles which would display information about open handles and mutexes with the ability to close them. Which has proven useful on more then one occasion, and OllyDBG doen't have this as option so it seemed like a good idea... That is until we found a bug in handle filtering that prevented retrieving names of certain handles. Now its Sunday afternoon and we have three great samples on how you can use TitanEngine but since there are some bugs in the engine we can't use this code yet. So what do we do (after we fix them obviously)?

We open our known formats list, place our hand over the eyes and pray that our next pick wont be an epic fail... And the pick is... PeX 0.99. Nice and easy, it should be fun to do. Gentleman, start your debuggers.

Once we start the analysis we find that the entry point has a nice message for us telling us that the sample is packed with PeX. How nice of bart^xt, the author of the packer. This can be used as a part of the signature for this format. After some tracing we find this code:

  ADD ESP,4 ; [EntryPoint + 0x254]
  POP EDX
  POP ESI
  PUSH CS
  PUSH ESI
  RETF

Which once executed leads us to level two of the packer. Formats who use multiple packing levels usually use them to process PE format specifics, such import table processing and file memory protection. In this case packer shell uses this level to fill and protect the import table. So by some more tracing we find:

  CALL NEAR EAX ; kernel32.LoadLibraryA [Level2 + 0xF0]
  TEST EAX,EAX
  JE Level2 + 0x3BF

Simple call the LoadLibraryA API call to load all needed libraries. Data we need is located as a pointer to string in EBX register which holds the name of DLL to be loaded. Some more tracing leads us to this point in code:

  ADD ESP,4 ; [Level2 + 0x1DF]
  AND EBX,7FFFFFFF
  PUSH EBX
  PUSH DWORD PTR SS:[EBP+402A18]
  CALL +0x01	;Redirected GetProcAddress call

This is a call to GetProcAddress API which locates the functions inside the previously loaded DLL file. Parameters we need from here are EBX which is either API ordinal number or a pointer to string which is the name of the function to be found in loaded DLL, and EDI which holds the pointer to IAT. More specifically the place where the API pointer will be written. Normally that would be it for import fixing but PeX has a simple redirection code we must disable before continuing the unpacking process. That code is located here:

  LEA ECX,DWORD PTR SS:[EBP+4025CB] ; [Level2 + 0x299]
  ADD EBX,DWORD PTR DS:[ECX]
  CMP DWORD PTR DS:[ECX],0B13
  JNB OverCodeThatProtectsTheImportTable
  PUSH EBX

By simple patching we change JNB jump from above to JMP and ensure that import table protection code isn't executed. Last thing we have to find is the entry point location and set a breakpoint to dump and fix the file on it. We look a little bit down the code and find this:

  PUSH 4012BF ; [Level2 + 0x396]
  JMP L003
  ???
L003:
  POP EAX
  INC EAX
  PUSH EAX
  RET

Code that will be written to packed entry point and used as a redirection to original entry point. We read this address (0x004012BF) and add one to it to get the original entry point address. Breakpoint we chose to set is a hardware breakpoint on execution, but we could have used a normal breakpoint as well since code at that address has been unpacked and written just before level switching. Once that breakpoint is hit our unpacker will finalize the unpacking in the well known manner.

Since we were (and are) low on Delphi samples, this weeks unpacker was written for that programming language. Also note that all bugs that affected the three candidates for Monday blog were fixed and will be published very soon with the next TitanEngine release. In the mean time keep checking back at our blog and forums for more info about the continuous TitanEngine development.

TitanEngine

ReversingLabs Corporation

Download RL!dePeX unpacker
(package contains unpacker binary, source and samples used)

VN:F [1.9.13_1145]
Rating: +3 (from 3 votes)
Share
  1. SKmr0a I bookmarked this link. Thank you for good job!

    VA:F [1.9.13_1145]
    Rating: 0 (from 0 votes)