Rootkits——windows内核的安全防护(4)

来源:互联网 发布:卖家网的数据准确吗 编辑:程序博客网 时间:2024/05/18 12:33

在计算机组成当中,每一个硬件模块都有专属于自己的寄存器,这些寄存器用于短时间内保存自己的数据,接受命令用于下一步执行,或者保存硬件的状态。而这些寄存器可以通过相应的端口进行访问这些寄存器。

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath ){LARGE_INTEGER timeout;theDriverObject->DriverUnload  = OnUnload; gTimer = (PKTIMER)ExAllocatePool(NonPagedPool,sizeof(KTIMER));gDPCP = (PKDPC)ExAllocatePool(NonPagedPool,sizeof(KDPC));timeout.QuadPart = -10;KeInitializeTimer( gTimer );KeInitializeDpc( gDPCP, timerDPC, NULL );if(TRUE == KeSetTimerEx( gTimer, timeout, 300, gDPCP))// 300 ms timer{DbgPrint("Timer was already queued..");}return STATUS_SUCCESS;}

首先在驱动入口程序设置一个定时器以及相应的定时器处理函数,定时器每隔300ms进行一次异步的定时处理程序进行一次处理。而与DPC相关联的异步处理函数式timerDPC,下一步进入到timerDPC的分析。

VOID timerDPC(IN PKDPC Dpc,IN PVOID DeferredContext,IN PVOID sys1,IN PVOID sys2){SetLEDS( g_key_bits++ );if(g_key_bits > 0x07) g_key_bits = 0;}

timerDPC当中对键盘LED进行设置,然后在键盘按键计数大于7的时候,对键盘计数进行清0

void SetLEDS( UCHAR theLEDS ){if(FALSE == SendKeyboardCommand( 0xED )){DbgPrint("SetLEDS::error sending keyboard command\n");}// send the flags for the LEDSif(FALSE == SendKeyboardCommand( theLEDS )){DbgPrint("SetLEDS::error sending keyboard command\n");}}
ULONG SendKeyboardCommand( IN UCHAR theCommand ){char _t[255];if(TRUE == WaitForKeyboard()){DrainOutputBuffer();_snprintf(_t, 253, "SendKeyboardCommand::sending byte %02X to port 0x60\n", theCommand);DbgPrint(_t);WRITE_PORT_UCHAR( KEYBOARD_PORT_60, theCommand );DbgPrint("SendKeyboardCommand::sent\n");}else{DbgPrint("SendKeyboardCommand::timeout waiting for keyboard\n");return FALSE;}// TODO: wait for ACK or RESEND from keyboardreturn TRUE;}

函数首先等待输入缓冲标志为满,然后对缓冲进行排空,然后利用0X60端口写入命令。

ULONG WaitForKeyboard(){char _t[255];int i = 100;// number of times to loopUCHAR mychar;DbgPrint("waiting for keyboard to become accecssable\n");do{mychar = READ_PORT_UCHAR( KEYBOARD_PORT_64 );KeStallExecutionProcessor(666);_snprintf(_t, 253, "WaitForKeyboard::read byte %02X from port 0x64\n", mychar);DbgPrint(_t);if(!(mychar & IBUFFER_FULL)) break;// if the flag is clear, we go ahead}while (i--);if(i) return TRUE;return FALSE;}

在等待函数当中,首先读取端口数据,然后建等待,再看看其中的INPUTBUFFER标志是否被标上。

void DrainOutputBuffer(){char _t[255];int i = 100;UCHAR c;DbgPrint("draining keyboard buffer\n");do{c = READ_PORT_UCHAR(KEYBOARD_PORT_64);KeStallExecutionProcessor(666);_snprintf(_t, 253, "DrainOutputBuffer::read byte %02X from port 0x64\n", c);DbgPrint(_t);if(!(c & OBUFFER_FULL)) break;// if the flag is clear, we go ahead// gobble up the byte in the output bufferc = READ_PORT_UCHAR(KEYBOARD_PORT_60);_snprintf(_t, 253, "DrainOutputBuffer::read byte %02X from port 0x60\n", c);DbgPrint(_t);}while (i--);}
0 0
原创粉丝点击