Archived Blog
Previous Posts
June 2007+ May 2007
+ April 2007
+ March 2007
+ February 2007
+ January 2007
The packer itself uses a few tricks to prevent (or try to prevent) reversing, but overall, it's rather trivial. I will present the packer, explain how to bypass the anti-dumping trick, and show how to have a nice disassembly of the executable, even if the application (and I am not talking about the packer here) uses dynamic API function resolution.
1) BPX Check:
The packer checks for 0xCC on function entry, but in an "obfuscated" way:
A trained eye will spot this check in a second. ESI is pointing to ExitProcess, and the packer fetches the first byte of the function, subtracts 0x34 and checks to see if the result is equal to 0x98. Obviously, 0x98 + 0x34 = 0xCC, which is the int 3, also known as the software breakpoint opcode.
2) ExitProcess Patch
I am not really sure why the author does this, probably to trick emulators.
The packer moves 0x900004C2 into ESI (once again, a trained eye will recognize NOP RET 4) and exchanges DWORD PTR [EDI] (pointing to ExitProcess) with ESI.
At this point, ExitProcess starts with RET 4 / NOP.
The packer then calls ExitProcess, which doesn't do anything besides returning to the next instruction. The original bytes are restored, in order to have a working ExitProcess.
The packer then checks whether the third and fourth bytes of ExitProcess are 0x558B. You will crash eventually, if this isn't the case. (0x558B is PUSH EBP and start of MOV EBP, ESP).
3) Anti-Dump
Once it is unpacked in memory, you cannot dump it with any of the popular process dumpers. They will report that they cannot access memory. If you look at the IMAGE SECTION HEADERS you will see this:
The last section's characteristics are "0x00000000", which is basically PAGE_NO_ACCESS. The last page of the process has the no access attributes, so any process dumper trying to dump every page (szeofimage) will fail.
A very easy way to bypass the anti-dump is to change the characteristics of this section. Read Access should be enough, but I used PAGE_READWRITE_EXECUTE. With that change, any process dumper will work on the file. You could also use Ollydbg memory manager to change the page attributes on the fly.
4) Analyzing NTOS.EXE
NTOS.EXE uses dynamic API function resolution; therefore, the original import table is rather small. Note that I am not talking about the packer anymore here; it imports only one function from USER32, but NTOS has imported functions from kernel32, oleaut32, and WS2_32.DLL. Most of the other functions are resolved at runtime, and your disassembly isn't really helpful, unless you rename every DWORD, with an IDC or manually.
There is another easy way to get a nice disassembly. If you use ImpRec (Import Reconstructor), you can generate a "fake" import table from the dynamic array the malware is creating. Because the malware isn't really generating an IAT, but just filling an array of Windows functions for its own use, there will be no NULL DWORDs between DLL functions. You cannot generate a new import table unless all the DLLs are separated with a NULL DWORD. To fix this issue, I used "cut thunks" on DLL boundaries and removed one function for every DLL (about 7 functions in all), to be able to generate a new import table:
Now if you open your file again in IDA Pro, you will get such a nice disassembly:
You will need to fix only the 7 functions you removed, by renaming the DWORDs in IDA, and your disassembly will be perfect.
Researcher: Nicolas Brulez




























