Tuesday, June 26, 2012

Dumping PnkBstrK.sys

So I finally had a few hours to sit down and muck around in driver land tonight. I learned a few useful things about WinDBG which I kind of which I had known before. This reminds me I should probably read WinDBG A-to-Z from back to front (or front to back, sheash I've been in Japan too long) at some point.

Once again I started from the beginning and traced through the first IOCTL coming in. I tried to look for any sort of patterns but again my boredum got the best of me and I kind of gave up. One thing I know is that it is occuring in some sort of loop. I set a break point on the below address because it jumped back to this point a number of times in the code.
.reloc:EE05BB4E                 lodsb

For those who aren't aware, lodsb basically will take a byte out of ds:esi and store it in al (because we're doing a Load Store Byte). It then increments or decrements esi depending on the df (Direction Flag). By looking at the following code, sure enough eax appears to be a register of importance. One thing I realized I *should* have done, and probably will do once I get some more free time is to totally disregard all the stupid register operations that are going on in this loop and concentrate on one important factor.

When do the values of registers get *written* to locations in memory? This is a very important operation because this is what will give away what it is doing. I need to see if it's writing to the driver itself? (self modification) or writing to some objects in memory, or doing something else crazy. So this is really where I should have concentrated my efforts better. Instead I was 'getting a feel for it' also known as 'not having a fucking clue what I'm doing'.

So I set a breakpoint at the lodsb operation in the .reloc section to print out what exactly esi was pointing to. After a few bagillion operations I got a nice table of what byte it was pulling from esi and storing in al.
The command I ran was:
bp ee05e11d ".printf \"esi: %08x ds:esi: %08x\r\n\",esi,by(@esi); g"

This basically sets a break point and tells it to call the printf function displaying both what esi is, and the low-order byte that esi points to (note the 'by()' function). Then it tells it to continue running. So I got this enormous table which, is pretty friggen useless to me. While I'm sure if I had time I could script something up to recreate exactly what it is doing, I still hadn't looked at what it's doing with the value once it got into the al register.


So even though I am pretty tired of looking at this loop I will need to go back to it and look for any when registers are dereferenced or direct memory locations are referenced for mov or write operations. So I can see what it's modifying. This shouldn't be too hard I think, because from what I could tell it wasn't modifying the loop itself, just other parts of the driver.


So to do something a bit different I decided that maybe I should just dump the driver's memory while it's running during various IOCTLs and see if I can see any major changes. After a bit of searching I found out you can dump arbitrary memory by using the .writemem command. This takes addresses/ranges and will spit out the resultant bytes to a file. In my case I ran:
.writemem c:\temp\pnkbstrk_dump_ioctl1.sys 0xEE050000 0xEE073FF6 a few times with varying filename parameter values. The 0xee05000 is of course the base address and 0xee073ff6 is the end of the file.
i'm in ur memory, dumpin' ur codes.
So now I have three new driver files to look at. Oddly enough they look very different from the one from on disk and I'm not entirely sure why, but there's enough similarity in them to lead me to believe it's just what is in memory, so whatever. For example when the first IOCTL is called the DriverEntry function looks waaaaaaaaaay different then the one I'm working with in IDA (pulled from disk). Even though, I think, none of the self modification code has been called yet? If someone could explain how the hell this happened I'd appreciate it :>.

Anyways, the most striking difference I found is the relocation table/fix up code that I RE'd a while back. You may remember it was a series of 1000xxxx values that get rewritten to include the real address. Anyways here's what they look like side by side after the first IOCTL has been called.
yehp, symbol names.
The other thing I noticed was another area around this section of the driver that contained a very curious ID. So curious that I think it might be my GUID, the one that EvenBalance/PunkBuster use to global shit ban people. This is the first time I've seen it so I'm totally jumping to conclusions on that. Anyways, since that *may* give away who the hell I am, i'mma muck with it in the image below:
My guid? Maybe? Notice the BFP4F in the middle of it...
It's a 69 byte long string with BFP4F in the middle of it. The first section (before the BFP4F string) is 24 bytes, the second section (after the BFP4F) is 40 bytes. Both sections are stringified hex strings, as in a string representation of the hex bytes. So yeah, maybe two 32 byte md5 hashes with a BFP4F thrown in the middle to split them up? I dunno... yet!





Thursday, June 7, 2012

Tedious Boring Work (Obfuscation 1, Me 0)

I really do want to be posting more, and exploring more and learning more. But right now I'm stuck in state of tedium. The past few attempts at looking at PnkBstrK.sys have left me pretty bored. Right now the majority of the code is doing some sort of silly obfuscation and is just fixing up addresses and data. After the first IOCTL is sent to the driver, the IOCTL instructs the driver to fix up some table of addresses. In IDA we can see this table of pointers in it's base address form.
A table of pointers that are to be 'rebased' during execution
 You can see from my comments in the above code that various registers contain the address of the driver in memory, which in a below function are used to recalculate the table and update it to point to where the driver is loaded for the current execution run. This table, when all is said it is updated to look like:


ee05b844 ee05e046
ee05b848 ee05c997
ee05b84c ee05d719
ee05b850 ee05bc4d
ee05b854 ee05f5f1
...
ee05bad0 ee05c842
ee05bad4 ee05c049
ee05bad8 ee05f3e4
ee05badc ee05eff3
ee05bae0 ee05cc3c

While that part of the code is easy to understand, what isn't easy is the next part.
Borrrrrrrrrrrrrrrrrrringgg....
The rest appears to just be doing arithmetic to change various addresses both in the stack and in the registers. It's so boring and tedious that I find it hard to walk through more than a few functions at a time before I give up and go do something else.

I guess, that *would* be the entire point of obfuscation :>. However, I don't plan on giving up, but forgive me this might take a bit longer because, well, it's boring as shit. Someday when I have more free time (right now i'm clocking in about 1-2 hours a week looking at this) I'll sit down and run through the entire process to see if there are any patterns I can extract on what it is doing from a more high level view point.