Windows Drivers

From Ggl's wiki

Jump to: navigation, search

Big kudos to Greg Hoglund and Jamie Butler for their works on rootkit and their book "Rootkit: Subverting the Windows Kernel" for which I learn a lot and inspired this article.

Contents

Working environment

Basically you need the Windows DDK (actually, Download the Windows Server 2003 SP1 DDK ISO file), and to create a clean source tree (taken from Hoglund's basic_1.zip archive):

basic_1\
  basic.c
  MAKEFILE
  SOURCES

basic_1 is the driver basic templace below.

SOURCES contains:

TARGETNAME=basicrk_1
TARGETPATH=OBJ
TARGETTYPE=DRIVER # Choose between DRIVER, PROGRAM, EXPORT_DRIVER, DRIVER_LIBRARY, DYNLINK
#TARGETLIBS=
SOURCES=basic.c 

MAKEFILE contains:

!INCLUDE $(NTMAKEENV)\makefile.def

Driver basic template

#include "wdm.h"

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
	DbgPrint("OnUnload called\n");
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
	DbgPrint("I loaded!");

	theDriverObject->DriverUnload  = OnUnload; 

	return STATUS_SUCCESS;
}

MSDN tells that the function protoype is:

DriverEntry is the first routine called after a driver is loaded, and is responsible for initializing the driver.

NTSTATUS 
  DriverEntry( 
    IN PDRIVER_OBJECT  DriverObject, 
    IN PUNICODE_STRING  RegistryPath 
    ); 

  • Parameters
DriverObject
Caller-supplied pointer to a DRIVER_OBJECT structure. This is the driver's driver object.
RegistryPath
Pointer to a counted Unicode string specifying the path to the driver's registry key.
Return Value
If the routine succeeds, it must return STATUS_SUCCESS. Otherwise, it must return one of the error status values defined in ntstatus.h.
  • Headers
Declared in wdm.h. Include wdm.h or ntddk.h.


Build the driver

Ok, now start a checked (Free is meant for production release e.g. no debug) build environment (in Start > Programs > Developement Kits ...)

Go into basic_1 directory and type build. Now you have a driver in objchk_wxp_x86\i386 with the name basicrk_1.sys.

Load the driver

Fine, we have built our basic driver but now we need to load it.

There are several ways to load a driver. I describe the common: using Service Control Manager (SCM). SCM provides management capabilities to drivers e.g. automatic loading, on demand, start, stop, etc ...

There are three main steps to load a driver:

  • Open the SCM
  • Create the service associated with the driver
  • Start the driver

Opening the SCM

For this purpose, we use the OpenSCManager() function which establishes a connection to the service control manager on the specified computer and opens the specified service control manager database.

SC_HANDLE WINAPI OpenSCManager(
  LPCTSTR lpMachineName,
  LPCTSTR lpDatabaseName,
  DWORD dwDesiredAccess
);

So, we use this functin like that:

SC_HANDLE sh = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);

Creating the service

We use the CreateService() function which creates a service object and adds it to the specified service control manager database.

SC_HANDLE WINAPI CreateService(
  SC_HANDLE hSCManager,
  LPCTSTR lpServiceName,
  LPCTSTR lpDisplayName,
  DWORD dwDesiredAccess,
  DWORD dwServiceType,
  DWORD dwStartType,
  DWORD dwErrorControl,
  LPCTSTR lpBinaryPathName,
  LPCTSTR lpLoadOrderGroup,
  LPDWORD lpdwTagId,
  LPCTSTR lpDependencies,
  LPCTSTR lpServiceStartName,
  LPCTSTR lpPassword
);

We use it as the following:

SC_HANDLE rh = CreateService(

sh, DriverName, DriverName, SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, aPath, NULL, NULL, NULL, NULL, NULL);

with

DriverName
The name of the driver. Typically a copy of a command line argument or a option.
aPath
A string that represents the path the driver file.

Starting the driver

Last step is is to start the service, in this case to actually load the driver.

For this purpose we use the StartService() function :

BOOL WINAPI StartService(
  SC_HANDLE hService,
  DWORD dwNumServiceArgs,
  LPCTSTR* lpServiceArgVectors
);

In the code we call:

StartService(rh, 0, NULL)
Personal tools