date: 2015-05-21
Having figured out how to deploy the skeleton KMDF project and step through the code, and after learning how to implement the callbacks recommended as per http://www.adlice.com/making-an-antivirus-engine-the-guidelines/
I attempted to grab the file paths of new processes / images etc and begin by generating the sha256 hashes. however I had hit a roadblock in that some of the header files that would make this easy, like windows.h for PBYTES are not allowed in the KMDF framework, but are in the UMDF2.0.
Now I have to go figure out either a method for inter driver communications or if UMDF2.0 is high enough to request callbacks, that can also block new processes when required.
For now, I’ll throw in some of what I have changed to get the callbacks working. The two files in the skeleton KMDF project I modified are below, I’ve surrounded then with comments and regions but you can always use winmerge to highlight the changes I’ve made.
Driver.c
/\*++
Module Name:
driver.c
Abstract:
This file contains the driver entry points and callbacks.
Environment:
Kernel-mode Driver Framework
\--\*/
/\* ########################################
######### Kempy's Notes ################
###########################################
hit F7 on solution which will install driver.
right click driver project > debug > step into new instance
request a break.
kd> lm
only nt listed so run
kd> .reload
wait for ages, rerun lm
kd > lm
should list pages of modules.
then set my break points on code view.
f5 to continue
Often have to use debugger commandline to disable breakpoints etc.
windows 8.1 kit includes bcrypt.h, option to explore for hashing functions also referred to as CNG cryptography Next Generation.
\*/
#include "driver.h"
#include "driver.tmh"
#ifdef ALLOC\_PRAGMA
#pragma alloc\_text (INIT, DriverEntry)
#pragma alloc\_text (PAGE, KMDFDriver3EvtDeviceAdd)
#pragma alloc\_text (PAGE, KMDFDriver3EvtDriverContextCleanup)
#endif
NTSTATUS
DriverEntry(
\_In\_ PDRIVER\_OBJECT DriverObject,
\_In\_ PUNICODE\_STRING RegistryPath
)
/\*++
Routine Description:
DriverEntry initializes the driver and is the first routine called by the
system after the driver is loaded. DriverEntry specifies the other entry
points in the function driver, such as EvtDevice and DriverUnload.
Parameters Description:
DriverObject - represents the instance of the function driver that is loaded
into memory. DriverEntry must initialize members of DriverObject before it
returns to the caller. DriverObject is allocated by the system before the
driver is loaded, and it is released by the system after the system unloads
the function driver from memory.
RegistryPath - represents the driver specific path in the Registry.
The function driver can use the path to store driver related data between
reboots. The path does not store hardware instance specific data.
Return Value:
STATUS\_SUCCESS if successful,
STATUS\_UNSUCCESSFUL otherwise.
\--\*/
{
WDF\_DRIVER\_CONFIG config;
NTSTATUS status;
WDF\_OBJECT\_ATTRIBUTES attributes;
//
// Initialize WPP Tracing
//
WPP\_INIT\_TRACING( DriverObject, RegistryPath );
TraceEvents(TRACE\_LEVEL\_INFORMATION, TRACE\_DRIVER, "%!FUNC! Entry");
//
// Register a cleanup callback so that we can call WPP\_CLEANUP when
// the framework driver object is deleted during driver unload.
//
WDF\_OBJECT\_ATTRIBUTES\_INIT(&attributes);
attributes.EvtCleanupCallback = KMDFDriver3EvtDriverContextCleanup;
WDF\_DRIVER\_CONFIG\_INIT(&config,
KMDFDriver3EvtDeviceAdd
);
status = WdfDriverCreate(DriverObject,
RegistryPath,
&attributes,
&config,
WDF\_NO\_HANDLE
);
if (!NT\_SUCCESS(status)) {
TraceEvents(TRACE\_LEVEL\_ERROR, TRACE\_DRIVER, "WdfDriverCreate failed %!STATUS!", status);
WPP\_CLEANUP(DriverObject);
return status;
}
#pragma region kempy\_register\_callbacks
/\*##############################################
########### Add my own callbacks here #########
\*/
status = PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, FALSE);
status = PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx, FALSE); // added this and driver is getting code 37, access denied.
// have created a driver certificate now, which did not help
// Added to driver properties 'configuration properties' > 'linker' > 'command line', 'additional options' /INTEGRITYCHECK
// integritycheck option fixed driver loading error!
/\*##### end section ####
########################
\*/
#pragma endregion
TraceEvents(TRACE\_LEVEL\_INFORMATION, TRACE\_DRIVER, "%!FUNC! Exit");
return status;
}
NTSTATUS
KMDFDriver3EvtDeviceAdd(
\_In\_ WDFDRIVER Driver,
\_Inout\_ PWDFDEVICE\_INIT DeviceInit
)
/\*++
Routine Description:
EvtDeviceAdd is called by the framework in response to AddDevice
call from the PnP manager. We create and initialize a device object to
represent a new instance of the device.
Arguments:
Driver - Handle to a framework driver object created in DriverEntry
DeviceInit - Pointer to a framework-allocated WDFDEVICE\_INIT structure.
Return Value:
NTSTATUS
\--\*/
{
NTSTATUS status;
UNREFERENCED\_PARAMETER(Driver);
PAGED\_CODE();
TraceEvents(TRACE\_LEVEL\_INFORMATION, TRACE\_DRIVER, "%!FUNC! Entry");
status = KMDFDriver3CreateDevice(DeviceInit);
TraceEvents(TRACE\_LEVEL\_INFORMATION, TRACE\_DRIVER, "%!FUNC! Exit");
return status;
}
#pragma region kempy\_callback\_routines
/\*###########################################################
############# drop in callback routines here ##############
\*/
VOID CreateProcessNotifyRoutine(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create) {
PAGED\_CODE();
DbgPrint("CreateProcessNotifyRoutine called with ParentId = 0x%p, ProcessId = 0x%p, Create = %d\\n",
ParentId,
ProcessId,
Create);
}
VOID CreateProcessNotifyRoutineEx(IN OUT PEPROCESS Process,
IN HANDLE ProcessId,
IN OPTIONAL PPS\_CREATE\_NOTIFY\_INFO CreateInfo) {
PAGED\_CODE();
UNREFERENCED\_PARAMETER(CreateInfo);
DbgPrint("CreateProcessNotifyRoutineEx called with Process = 0x%p, ProcessId = 0x%p\\n",
Process,
ProcessId);
}
/\*##### end section ####
########################
\*/
#pragma endregion
VOID
KMDFDriver3EvtDriverContextCleanup(
\_In\_ WDFOBJECT DriverObject
)
/\*++
Routine Description:
Free all the resources allocated in DriverEntry.
Arguments:
DriverObject - handle to a WDF Driver object.
Return Value:
VOID.
\--\*/
{
UNREFERENCED\_PARAMETER(DriverObject);
PAGED\_CODE ();
#pragma region Kempy\_cleanup\_section
/\*####################################################
########### cleanup my own callbacks here. #########
\*/
PsSetCreateProcessNotifyRoutine(CreateProcessNotifyRoutine, TRUE);
PsSetCreateProcessNotifyRoutineEx(CreateProcessNotifyRoutineEx, TRUE);
/\*##### end section ####
########################
\*/
#pragma endregion
TraceEvents(TRACE\_LEVEL\_INFORMATION, TRACE\_DRIVER, "%!FUNC! Entry");
//
// Stop WPP Tracing
//
WPP\_CLEANUP( WdfDriverWdmGetDriverObject(DriverObject) );
}
Driver.h
/\*++
Module Name:
driver.h
Abstract:
This file contains the driver definitions.
Environment:
Kernel-mode Driver Framework
\--\*/
#define INITGUID
#include
#include
#include "device.h"
#include "queue.h"
#include "trace.h"
//
// WDFDRIVER Events
//
DRIVER\_INITIALIZE DriverEntry;
EVT\_WDF\_DRIVER\_DEVICE\_ADD KMDFDriver3EvtDeviceAdd;
EVT\_WDF\_OBJECT\_CONTEXT\_CLEANUP KMDFDriver3EvtDriverContextCleanup;
#pragma region kempy\_declare\_functions
/\*##############################################
########### Declare Functions #########
\*/
VOID CreateProcessNotifyRoutine(IN HANDLE ParentId, IN HANDLE ProcessId, IN BOOLEAN Create);
VOID CreateProcessNotifyRoutineEx(IN OUT PEPROCESS Process, IN HANDLE ProcessId,
IN OPTIONAL PPS\_CREATE\_NOTIFY\_INFO CreateInfo);
/\*##### end section ####
########################
\*/
#pragma endregion