Well, I don't know what to expect.
# Include <stdio. h>
# Include <windows. h>
# Define uty_hook 2048
Int main (void)
{
Handle handle;
Char * Buf [1024];
DWORD returnsize;
Handle = createfile ("//. // utydriver ",
Generic_read,
File_pai_read | file_pai_write,
Null, open_existing,
File_attribute_normal, null );
Deviceiocontrol (handle, uty_hook, null,
0, Buf, 1024, & returnsize, null );
Printf ("% d/N", getlasterror ());
Printf ("% d/N", returnsize );
Printf ("% s/n", Buf );
Return 0;
}
//--------------------------------------------------------------------
This is the user-mode app. After loading the driver, use createfile to open a handle and use deviceiocontrol. The control code is defined in the driver and user-modeapp # define uty_hook 2048, because the SDK header file winioctl. h has
//
// Macro definition for defining IOCTL and fsctl function control codes. Note
// That function codes 0-2047 are reserved for Microsoft Corporation, and
// 2048-4095 are reserved for MERs.
//
# Define ctl_code (devicetype, function, method, access )(/
(Devicetype) <16) | (ACCESS) <14) | (function) <2) | (method )/
)
So uty_hook uses 2048
The driver is pasted once again, and the hook is no longer needed,
# Include <ntddk. h>
// # Pragma comment (Lib, "NTDLL. lib ")
Typedef ntstatus (ntapi * ntproc )();
Typedef ntproc * pntproc;
# Define ntproc _ sizeof (ntproc)
# Define uty_hook 2048
Typedef struct _ system_service_table
{
/* 000 */pntproc servicetable; // array of entry points
/* 004 */long * countertable; // array of usage counters
/* 008 */long servicelimit; // Number of table entries
/* 00c */uchar argumenttable; // array of byte counts
/* 010 */}
System_service_table,
* Psystem_service_table,
** Ppsystem_service_table;
# Define system_service_table _/
Sizeof (system_service_table)
//--------------------------------------------------------------------
Typedef struct _ service_descriptor_table
{
/* 000 */system_service_table ntoskrnl; // ntoskrnl.exe (native API)
/* 010 */system_service_table win32k; // win32k. sys (GDI/user)
/* 020 */system_service_table table3; // not used
/* 030 */system_service_table table4; // not used
/* 040 */}
Service_descriptor_table,
* Pservice_descriptor_table,
** Ppservice_descriptor_table;
# Define service_descriptor_table _/
Sizeof (service_descriptor_table)
//--------------------------------------------------------------------
Extern pservice_descriptor_table keservicedescriptortable;
Void utydriverunload (in pdriver_object driverobject );
Ntstatus utydriverio (in pdevice_object deviceobject, in pirp );
Ntstatus utydriveriocontrol (in pdevice_object, in pirp );
// Ntsysapi
Ntstatus
// Ntapi
Utyntreadfile (
In handle filehandle,
In handle event optional,
In pio_apc_routine apcroutine optional,
In pvoid apccontext optional,
Out pio_status_block iostatusblock,
Out pvoid buffer,
In ulong length,
In plarge_integer byteoffset optional,
In Pulong key optional );
Pdevice_object utydriverdeviceobject = NULL;
Ulong out_size;
Pfile_object handle_object;
Long temp;
Char tempbuf [1024];
Ntstatus DriverEntry (pdriver_object driverobject,
Punicode_string registrypath)
{
Unicode_string ntdevicename;
Unicode_string win32devicename;
Ntstatus status;
Pntproc servicetable;
Rtlinitunicodestring (& ntdevicename, l "// device // utydriver ");
If (! Nt_success (status = iocreatedevice (driverobject, 0, & ntdevicename,
File_device_unknown, 0, false,
& Utydriverdeviceobject )))
Return status_no_such_device;
Utydriverdeviceobject-> flags | = do_buffered_io;
Rtlinitunicodestring (& win32devicename, l "// dosdevices // utydriver ");
If (! Nt_success (status = iocreatesymboliclink (& win32devicename, & ntdevicename )))
Return status_no_such_device;
Driverobject-> majorfunction [irp_mj_create] = utydriverio;
Driverobject-> majorfunction [irp_mj_close] = utydriverio;
Driverobject-> majorfunction [irp_mj_read] = utydriverio;
Driverobject-> majorfunction [irp_mj_write] = utydriverio;
Driverobject-> majorfunction [irp_mj_device_control] = utydriveriocontrol;
Driverobject-> driverunload = utydriverunload;
// Interlockedexchange (plong) & temp, * (long *) keservicedescriptortable-> ntoskrnl. servicetable + 151 ));
// Interlockedexchange (plong) keservicedescriptortable-> ntoskrnl. servicetable + 151, (long) utyntreadfile );
Return STATUS_SUCCESS;
}
// Configure //-------------------------------------------------------------------------------------
Void utydriverunload (in pdriver_object driverobject)
{
Unicode_string win32devicename;
// Interlockedexchange (plong) keservicedescriptortable-> ntoskrnl. servicetable + 151, (long) temp );
Rtlinitunicodestring (& win32devicename, l "// dosdevices // utydriver ");
Iodeletesymboliclink (& win32devicename );
Iodeletedevice (utydriverdeviceobject );
}
// Configure //-------------------------------------------------------------------------------------
Ntstatus utydriverio (in pdevice_object deviceobject, in pirp)
{
IRP-> iostatus. Status = STATUS_SUCCESS;
Iocompleterequest (IRP, io_no_increment );
Return IRP-> iostatus. status;
}
// Configure //-------------------------------------------------------------------------------------
Ntstatus utydriveriocontrol (in pdevice_object deviceobject, in pirp)
{
Pio_stack_location stack;
Uchar * in_buffer, * out_buffer;
Ulong code, RET;
Stack = iogetcurrentirpstacklocation (IRP );
Out_size = stack-> parameters. deviceiocontrol. outputbufferlength;
Code = stack-> parameters. deviceiocontrol. iocontrolcode;
In_buffer = out_buffer = IRP-> associatedirp. systembuffer;
Ret = STATUS_SUCCESS;
Switch (CODE)
{
Case uty_hook:
{
Rtlcopybytes (out_buffer, "Hi, this is from the kernel", 30 );
Out_size = 50;
IRP-> iostatus. Information = 30;
}
}
IRP-> iostatus. Status = STATUS_SUCCESS;
IRP-> iostatus. Information = 30;
Iocompleterequest (IRP, io_no_increment );
Return ret;
}
// Configure //-------------------------------------------------------------------------------------
// Ntsysapi
Ntstatus
// Ntapi
Utyntreadfile (
In handle filehandle,
In handle event optional,
In pio_apc_routine apcroutine optional,
In pvoid apccontext optional,
Out pio_status_block iostatusblock,
Out pvoid buffer,
In ulong length,
In plarge_integer byteoffset optional,
In Pulong key optional)
{
/* If (nt_success (obreferenceobjectbyhandle (filehandle, 0x80000000,0, 0,
(Void *) handle_object, 0 ))){
Rtlunicodestringtoansistring (pansi_string) tempbuf, (punicode_string) & handle_object-> filename, false );
// Rtlcopystring (tempbuf, (char *) handle_object-> filename );
}*/
Return STATUS_SUCCESS;
}
// Configure //-------------------------------------------------------------------------------------
The most important thing is
Ntstatus utydriveriocontrol (in pdevice_object deviceobject, in pirp)
{
Pio_stack_location stack;
Uchar * in_buffer, * out_buffer;
Ulong code, RET;
Stack = iogetcurrentirpstacklocation (IRP );
// In the driver layer, such as PDO, fdo, and Fido, get your own stack.
Out_size = stack-> parameters. deviceiocontrol. outputbufferlength; // corresponds to the parameter in driveriocontrolNoutbuffersize, the same for others, all correspond to one-to-one under devicoiocontrol
Code = stack-> parameters. deviceiocontrol. iocontrolcode;
In_buffer = out_buffer = IRP-> associatedirp. systembuffer;
// It looks like the buffer from the user-mode is also returned here. The buffer returned to the user-mode is also the buffer. Yes, I tried it just now, you can use this to send user-mode data to the kernel,
Ret = STATUS_SUCCESS;
Switch (CODE)
{
Case uty_hook:
{
Rtlcopybytes (out_buffer, "Hi, this is from the kernel", 30 );
Out_size = 50;
IRP-> iostatus. Information = 30;
// IRP-> iostatus. information indicates the number of bytes to be returned. When it is set to 0, the user-mode returnsize is 0, and no data is returned in the buffer.
}
}
IRP-> iostatus. Status = STATUS_SUCCESS;
IRP-> iostatus. Information = 30;
Iocompleterequest (IRP, io_no_increment );
// This complete is very important. When this is not added, the user-mode program will not return, and the driver will not be uninstalled, use this function to returning the given IRP to the I/O manager, which completes a complete IRP. Now we should clarify the relationship between IRP and io_stack_location, in Windows operating system principles, we found that "when creating an IRP for any kernel-mode program, we also create an I/O stack associated with it, the I/O stack unit in the stack is defined by the io_stack_location structure. Each stack unit corresponds to a driver that will process the IRP. To determine the current irp I/O stack unit in a given IRP, the driver can call the iogetcurrentstacklocation function, which returns a pointer to the current I/O stack unit ."
Return ret;
}
// Configure //-------------------------------------------------------------------------------------
It's easy to get it up,
Next, we should use this to get something useful.