直接IO模拟键盘源代码

来源:互联网 发布:淘宝卖什么东西最好卖 编辑:程序博客网 时间:2024/04/29 01:15
 //fuckaid driver
//xxx by MJ0011 2007-12-4 14:44


#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
// ================================================================
// 60h    data
// 64h    command (write)
// 64h    Status (read)
//
// Bits in Status register (names from Linux source)
//    b7  PERR    parity error in data received from keyboard
//    b6  GTO    receive timeout
//    b5          transmit timeout (or PS/2 mouse?)
//    b4          keyboard is locked
//    b3          0=60h was the port last accessed, 1=61h 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.A)
// 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 SHOULD 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.A)
// The "Command Byte" is written by controller command 60h
// and read by controller command 20h
// (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.A)
// 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

            ;64号端口为AT Keyboard controller 8042芯片的状态/控制端口
        and al , 2
        jnz    LoopWaitForKdbOK

            ;等待状态端口OK
            ;等待status register 的IBF位为1
            ;就是等待host 到 keyboard的Input Buffer full
            ;参见上资料

        mov    al , 0xD2
        out 0x64 , al

            ;向64端口发送控制命令
            ;0xD2号命令是写键盘output buffer的命令
            ;参考:[url]http://lezy.51.net/sub/i8042.htm[/url]

       
LoopWaitForCmdOK:   
        in    al , 0x64
        and    al , 2   
        jnz    LoopWaitForCmdOK
            ;等待命令完成
            ;等待status register 的IBF位为1
            ;就是等待host 到 keyboard的Input Buffer full

        mov    al , byte ptr[esp + 4]

            ;获得要写入的scan code

        out 0x60 , al
           
            ;60号端口是AT KeyBoard controller 8042的Input/Output Buffer端口

            ;向键盘写入一个scan code
            ;相当于一次模拟按键

        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 devobj, PIRP Irp)
{
  ULONG InputBufferLen;
  PIO_STACK_LOCATION irpstack;
  PIRP pIrp;
  char *buf;
  PVOID    InBuffer;
  NTSTATUS stat;

  DbgPrint("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:
    DbgPrint(buf);
    goto endreq;
  }
  if ( irpstack->MajorFunction  == IRP_MJ_DEVICE_CONTROL )
  {
    DbgPrint("IRP_MJ_DEVICE_CONTROL");
    if ( irpstack->Parameters.DeviceIoControl.IoControlCode ==  IOCTL_SET_KBD_INPUT)
    {
      DbgPrint("IOCTL_INPUTDRV_KBDINPUT");
      if ( InputBufferLen )
        SetKbdIo(InBuffer, InputBufferLen);
    }
    else
    {
      DbgPrint("ERROR: Unknown IRP_MJ_DEVICE_CONTROL");
      pIrp->IoStatus.Status = STATUS_INVALID_PARAMETER;
    }
  }
endreq:
  stat = pIrp->IoStatus.Status;
  IofCompleteRequest(pIrp, 0);
  DbgPrint("Leaving InputDispatch");
  return stat;
}

NTSTATUS __stdcall DrvUnload(PDRIVER_OBJECT drvObj )
{
  UNICODE_STRING DestinationString;

  DbgPrint("Entering InputUnload");
  RtlInitUnicodeString(&DestinationString, L"//DosDevices//fuckaid");
  if ( !NT_SUCCESS(IoDeleteSymbolicLink(&DestinationString)) )
    DbgPrint("ERROR: IoDeleteSymbolicLink");
  else
    IoDeleteDevice(drvObj->DeviceObject);
  return DbgPrint("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;   

  DbgPrint("fuckaid Driver xxx by MJ0011!/n");
 
  DeviceObject = 0;
  DbgPrint((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) )
  {
    DbgPrint("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(stat3) )
    {
      DbgPrint("ERROR: IoCreateSymbolicLink failed");
      IoDeleteDevice(DeviceObject);
    }
  }
  DbgPrint("Leaving DriverEntry");
  return stat2;
}