// Fuckaid driver
// XXX by mj0011 2007-12-4
# Include <ntddk. h>
# Include <zwfunc. h>
# Include <stdafx. h>
# Include <ntifs_48.h>
# Define device_kbd_device 0x9801
# Define ioctl_set_kbd_input ctl_code (device_kbd_device, 0x912, method_buffered, file_any_access)
// ================================================ ======================================
// Keyboard I/O registers on the PC
// ================================================ ======================================
// 60 h Data
// 64 h command (write)
// 64 h status (read)
//
// Bits in Status Register (names from Linux source)
// B7 Perr parity error in data driven ed from keyboard
// B6 GTO receive timeout
// B5 transmit timeout (or PS/2 mouse ?)
// B4 keyboard is locked
// B3 0 = 60 h was the port last accessed, 1 = 61 H was last (?)
// B2 system flag status: 0 = power-up/reset, 1 = selftest OK (?)
// B1 IBF input buffer full (data from host to keyboard)
// B0 OBF output buffer full (data from keyboard to host)
//
// Bits in output port of 8042 chip (Table p0383 in ports.)
// The output port is written by Controller command d1h,
// And read by Controller command d0h
// B7 keyboard data output
// B6 keyboard clock output
// B5 input buffer not full
// B4 output buffer not empty
// B3 (varies)
// B2 (varies)
// B1 A20 Gate
// B0 system reset (this bit shoshould always be set to 1)
//
// Bits in input port of 8042 Chip
// The input port is read by Controller command c0h
// B7 Keyboard not locked
// B6-b0 (varies)
//
// Bits in "command Byte" (confusing name; from Table p0404 in ports.)
// The "command Byte" is written by Controller command 60 h
// And read by Controller command 20 h
// (Names from Linux source)
// B7 (Reserved)
// B6 KCC convert set 2 scancodes to set 1 ("ibm pc compatibility mode ")
// B5 DMS disables PS/2 mouse when set
// B4 disables keyboard when set
// B3 ignore keyboard lock switch when set
// B2 sys system flag (same as B2 in status register, it seems)
// B1 enables irq12 from PS/2 mouse when set
// B0 eki enables irq1 on keyboard output buffer full
//
// Result byte for interface self-tests (Table p0406 in ports.)
// Returned by Controller commands a9h or ABH
// 0 no error
// 1 clock line stuck low
// 2 clock line stuck high
// 3 data line stuck low
// 4 data line stuck high
Char _ stdcall _ setkdbio (byte keyscancode)
{
_ ASM
{
Loopwaitforkdbok:
In Al, 0x64
Port 64 is the at keyboard controller 8042 chip status/control port
And Al, 2
Jnz loopwaitforkdbok
; Waiting status port OK
; Wait for the IBF bit of Status Register to be 1
Is to wait for the input buffer full from the host to the keyboard
For more information, see
MoV Al, 0xd2
Out 0x64, Al
; Send control commands to port 64
The 0xd2 command is used to write the output buffer on the keyboard.
For details, refer to [url] http://lezy.51.net/sub/i8042.htm#/url].
Loopwaitforcmdok:
In Al, 0x64
And Al, 2
Jnz loopwaitforcmdok
; Wait for the command to complete
; Wait for the IBF bit of Status Register to be 1
Is to wait for the input buffer full from the host to the keyboard
MoV Al, byte PTR [esp + 4]
; Get the scan code to write
Out 0x60, Al
Port 60 is the input/output buffer port of at keyboard controller 8042.
; Write a scan code to the keyboard
; Equivalent to a simulated button
Retn 4
}
}
Char _ stdcall _ setkbdio (byte keyscancode)
{
Return _ setkdbio (keyscancode );
}
Char _ stdcall setkbdio (pvoid inbuffer, ulong inputlen)
{
Ulong I;
Char result;
For (I = 0; I <inputlen; ++ I)
Result = _ setkbdio (* (byte *) (ulong) inbuffer + I ));
Return result;
}
Ntstatus _ stdcall commondispatch (pdevice_object implements BJ, pirp)
{
Ulong inputbufferlen;
Pio_stack_location irpstack;
Pirp;
Char * Buf;
Pvoid inbuffer;
Ntstatus Stat;
Dbuplint ("entering inputdispatch ");
Pirp = IRP;
Irpstack = iogetcurrentirpstacklocation (IRP );
Inbuffer = IRP-> associatedirp. systembuffer;
IRP-> iostatus. Status = 0;
IRP-> iostatus. Information = 0;
Inputbufferlen = irpstack-> parameters. deviceiocontrol. inputbufferlength;
// IRP = V7;
If (irpstack-> majorfunction = irp_mj_create)
{
Buf = "irp_mj_create ";
Goto show_debug;
}
If (irpstack-> majorfunction = irp_mj_close)
{
Buf = "irp_mj_close ";
Show_debug:
Dbuplint (BUF );
Goto endreq;
}
If (irpstack-> majorfunction = irp_mj_device_control)
{
Dbuplint ("irp_mj_device_control ");
If (irpstack-> parameters. deviceiocontrol. iocontrolcode = ioctl_set_kbd_input)
{
Dbuplint ("ioctl_inputdrv_kbdinput ");
If (inputbufferlen)
Setkbdio (inbuffer, inputbufferlen );
}
Else
{
Dbuplint ("error: Unknown irp_mj_device_control ");
Pirp-> iostatus. Status = status_invalid_parameter;
}
}
Endreq:
Stat = pirp-> iostatus. status;
Iofcompleterequest (pirp, 0 );
Dbuplint ("leaving inputdispatch ");
Return Stat;
}
Ntstatus _ stdcall drvunload (pdriver_object drvobj)
{
Unicode_string destinationstring;
Dbuplint ("entering inputunload ");
Rtlinitunicodestring (& destinationstring, l "// dosdevices // fuckaid ");
If (! Nt_success (iodeletesymboliclink (& destinationstring )))
Dbuplint ("error: iodeletesymboliclink ");
Else
Iodeletedevice (drvobj-> deviceobject );
Return dbuplint ("leaving inputunload ");
}
Ntstatus _ stdcall DriverEntry (pdriver_object driverobject, int A2)
{
Ntstatus stat2;
Pdriver_object drvobj;
Ntstatus Stat;
Ntstatus STAT3;
Pdevice_object deviceobject;
Unicode_string destinationstring;
Unicode_string symboliclinkname;
Dbuplint ("fuckaid driver XXX by mj0011! /N ");
Deviceobject = 0;
Dbuplint (char *) "entering DriverEntry ");
Rtlinitunicodestring (& destinationstring, (const wchar *) "// device // fuckaid ");
Drvobj = driverobject;
Stat = iocreatedevice (driverobject, 0, & destinationstring, device_kbd_device, 0, true, & deviceobject );
Stat2 = Stat;
If (! Nt_success (STAT ))
{
Dbuplint ("error: iocreatedevice failed ");
}
Else
{
Drvobj-> majorfunction [irp_mj_device_control] = (pdriver_dispatch) commondispatch;
Drvobj-> majorfunction [irp_mj_close] = (pdriver_dispatch) commondispatch;
Drvobj-> majorfunction [irp_mj_create] = (pdriver_dispatch) commondispatch;
Drvobj-> driverunload = (pdriver_unload) drvunload;
Rtlinitunicodestring (& symboliclinkname, l "// dosdevice // fuckaid ");
STAT3 = iocreatesymboliclink (& symboliclinkname, & destinationstring );
Stat2 = STAT3;
If (! Nt_success (STAT ))
{
Dbuplint ("error: iocreatesymboliclink failed ");
Iodeletedevice (deviceobject );
}
}
Dbuplint ("leaving DriverEntry ");
Return stat2;
}