Log in

View Full Version : Had to say (Driver Debugging Basics)


/db/
November 23rd, 2011, 19:33
I know these are old tutorials ( i believe ) but over-reading them and modernizing it a bit has helped me so much more with understand ASM in a general aspect.
http://www.woodmann.com/RCE-CD-SITES/Quantico/mib/tutor.htm

Also I have been playing around with IDA Pro and OllyDbg (I use a Vista 32x virtual enviroment to play) I was curious about what other useful tools there are,
or any other hints I should go on about? I been doing the "cruehead" crackme's.

I was once into them before, but I was too young to comprehend any of it and stuck to nooby memory editting lol, my friend BanMe (the one on this board here) had tried to show me the light but I was incapable at the time of following, but now I see - and I see more than I ever thought I could imagine.

So fellow reversers', I would love to hear any advice, tool tips, and anything available to offer my brain :3

I have dabbled in C++, C#, but recently been getting into Perl, but reversing has got my heart hooked now, and I want more! (x

PS;; this has honestly been the only place I have turned to for RCE knowledge. >_<

Kayaker
November 25th, 2011, 00:33
Hi

It all depends on what you want to do. There are a ton of things to get into reversing related, and you never stop learning no matter how long you play the game.

At some point you might want to delve into ring 0, kernel mode, either to study an advanced malware or protection, or to learn about Windows internals, or to write your own driver for nefarious or otherwise purposes, or simply to find out where the hell that API goes when OllyDbg craps out on the tracing. (It was the latter that got me interested in kernel mode, I hate 'black boxes'

The easiest way to trace into ring 0, though some would say the most archaic, is to install Softice in an XP virtual environment and simply keep single stepping any old program into kernel mode past where a ring 3 debugger would halt. If that might be of interest to you. There's a whole other world in there.

A more modern and generally useful approach since you're interested in learning the tools, is to create a remote debugging environment using WinDbg and a VM. These 2 articles explain how to set that up:

Remote Debugging using VMWare
http://www.catch22.net/tuts/vmware

Driver Debugging with WinDbg and VMWare
http://silverstr.ufies.org/lotr0/windbg-vmware.html


And VirtualKD will make the whole experience more pleasant by speeding everything up:

http://virtualkd.sysprogs.org/

That should keep you busy for a little while

Cheers,
Kayaker

Elenil
November 25th, 2011, 22:44
softice is keeping alive it seems ^^ ?

/db/
November 27th, 2011, 19:48
You definitely have caused my schedule to become very busy via ring0. -___-
Edit:**
One thing that's been a problem with me was connecting via com1 remotely to Virtualbox via Windbg (Guest OS is Vista)
I keep getting a "Debugee not conected" error after a neat
Opened \\.\pipe\com_1
Waiting to reconnect...
I know I am probably overlooking something simple but I have tried different methods and its still giving me the connection problems.
I also tried VirtualKD but that didn't work crap for me, and knowing how they change the baud rate or whatever to speed up the connection is just simple in itself so its effortless, but getting that remote kernel debug connection just is not working for me. =[

ZaiRoN
November 28th, 2011, 09:42
If you want to avoid remote debugging you can also try Syser debugger...

Kayaker
November 28th, 2011, 19:44
I couldn't even begin to guess what the problem might be with that particular setup. I'm sure you've googled for things to try, such as this

https://www.virtualbox.org/wiki/Windows_Kernel_Debugging

VirtualKD does a lot more than just change the baud rate. Ideally it should work out of the "box" so to speak, setting everything up for you if you follow the instructions closely for VirtualBox. If you have specific problems with it you could always ask in the SysProgs forums.

Maybe someone else has had success with a similar setup to yours...

/db/
November 29th, 2011, 18:24
this is going to be a perfect example of why I posted in the "newbie" forum.

i finally got it my ring0 remote debugging working perfectly with windbg, virtualbox, and virtualkd as the amazing Kayaker has mentioned and I have to agree virtualkd does make it seem a lot faster, i hope i learn its other features soon. i haven't done anything extremely great yet but i plan to continue to learn more now that i got this access, which is going to be fun crashing windows ulitmately buwahahah. jk :P now its time to play with some nasty malware c:

ty Kayaker for the suggestion, plus the site you linked last to did not FIX the problem per se - it did make me realise something. virtualbox says it can use 1394 fireware or w/e to make it faster but the virtualkd works much better going the route it suggests.

my PROBLEM ; i couldn't get my debugger to connect - lulz.
the SOLUTION/WHY ; the guest OS was 32bit but i was using the 64bit virtualkd monitor to try and connect.
ignorant i know but in my defense i just assumed that the vmmon64.exe was for 64bit machines regardless of guest OS! XD

anyways fun times ahead, this ring0 debugging is very informational, thank you guys for helping me fall into this newly found obsession. Seriously, my 2 yr old lil girl is in my lap having fun with me. :3

Kayaker
November 30th, 2011, 23:14
I hope your daughter doesn't get nightmares from seeing the inside of Windows, many people do

You asked me for some ideas as to where to go from here. If you want to reverse drivers you'll need to understand driver structure. The best way is to create your own driver skeleton, disassemble it so as to recognize standard constructs in assembly, learn WinDbg methods of tracing it, etc.

I think one of the best summaries of driver structure is an old tutorial written by one of our members:

Kernel Mode Driver Tutorial: Part I: The Skeleton KMD by Clandestiny
http://www.reverse-engineering.info/SystemCoding/SkeletonKMD_Tutorial.htm
or
http://www.woodmann.com/forum/attachment.php?attachmentid=747&d=1062490066

Other excellent resources:

Device Driver Development for Beginners - Reloaded
http://www.kernelmode.info/forum/viewtopic.php?f=14&t=374

Making your first driver - complete walkthrough
http://articles.sysprogs.org/visualddk/firstdriver/

System Coding
http://www.reverse-engineering.info/documents/31.html

Kernel Mode Driver Development Kit for MASM32 programmers
http://www.freewebs.com/four-f/



Here's an example of what you could do. For arguments sake lets say you wanted to trace the IOCTL codes (the usermode/kernelmode communication) for beep.sys. Start up your WinDbg/VM and display the DRIVER_OBJECT details for beep.sys with extended flag information.

Code:

kd> !drvobj beep 7
Driver object (8c6299e0) is for:
\Driver\Beep

DriverEntry: 8e56e03e
DriverStartIo: 8e56b248
DriverUnload: 8e56b2c6

Dispatch routines:
[00] IRP_MJ_CREATE 8e56b1ac
..
[02] IRP_MJ_CLOSE 8e56b1fe
..
[0e] IRP_MJ_DEVICE_CONTROL 8e56b116


For IOCTL codes we are interested in the IRP_MJ_DEVICE_CONTROL Dispatch routine function address. So let's set a breakpoint on that address and trigger a beep and see what happens.

Code:
kd> bp 8e56b116


Type Ctrl-G in a command window in the VM and press Enter and it should beep. Don't ask me why, I just found that on the net. You could also use the funky NirCmd utility to create a beep and it should also work.

http://www.nirsoft.net/utils/nircmd.html

Windbg should break and you'll see this:

Code:

...
8e56b11b 8b4d0c mov ecx,dword ptr [ebp+0Ch]
8e56b11e 8b4160 mov eax,dword ptr [ecx+60h]
8e56b121 8b500c mov edx,dword ptr [eax+0Ch]
8e56b124 81ea00000100 sub edx,10000h
8e56b12a 56 push esi
8e56b12b 743c je 8e56b169


Those first 3 lines are important and you'll see them in various guises in the majority of drivers, but we need to understand them.

Disassemble beep.sys in IDA and find the function, which tells us that the first structure of interest is an _IRP

Code:

:00011116 ; int __stdcall BeepDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
:00011116 _BeepDeviceControl@8 proc near ; DATA XREF: DriverEntry(x,x)+BE
:00011116
:00011116 DeviceObject = dword ptr 8
:00011116 Irp = dword ptr 0Ch
:00011116
...
:0001111B mov ecx, [ebp+Irp] ; Irp
:0001111E mov eax, [ecx+60h]
:00011121 mov edx, [eax+0Ch]
:00011124 sub edx, 10000h
:0001112A push esi
:0001112B jz short loc_11169



Look at the definition of _IRP in the WinDDK wdm.h file, or Clandestiny's tutorial and try to figure out what is at the offset [ecx+60h] (PIRP+60h).

You could also use WinDbg. Trace past the line 8e56b11b and type

Code:

kd> dt nt!_IRP @ecx -r
+0x000 Type : 0n6
+0x002 Size : 0x94
...
+0x040 Tail : <unnamed-tag>
+0x000 Overlay : <unnamed-tag>
...
+0x020 CurrentStackLocation : 0x8ba04898 _IO_STACK_LOCATION


[ecx+60h] is therefore _IO_STACK_LOCATION.

In code this would be equivalent to

Code:

PIO_STACK_LOCATION IrpStack;

// Get pointer to IRP stack location
IrpStack = IoGetCurrentIrpStackLocation( Irp );




The next line we must parse is [eax+0Ch], or PIO_STACK_LOCATION + 0Ch. In this case the definition of the offset 0Ch is a union, the exact meaning being dependant on the service being invoked. In our case it's DeviceIoControl and we can work out from the structure definitions that offset 0Ch is IoControlCode.

Code:

ULONG ioControlCode = IrpStack->Parameters.DeviceIoControl.IoControlCode;



I know that's a lot of theory for 3 little lines, but now we've been able to interpret the code so we know that EDX contains the IOCTL code being passed from usermode through the DeviceIoControl API. From here we can just trace logically to wherever the code takes us to each of the individual functions.


btw, a handy trick for static disassembly is to add the IRP and IO_STACK_LOCATION structure definitions in IDA and use them to name the structure offsets, it would look like this.

Code:

:0001111B mov ecx, [ebp+Irp] ; Irp
:0001111E mov eax, dword ptr [ecx+IRP.Tail.Overlay.anonymous_1.anonymous_0]
:00011121 mov edx, [eax+IO_STACK_LOCATION.Parameters.DeviceIoControl.IoControlCode]




Just so you don't think it's always this straightforward, say we do the same thing with Process Explorer:

Code:

kd> !drvobj procexp100 7
Driver object (8b8e6488) is for:
\Driver\PROCEXP100

Dispatch routines:
[00] IRP_MJ_CREATE 9bbfcd46
..
[02] IRP_MJ_CLOSE 9bbfcd46
[..
[0e] IRP_MJ_DEVICE_CONTROL 9bbfcd46


Notice that all 3 IRP_MJ functions have the same address. This is a common way of writing a driver, unlike the beep.sys example. Breakpoint on that address and you'll see familiar code, plus a switch statement line pointing the way to IRP_MJ_DEVICE_CONTROL:

cmp dl,0Eh // [0e] IRP_MJ_DEVICE_CONTROL


If you wish, take a look at the driver source code in my latest blog post to see how that is constructed:

Code:

// Dispatch on MajorFunction
switch (IrpStack->MajorFunction)
{
// Default these two IRPs
case IRP_MJ_CREATE:
case IRP_MJ_CLOSE:
break;

case IRP_MJ_DEVICE_CONTROL:

// Handle the GUI IOCTL requests




Well I've beat that to death like a rented mule... Enough for now.

Kayaker

/db/
December 10th, 2011, 13:34
Quote:
[Originally Posted by Kayaker;91470]Well I've beat that to death like a rented mule... Enough for now.

Kayaker


For starters, my daughter enjoys it for some odd reason >_>
Secondly, "that" must refer to my mind because it did.
I will definitely be following into that to see how it goes though :P