Tuesday, July 10, 2012

Dumping PnkBstrK.sys Part 2: Fixing it up!

You may remember from my last post that I was able to dump PnkBstrK.sys from memory but it "looked weird". As in the addresses, even after I rebased the image in IDA to make them look right, were showing up incorrectly. After a bit of work I've figured out not only why but also how to get a module/driver/dll that was dumped from memory to "look right" in IDA.

You may remember from the PECOFF specification that the sections of a PE file have some meta-data associated with them. In particular the IMAGE_SECTION_HEADER. This section has the name, the VirtualSize, address of the section in the image as well as the address of where it will be when the image loads, also known as the VirtualAddress. This is the important part. Because what is on disk versus what is loaded into memory is quite different due to section alignment. Here's what the files look like side-by-side in 010editor.

The difference between the file from disk (left) and the one dumped from memory (right)

You'll notice in the above image there's a large section of null bytes that doesn't exist in the file from disk. This is due to the value of the VirtualAddress section of the PE file for each section. It basically is aligned at 0x1000 so it injects a bunch of null bytes by the loader. If you attempt to load the file as is into IDA Pro you'll get something that looks like the below image.

The file that was dumped from memory, rebased, but the DriverEntry is totally wrong.

When I first loaded it, the DriverEntry point was totally off. That's because IDA Pro is reading the PointerToRawData value of the PE file metadata struct and assuming that the entry point is where it says it is: at 0x400 in the case of the .text section. This of course is wrong because the dump from memory was aligned differently (adding about 0xc00 of null bytes). With that mystery finally solved (after much head banging, I assure you.) I fixed the PointerToRawData values for each section in 010editor.

Fixing the values for each section for (updating PointerToRawData values)

I then attempted to reload the dumped driver into IDA for analysis again. At first I tried to rebase on load (again selecting the "Manual Load" and "Load resources" check boxes) but that turned out to be incorrect as well, as you can see below.

Looks "ok" but some offsets are pointing to the wrong place!

This was annoying as I wasn't really sure how to fix this problem. After mucking around for a while in IDA Pro's rebasing abilities (Edit -> Segments -> Rebase program...) I found if I unchecked the 'Rebase the whole program' I'd get a proper load with all offsets pointing to the right part of the PE file.

After all that, I finally got the driver dumped from memory to look like the one extracted from the disk.

The image with all sections correctly resolved and displayed.

And that's pretty much it! Now I know how to dump drivers directly from memory and fix them up to be able to analyze with IDA Pro easier. Hope this saves someone the headache!