IOCTL Input Buffer Content From Crash Dump + Windbg[BSOD]

Discussion on reverse-engineering and debugging.
Post Reply
debasishm89
Posts: 1
Joined: Mon Oct 15, 2012 7:41 pm
Contact:

IOCTL Input Buffer Content From Crash Dump + Windbg[BSOD]

Post by debasishm89 » Fri Mar 07, 2014 1:28 pm

Hi Guys,

I joined http://www.kernelmode.info few days back. First time i'm posting here. So here is my problem,

We all know user mode applications can pass IOCTL code and data buffer to kernel device drivers by calling DeviceIoControl() API.

Code: Select all

BOOL WINAPI DeviceIoControl(
  _In_         HANDLE hDevice,
  _In_         DWORD dwIoControlCode, <--Control Code
  _In_opt_     LPVOID lpInBuffer,  <- Input buffer pointer
  _In_         DWORD nInBufferSize, <- Input buffer size
  _Out_opt_    LPVOID lpOutBuffer,
  _In_         DWORD nOutBufferSize,
  _Out_opt_    LPDWORD lpBytesReturned,
  _Inout_opt_  LPOVERLAPPED lpOverlapped
);
I've a situation, where an user mode application sometime passing an IOCTL buffer to a Kernel driver and which is causing BSOD again and again. Every time i'm getting kernel memory dump for BSOD.

So my question is, is it possible to find the exact malformed input buffer and IOCTL code which causes the BSOD from the Kernel memory dump so that I can reproduce the BSOD using simple C prog.

As you can find from the stack trace, its crashing just after ntDeviceIoContrilFile call.

Code: Select all

kd> kb
ChildEBP RetAddr  Args to Child              
b8048798 805246fb 00000050 ffff0000 00000001 nt!KeBugCheckEx+0x1b
b80487e4 804e1ff1 00000001 ffff0000 00000000 nt!MmAccessFault+0x6f5
b80487e4 804ed0db 00000001 ffff0000 00000000 nt!KiTrap0E+0xcc
b80488b4 804ed15a 88e23a38 b8048900 b80488f4 nt!IopCompleteRequest+0x92
b8048904 806f2c0a 00000000 00000000 b804891c nt!KiDeliverApc+0xb3
b8048904 806ed0b3 00000000 00000000 b804891c hal!HalpApcInterrupt2ndEntry+0x31
b8048990 804e59ec 88e23a38 88e239f8 00000000 hal!KfLowerIrql+0x43
b80489b0 804ed174 88e23a38 896864c8 00000000 nt!KeInsertQueueApc+0x4b
b80489e4 f7432123 8960e9d8 8980b300 00000000 nt!IopfCompleteRequest+0x1d8
WARNING: Stack unwind information not available. Following frames may be wrong.
b80489f8 804e3d77 0000001c 0000001c 806ed070 NinjaDriver+0x1123
b8048a08 8056a9ab 88e23a8c 896864c8 88e239f8 nt!IopfCallDriver+0x31
b8048a1c 8057d9f7 89817030 88e239f8 896864c8 nt!IopSynchronousServiceTail+0x60
b8048ac4 8057fbfa 00000090 00000000 00000000 nt!IopXxxControlFile+0x611
b8048af8 b6e6a06f 00000090 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
b8048b8c b6e6a5c3 00000001 00000090 00000000 Ninja+0x506f
b8048c80 b6e6ab9b 00000001 88da9898 00000090 Ninja+0x55c3
b8048d34 804df06b 00000090 00000000 00000000 Ninja+0x5b9b
b8048d34 7c90ebab 00000090 00000000 00000000 nt!KiFastCallEntry+0xf8
00f8fd7c 00000000 00000000 00000000 00000000 0x7c90ebab
Thanks in Advance,

POPPOPRET
Posts: 2
Joined: Fri Aug 30, 2013 3:40 pm

Re: IOCTL Input Buffer Content From Crash Dump + Windbg[BSOD

Post by POPPOPRET » Tue Mar 25, 2014 5:06 pm

My suggestion would be to grab it from usermode. It is likely that this "Ninja" driver has an associated Device or Dos-Device name, which you could use to help target the usermode culprit (it will likely be a string in memory\disk). If you can figure out which usermode application is calling DeviceIoControl then you could quickly toss it into a dissassembler and find the import for DeviceIoControl. Navigate to that location, and check out the argument pushes and reverse engineer the function call parameters.

If you are in a kernel debugging environment, it is likely that the first/second addresses on your call stack belonging to "Ninja" are the IRP handler for the IOCTL. You could also breakpoint there, Grab symbols from msdn, and pretty easily view the buffer in memory.

My preference would be to get it from usermode. Especially since it sounds like your end goal is to recreate the situation from usermode. No need to complicate it by forcing yourself into the kernel.

That is probably how I would go about it. There are probably many other ways, the one that works best/easiest for you is going to depend on your environment/resources.

let me know if this helps!

-POPPOPRET

Sandstone
Posts: 1
Joined: Sun Sep 22, 2013 4:00 am

Re: IOCTL Input Buffer Content From Crash Dump + Windbg[BSOD

Post by Sandstone » Mon Jun 02, 2014 10:04 pm

I have been facing similar problems with a project I am working on. Here's my solution:

I downloaded this application from Nirsoft http://www.nirsoft.net/utils/device_io_view.html
From what I can tell it globally hooks all IOCTL requests and displays them in the application. Now, this may not work for you due to the fact that you get a BSoD when this function reaches the kernel.
So, as an alternative I suggest you run your program in a debugger and place a breakpoint at NtDeviceIoControlFile.
If you have IDA or something similar, you should load disassemble Ninja+0x506f to find how the arguments are being passed to DeviceIOControl. (Depending on if you are x64 or x86 I think the calling convention differs for stdcall)
So, now you should have the data, and you should also be able to see the Control Code and Input Buffer.

Now, to reproduce it in a seperate program is the difficult part, be prepared to walk undocumented and proprietary structures that the driver uses.
So, if your input buffer is a memory address, you may have a lot of work ahead of you, otherwise you are good to go to reproducing the BSoD.
If it's a memory address, you have two options. You can try to replicate whatever structure is being used and hope that it is not complex, or you can try to reverse the driver itself instead, and see where in it's parsing of the structure that the BSoD is caused.

Assuming you have done the correct Input Buffer
Make sure the driver is loaded. Either load it yourself with CreateService+StartService, or use sc. Now that it's loaded open a handle to the driver:

Code: Select all

HANDLE Device = CreateFile(_TEXT("\\\\.\\deviceName"), GENERIC_READ | GENERIC_WRITE,
			     0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
Now you can attempt to use DeviceIOControl.

I hope that this helped.

Post Reply