typedef struct _SSDT_HOOK_DATA{
 PULONG   pulAddress;                     //在SSDT表中要HOOK的位置
 ULONG    ulRealValue;                    //初始值
 ULONG    ulNewValue;                     //HOOK之后的值
}SSDT_HOOK_DATA,*PSSDT_HOOK_DATA;


//=========================================================================
//函数名:InitSSDTHook
//功能 :初始化SSDT HOOK的值
//  1.根据函数名取得SSDT表中的位置
//  2.设置HOOK所要有配置数据
//参数:
//  IN OUT pstSsdtHookData   Ssdt Hook的配置数据
//  IN pszFunName    函数名
//  IN ulNewAddress    新的函地址
//返回值:
//  TRUE 成功
//  FALSE 失败
//=========================================================================
BOOLEAN InitSSDTHook(IN OUT PSSDT_HOOK_DATA pstSsdtHookData, IN const PCHAR pszFunName, IN const ULONG ulNewAddress)
{
 PULONG pulAddress = NULL;

 puladdress = (PULONG)GetSSDTAddress(pszFunName);


 pstSsdtHookData->pulAddress = pulAddress;
 pstSsdtHookData->ulNewValue = ulNewAddress;
 pstSsdtHookData->ulRealValue = *pulAddress;

 if(NULL == pstSsdtHookData->pulAddress) || (NULL == pstSsdtHookData->ulNewValue) ||
 (0 == pstSsdtHookData->ulRealValue))
 {
  return FALSE;
 }

 return TRUE;
}


//=========================================================================
//函数名:HookSSDT
//功能 : 根据已设置的HOOK数据
//   进行SSDT HOOK
//参数:
//  IN  pstSsdtHookData   Ssdt Hook的配置数据
//返回值:
//  TRUE 成功
//  FALSE 失败
//=========================================================================
VOID HookSSDT(IN const PSSDT_HOOK_DATA pstSsdtHookData)
{

 _asm
 {
  cli
   mov eax,cr0
   and eax,not 0x10000
   mov cr0,eax
 }

 ExInterlockedExchangeUlong(pstSsdtHookData->pulAddress, pstSsdtHookData->ulNewValue, NULL);

 _asm
 {
  mov eax,cr0
   or eax,0x10000
   mov cr0,eax
   sti
 }
 pstSsdtHookData->bState = TRUE;
}


//=========================================================================
//函数名:UnHookSSDT
//功能 : 根据已设置的HOOK数据
//   进行SSDT HOOK的还原操作
//参数:
//  IN  pstSsdtHookData   Ssdt Hook的配置数据
//返回值:
//  TRUE 成功
//  FALSE 失败
//=========================================================================
VOID UnHookSSDT(IN const PSSDT_HOOK_DATA pstSsdtHookData)
{
 if (!pstSsdtHookData)
 {
  return;
 }

 _asm
 {
  cli
   mov eax,cr0
   and eax,not 0x10000
   mov cr0,eax
 }

 ExInterlockedExchangeUlong(pstSsdtHookData->pulAddress, pstSsdtHookData->ulRealValue, NULL);

 _asm
 {
  mov eax,cr0
   or eax,0x10000
   mov cr0,eax
   sti
 }
 pstSsdtHookData->bState = FALSE;
}