- Load-driven standard square law is only one, is the use of the service manager function to load ---- SCM loading method.
WIN64 driver template
// [0] contains the file header. Can be added to the system or their own definition of header files #include <ntddk.h> #include <WINDEF.H> #include <stdlib.h> // [1] definition of a symbolic link, in general, you can modify the name of the driver # dEFINE DEVICE_NAME L "\\ \\ KrnlHW64 Device" #define link_name L "\\ \\ KrnlHW64 DosDevices" #define LINK_GLOBAL_NAME L "DosDevices \\ \\ \\ KrnlHW64 Free Join" // [2] define the number and the name of the drive functions, provides an interface to the application calls #define IOCTL_IO_TEST CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_SAY_HELLO CTL_CODE (FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, { the UNICODE_STRING strLink; DbgPrint ( " [KrnlHW64] the DriverUnload \ n- " ); the RtlInitUnicodeString ( & strLink, link_name); IoDeleteSymbolicLink (& strLink); IoDeleteDevice (pDriverObj -> a DeviceObject); } // [4] IRP_MJ_CREATE corresponding processing routine, generally do not control it NTSTATUS DispatchCreate (PDEVICE_OBJECT pDevObj, PIRP PIRP) { DbgPrint ( " [KrnlHW64] DispatchCreate \ n- " ); PIRP -> IoStatus.Status = STATUS_SUCCESS; PIRP -> the IoStatus.Information = 0 ; the IoCompleteRequest (PIRP, IO_NO_INCREMENT); returnSTATUS_SUCCESS; } // [5] IRP_MJ_CLOSE corresponding processing routine, generally do not cares NTSTATUS DispatchClose (PDEVICE_OBJECT pDevObj, PIRP PIRP) { DbgPrint ( " [KrnlHW64] DispatchClose \ n- " ); PIRP -> IoStatus.Status = STATUS_SUCCESS; PIRP -> the IoStatus.Information = 0 ; the IoCompleteRequest (PIRP, IO_NO_INCREMENT); return STATUS_SUCCESS; } // [6] IRP_MJ_DEVICE_CONTROL corresponding processing routine, driving one of the most important functions, generally take the normal way function calls the driver program, this function will go through NTSTATUS DispatchIoctl (PDEVICE_OBJECT pDevObj, PIRP PIRP) { NTSTATUS Status =STATUS_INVALID_DEVICE_REQUEST; PIO_STACK_LOCATION pIrpStack; ULONG uIoControlCode; PVOID pIoBuffer; ULONG uInSize; ULONG uOutSize; DbgPrint ( " [KrnlHW64] DispatchIoctl \ n- " ); pIrpStack = IoGetCurrentIrpStackLocation (PIRP); // control code uIoControlCode = pIrpStack-> Parameters.DeviceIoControl.IoControlCode ; // input and output buffers pIoBuffer = pIrp-> AssociatedIrp.SystemBuffer; // input area size uInSize = pIrpStack-> Parameters.DeviceIoControl.InputBufferLength; // output area size uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength; Switch (uIoControlCode) { // add here the interface Case IOCTL_IO_TEST: { DWORD DW = 0 ; // get the contents entered the memcpy (& DW, pIoBuffer, the sizeof (DWORD)); // use the content input ++ DW; // result output process of the memcpy (pIoBuffer, & DW, the sizeof (DWORD)); // process is successful, returns a non-return failure STATUS_SUCCESS will DeviveIoControl Status = STATUS_SUCCESS; BREAK ; } case IOCTL_SAY_HELLO: { DbgPrint("[KrnlHW64]IOCTL_SAY_HELLO\n"); status = STATUS_SUCCESS; break; } } if(status == STATUS_SUCCESS) pIrp->IoStatus.Information = uOutSize; else pIrp->IoStatus.Information = 0; pIrp->IoStatus.Status = status; IoCompleteRequest(pIrp, IO_NO_INCREMENT); return status; } //[7] The driving load processing routine, which has been driven initialization NTSTATUS the DriverEntry (PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString) { NTSTATUS Status = STATUS_SUCCESS; the UNICODE_STRING ustrLinkName; the UNICODE_STRING ustrDevName; PDEVICE_OBJECT pDevObj; // initialize driven routine pDriverObj-> the MajorFunction [the IRP_MJ_CREATE] = DispatchCreate; pDriverObj -> the MajorFunction [an IRP_MJ_CLOSE] = DispatchClose; pDriverObj -> the MajorFunction [an IRP_MJ_DEVICE_CONTROL] = DispatchIoctl; pDriverObj -> = the DriverUnload the DriverUnload; // Create a drive apparatus RtlInitUnicodeString(&ustrDevName, DEVICE_NAME); status = IoCreateDevice(pDriverObj, 0, &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj); if(!NT_SUCCESS(status)) return status; if(IoIsWdmVersionAvailable(1, 0x10)) RtlInitUnicodeString(&ustrLinkName, LINK_GLOBAL_NAME); else RtlInitUnicodeString(&ustrLinkName, LINK_NAME); //创建符号链接 status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); if(!NT_SUCCESS (Status)) { IoDeleteDevice (pDevObj); return Status; } // come here actually drive initialization is complete, add the following initialization code is a functional DbgPrint ( " [KrnlHW64] the DriverEntry \ n- " ); return STATUS_SUCCESS; }
SCM series using function-driven loading and unloading process is not complicated, the overall process is: Open the SCM Manager (SCM get a handle) -> Create-driven services (access to services handle if the service already exists, this step becomes open service) - > start services -> stop services -> remove services -> close the service handle -> close SCM handle. To communicate with the driver, the symbolic link with the open drive CreateFile (will be appreciated that to obtain a "communication handler"), then use DeviceIoControl exchange information with the drive. If you've ever opened a symbolic link overdrive, you must unload there will be some trouble close the "communication handler" front-loading drive, or load the same driver again.
DeviceIoControl parameters well understood, only five important parameters: control code , input buffer, input length, an output buffer, the output length