Ring3 adopts two common methods: METHOD_BUFFERED and METHOD_IN_DIRECT to test the ring0-level interactive file reading,

Source: Internet
Author: User

Ring3 adopts two common methods: METHOD_BUFFERED and METHOD_IN_DIRECT to test the ring0-level interactive file reading,

To familiarize yourself with the interaction process between ring3 and ring0, I wrote a simple program to test it so as to deepen my impression.

This article reads fixed files on a disk by testing METHOD_BUFFERED and METHOD_IN_DIRECT. For details about the communication methods of ring0 and ring3, see the following link.

Http://book.51cto.com/art/201107/275240.htm

The Code is as follows:

Ring3:

# Include <Windows. h> # include <winioctl. h> # include <stdio. h> # define BUFFERSIZE 1024 // two read/write modes # define CTL_CODE (latency, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) # define IOCTL_IN_DIRECT CTL_CODE (latency, 0x801, METHOD_IN_DIRECT, FILE_ANY_ACCESS) //////////////////////////////////////// /// // void Usage (char * proc) {printf ("% s-B // buffer Io \ n "" % s-d // direct io \ n ", proc, proc);} int main (int argc, char * argv []) {if (argc! = 2) {Usage (argv [0]); return 0;} char OutBufer [BUFFERSIZE]; bool ret = true; DWORD dwLength = 0; // HANDLE hDevice = CreateFile ("\\\\. \ KeReadSL ", GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM, NULL); if (hDevice = INVALID_HANDLE_VALUE) {printf ("Failed to open device ---- errorcode = % d... \ n ", GetLastError (); return 0;} if (strcmp (argv [1],"-B ") = 0) {printf (" Read File by Buf Fer Io way... \ n "); ret = DeviceIoControl (hDevice, IOCTL_DO_BUFFER, NULL, 0, OutBufer, BUFFERSIZE, & dwLength, NULL);} else if (strcmp (argv [1], "-d") = 0) {printf ("Read File by Direct Io way... \ n "); ret = DeviceIoControl (hDevice, IOCTL_IN_DIRECT, NULL, 0, OutBufer, BUFFERSIZE, & dwLength, NULL);} else {Usage (argv [0]); ret = false;} if (ret) {OutBufer [dwLength] = '\ 0'; printf ("Congratulation !!! \ NReadData: % s \ n ", OutBufer);} CloseHandle (hDevice); return 0 ;}

Ring0

# Include <ntddk. h> # define CTL_CODE (latency, 0x800, latency, FILE_ANY_ACCESS) # define CTL_CODE (latency, 0x801, METHOD_IN_DIRECT, FILE_ANY_ACCESS) typedef struct _ DEVICE_EXTENSION {PDEVICE_OBJECT pDevice; UNICODE_STRING ustrDeviceName; // device name UNICODE_STRING ustrSymlinkName; // Symbolic Link name} DEVICE_EXTENSION, * PDEVICE_EXTENSION; /////////////////////// //////////////////////////////////////// /////////// Read the file (for convenience, the test reads a small test.txt file from the C drive) ULONG KeReadFileData (UCHAR * OutputBuffer, ULONG BufferSize, ULONG * ReadSize) {OBJECT_ATTRIBUTES metadata; ioiostatus; HANDLE hFile; // initialize the file path UNICODE_STRING ustrFilePath; encode (& ustrFilePath, L "\\?? \ C :\\ test.txt "); InitializeObjectAttributes (& objectAtrtributes, & ustrFilePath, expiration, NULL, NULL); // open the file NTSTATUS zwStatus = ZwCreateFile (& hFile, GENERIC_READ, & objectAtrtributes, & iostatus, NULL, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ, FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); if (! NT_SUCCESS (zwStatus) {KdPrint ("The file is not exist! \ N "); return 0;} // obtain the file length FILE_STANDARD_INFORMATION fsi; zwStatus = ZwQueryInformationFile (hFile, & iostatus, & fsi, sizeof (FILE_STANDARD_INFORMATION), FileStandardInformation ); if (! NT_SUCCESS (zwStatus) {KdPrint ("Failed to ZwQueryInformationFile... \ n "); ZwClose (hFile); return 0;} ULONG DataSizeReaded = BufferSize <fsi. endOfFile. quadPart? BufferSize: fsi. endOfFile. quadPart; // actual file size to be read // zwStatus = ZwReadFile (hFile, NULL, & iostatus, OutputBuffer, DataSizeReaded, NULL, NULL); if (! NT_SUCCESS (zwStatus) {KdPrint ("Failed to ZwReadFile... \ n "); ZwClose (hFile); return 0;} KdPrint (" The program really read % d byutes... \ n ", iostatus. information); * ReadSize = iostatus. information; ZwClose (hFile); return 1 ;} //////////////////////////////////////// /// // create a device NTSTATUS CreateDevice (PDRIVER_OBJECT pDriverObject, UNICODE_STRING devname, UNICODE_STRING symLinkName) {NTSTATUS status; PDEVICE_OBJECT p1_bj; PDEVICE_EXTENSION pDevExt; // create a device status = IoCreateDevice (pDriverObject, sizeof (DEVICE_EXTENSION), & devname, FILE_DEVICE_UNKNOWN, 0, TRUE, & p1_bj ); if (! NT_SUCCESS (status) return status; p1_bj-> Flags | = bytes; pDevExt = (PDEVICE_EXTENSION) p1_bj-> DeviceExtension; pDevExt-> pDevice = p1_bj; pDevExt-> ustrDeviceName = devname; pDevExt-> ustrSymlinkName = symLinkName; KdPrint ("devname = % wZ \ nsymbollink = % wZ \ n", & devname, & symLinkName )); // create the device link status = IoCreateSymbolicLink (& symLinkName, & devname); if (! NT_SUCCESS (status) {KdPrint ("Failed to IoCreateSymbolicLink and delete DeviceObject --- errorcode = % d... \ n ", status); IoDeleteDevice (pDevObj); return status ;}return status ;}// uninstall the driver VOID DriverUnload (PDRIVER_OBJECT pDriverObject) {PDEVICE_OBJECT pNextObj; kdPrint ("Enter DriverUnload... \ n "); pNextObj = pDriverObject-> DeviceObject; // cyclically traverses and deletes all devices on the driver while (pNextObj! = NULL) {// The device name and Link name are stored in the extended structure PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION) pNextObj-> DeviceExtension; // Delete the symbolic link UNICODE_STRING LinkName = pDevExt-> ustrSymlinkName; IoDeleteSymbolicLink (& LinkName); pNextObj = pNextObj-> NextDevice; IoDeleteDevice (pDevExt-> pDevice );}} // process the message NTSTATUS DeviceIoControlDispatch (PDEVICE_OBJECT p1_bj, PIRP pIrp) {NTSTATUS status = STATUS_SUCCESS; KdPrint ("Enter DeviceIoControlDis Patch... \ n "); // obtain the current stack PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation (pIrp); // obtain the buffer size such as ULONG cbin = stack-> Parameters. deviceIoControl. inputBufferLength; // output buffer size ULONG cbout = stack-> Parameters. deviceIoControl. outputBufferLength; // obtain the IOCTL code ULONG code = stack-> Parameters. deviceIoControl. ioControlCode; // the actual size of the Read File ULONG ReadSize = 0; // determine the file operation mode switch (code) {case IOCTL_DO_BUFFER: // The buffer operation only performs the Read File test ){ UCHAR * OutputBuffer = (UCHAR *) pIrp-> AssociatedIrp. SystemBuffer; if (! KeReadFileData (OutputBuffer, cbout, & ReadSize) status = STATUS_UNSUCCESSFUL; break;} case IOCTL_IN_DIRECT: // direct file operation {// map the buffer to the address UCHAR * OutputBuffer = (UCHAR *) MmGetSystemAddressForMdlSafe (pir-> MdlAddress, NormalPagePriority) in kernel mode; if (! KeReadFileData (OutputBuffer, cbout, & ReadSize) status = STATUS_UNSUCCESSFUL; break;} default: {status = STATUS_INVALID_VARIANT ;}// set the completion status of the IRP. status = status; pir-> IoStatus. information = ReadSize; IoCompleteRequest (pIrp, IO_NO_INCREMENT); KdPrint ("Leave DeviceIoControlDispatch... \ n "); return status;} // IRP request processing function NTSTATUS MyDispatchFunction (PDEVICE_OBJECT device, piririrp) {// obtain the stack space PI of the current irp call O_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation (irp); NTSTATUS status = STATUS_INVALID_PARAMETER; // process various request switches (irpsp-> MajorFunction) {case IRP_MJ_CREATE: // This IRP requires simple processing, otherwise, an error occurred while opening the device link in CreateFile {// a simple error occurred while returning an IRP success trilogy irp-> IoStatus. information = 0; irp-> IoStatus. status = STATUS_SUCCESS; IoCompleteRequest (irp, IO_NO_INCREMENT); // At the application layer, print the string after the device is turned on. This string is only used to test dbgprs int ("congratulations gay, open device "); status = irp-> IoS Tatus. status; break;} case IRP_MJ_CLOSE: {irp-> IoStatus. information = 0; irp-> IoStatus. status = STATUS_SUCCESS; IoCompleteRequest (irp, IO_NO_INCREMENT); // At the application layer, print the string after the device is turned on. This string is only used to test dbgprs int ("congratulations gay, close device "); status = irp-> IoStatus. status; break;} case IRP_MJ_READ: {break;} default: {dbuplint ("unknow request !!! "); Break ;}} return status;} NTSTATUS DriverEntry (PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) {dbuplint (" Enter DriverEntry \ n "); // KdPrint ("Enter DriverEntry \ n"); NTSTATUS status; // set the dispatch function for (int I = 0; I <IRP_MJ_MAXIMUM_FUNCTION; I ++) pDriverObject-> MajorFunction [I] = MyDispatchFunction; pDriverObject-> MajorFunction [IRP_MJ_DEVICE_CONTROL] = DeviceIoControlDispatch; pDriverObject-> DriverU Nload = DriverUnload; // create a Device and link UNICODE_STRING ustrDevName, ustrSymbolicName; RtlInitUnicodeString (& ustrDevName, L "\ Device \ KeRead"); RtlInitUnicodeString (& signature, L "\ DosDevices \ KeReadSL"); status = CreateDevice (pDriverObject, ustrDevName, ustrSymbolicName); if (! NT_SUCCESS (status) {KdPrint ("Failed to Create Device... \ n "); return STATUS_UNSUCCESSFUL;} KdPrint (" Exit DriverEntry \ n "); return STATUS_SUCCESS ;}






Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.