Monday, July 12, 2010

Driver Programming in Windows (Hello World Programing )

Note: This really isn't a tutorial. I would strongly suggest that you read all of James Brown's tutorials which do a much better job of *explaining* this stuff.
Pre-requisites (all free downloads)
The latest Windows Driver Kit installed. I pulled a copy from one of our internal shares but I just found out that it is now a free download as well (you could only get it shipped to you in the past).
Microsoft Virtual PC. This is to let me test my driver without having to get another machine and finding the right cable to go between them (I'm just lazy). Modifying this tutorial to work with a real machine is pretty trivial.
Debugging Tools for Windows. Visual Studio cannot do kernel-mode debugging and hence you need to use the WinDBG/NTSD/CDB family of debuggers.
Windows XP/2003/Vista installed on VPC. In my case, I have a Win2k3 VPC but depending on which operating system you have, pick the right build environment in the 'Build your driver' section below.
Code for your driver
1. Create a directory where your driver sources will lie. For the following example, all my source files will lie in C:\testdrv

2. Create a file called test.c with the following contents. This is as simple a driver as you can get (in fact, it doesn't even know how to unload itself). When started, it prints a 'Hello World' message which any attached kernel debugger or DbgView will see.#include NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath) { DbgPrint("Hello World\n"); return STATUS_SUCCESS;}
3. Create a file called makefile.def with the following line it it. This pulls in the appropriate makefile for your build environment (more on that later). !INCLUDE $(NTMAKEENV)\makefile.def
4. Create a file called sources (note that it doesn't have any extension) with the following contents. This specifies which source files you are compiling, that it will build a driver and the headers and lib files to use.
TARGETNAME = testTARGETPATH = objTARGETTYPE = DRIVER
INCLUDES = %BUILD%\incLIBS = %BUILD%\lib
SOURCES = test.c

Building your driver
1. Click on Start->All Programs->Windows Driver Kits->WDK 6000->Build Environments->Windows Server 2003->Windows Server 2003 x86 Checked Build. I'm picking this since I have a 32-bit Win2k3 VPC - pick the one which matches the closest with your target machine. For example, if you have a physical Windows Vista x64 machine you want to try out your driver on, you would pick 'Windows Vista and Windows Server Longhorn x64 Checked Build Environment'.
This drops you into a command prompt with some nice environment variables (your build environment) already set for you.

2. Change to the directory which has your driver source and run 'build'. This invokes build.exe , the de-facto Microsoft build tool for almost two decades until MSBuild came on the scene (and even now, a lot of product groups still use build.exe). Written by Steve Wood over 15 years ago, this is one tool that has withstood the test of time :-) 1 If you've followed along well, you should see a test.sys and a test.pdb (along with other files) in your object build directory.

Setting up your target machine for kernel debugging
1. To attach a kernel debugger to a running instance of Windows, you need to do some minor configuration. In the target VPC Win2k3 instance, go to My Computer->Properties->Advance->Settings under Startup and Recovery->Edit. You should see a line like multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Windows Server 2003, Enterprise" /fastdetect /NoExecute=OptOutAdd "/debug /debugport=com1" to the line above (without the quotes).If you're using Windows Vista as your target operating system, you can't use this technique - you'll have to use the inbuilt bcdedit.exe utility.
2. In the virtual machine's settings, redirect the COM port to a pipe called http:////pipe/vpc . What we're doing here is telling Windows to redirect all debug spew to the COM1 port and then telling VPC to redirect COM1 to a named pipe.
3. Restart the virtual machine (the boot settings need a restart to kick in).
4. One final step - running the kernel debugger! Run windbg with the following command-line (if you already have symbols setup correctly, ignore the -y parameter).
windbg-y SRV*c:\symbols*http://msdl.microsoft.com/download/symbols -k com:pipe,port=\\.\pipe\vpc,resets=0,reconnect
This should open up windbg and connect it to your running instance of Win2k3 on VPC.

Registering and running your driver
Whew. Just a couple of steps more and we'll be home. The last 2 things for us to do are to register the driver and then to run it. Our driver currently cannot be unloaded (the ability to do so would just require 4 more lines of code though) so you'll have to restart the machine manually to see new changes reflected.
1. First, let's register the driver. James Brown's tutorial covers some of the ways you can register the driver but (like him), I'll recommend downloading the 'Driver Loader' utility from http://www.osronline.com/ which unfortunately requires a free registration. Run it on your target Win2k3 VPC
2. Copy your drivers' binaries over to the VPC (I typically do this using the shared folder feature). Point Driver Loader to your binary and register your driver. This needs to be done only once irrespective of how many times you rebuild your binaries.
If you've followed along so far, congratulations for you're finally home. Hit 'Start Service' in 'Driver Loader'. This should result in a call to your DriverEntry method and in your WinDBG running on the host computer, you should see this To quote John McClane, Yippie-Ki-ay !From here, it is pretty trivial to start exploring. Here's a screenshot of a breakpoint in my DriverEntry routine (the WRK stuff is because I'm running a custom Windows kernel built from the publicly available Windows Research Kernel code).
Happy hacking!

Notes
1. If you're interested in the internals of build.exe, you should check out the code that ships with Rotor (online cached copy here). However, I haven't checked to see whether it is from the same code base as the real build.exe.

1 comment:

  1. Harrah's Resort Atlantic City - MapYRO
    Find 구리 출장샵 hotels near 제주도 출장안마 Harrah's Resort Atlantic City in real-time and 울산광역 출장안마 see activity. 777 강원도 출장안마 Harrah's Blvd, Atlantic City, NJ 08401, US | 밀양 출장안마 MapYRO

    ReplyDelete