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.
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.|
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.|
|My guid? Maybe? Notice the BFP4F in the middle of it...|