欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

游戏保护大放送之HS

程序员文章站 2022-07-05 23:29:27
作 者: wtxpwh 本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系 做挂者请绕道!   本人不保证此办法现在还生效!蓝屏死机于本人无关 &...
作 者: wtxpwh

本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系
做挂者请绕道!
 
本人不保证此办法现在还生效!蓝屏死机于本人无关
 
安博士hook和tp差不多都是那些关键敏感的函数。至于是哪些被hook请自己动手用工具查看一下。
 
直接上代码!
 
代码:
 
#include "struct.h"
#include "4BOD.h"
 
//////////////////////////////////////////////////////////////////////////
ULONG Pass_NtProcess();
VOID UnDetour_NtProcess();
 
ULONG Pass_NtWriteVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
 
ULONG Pass_NtReadVirtualMemory();
VOID UnDetour_NtReadVirtualMemory();
 
ULONG Pass_KiAttachProcess();
VOID UnDetour_KiAttachProcess();
 
ULONG Pass_NtQueryInformationProcess();
VOID UnDetour_NtQueryInformationProcess();
 
ULONG Pass_PsSuspendThread();
VOID UnDetour_PsSuspendThread();
 
ULONG Pass_NtSetContextThread();
VOID UnDetour_NtSetContextThread();
 
ULONG Pass_NtGetContextThread();
VOID UnDetour_NtGetContextThread();
 
void Init_fun();
 
 
ULONG SearchMutex();
ULONG Pass_debugport();
ULONG FindProcess();
 
//////////////////////////////////////////////////////////////////////////
 
ULONG KeStackAttachProcess_Addr;
 
 
ULONG __stdcall IsNPCalled(HANDLE ProcessHandle);
 
 
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address;
PULONG  pSSDTKernel;
PSERVICE_DESCRIPTOR_TABLE_SHADOW _KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE_SHADOW  ShadowTable;
unsigned long SSDT_reentry_address,SSDTDW_reentry_address;
 
 
void __declspec(naked) my_function_detour_KiFastCallEntry()
{
  __asm
  {
    cmp     ecx,10h
    jne     SSDT
    mov    edi,KeServiceDescriptorTable
    sub    edi,0x10
    jmp    [SSDTDW_reentry_address]
     
SSDT:
    mov    edi,KeServiceDescriptorTable
    add    edi,0x20
    jmp    [SSDT_reentry_address]
     
 
  }
 
}
 
UCHAR findcode[]={0x83,0xf9,0x10,0x75};
 
VOID FindHackAddr()
{
  ULONG  uSysenter;
  ULONG i=0;
  PUCHAR strSysenter;
 
  __asm{
      mov ecx,0x176
      rdmsr
      mov uSysenter,eax  // www.2cto.com 得到KiFastCallEntry地址
    }
  strSysenter=(PUCHAR)uSysenter;
  for (i=0;i<0x100;i++)
  {
    if (
      findcode[0]==strSysenter[i] &&
      findcode[1]==strSysenter[i+1] &&
      findcode[2]==strSysenter[i+2] &&
      findcode[3]==strSysenter[i+3] )
    {
      break;
    }
 
  }
 
  KiSystemService_hack_address=uSysenter+i;
 
}
 
ULONG HookSysCall()
{
  KIRQL  oldIrql;
  ULONG  uSysenter;
 
  unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
 
  char *actual_function;
 
  int i = 0;
 
  FindHackAddr();
 
  if (KiSystemService_hack_address==0)
  {
    dprintf("find hack address error!\n");
    return 0;
  }
/*
  __asm{
      mov ecx,0x176
      rdmsr
      mov uSysenter,eax  //得到KiFastCallEntry地址
     }
 
  KiSystemService_hack_address=uSysenter+0xaf;
 
*/
 
 
  actual_function =(char*) KiSystemService_hack_address;
 
 
 
  SSDT_reentry_address = KiSystemService_hack_address+0x20;
  SSDTDW_reentry_address = KiSystemService_hack_address+0x5;
 
  *( (unsigned long *)(&newcode[1]) ) = (ULONG)my_function_detour_KiFastCallEntry-KiSystemService_hack_address-5;
 
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  for(i=0;i < 5;i++)
  {
    g_pFindOrigCode[i] = actual_function[i];
    actual_function[i] = newcode[i];
  }
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
}
void RestoreSSDT()
{
  int i;
  char *actual_function = (char *)(KiSystemService_hack_address);
  KIRQL  oldIrql;
  WPOFF();
 
  KeRaiseIrql( DISPATCH_LEVEL,&oldIrql );
 
  for(i=0;i < 5;i++)
  {
    actual_function[i] = g_pFindOrigCode[i];
  }
 
  KeLowerIrql( oldIrql );
  ExFreePool(pSSDTKernel);
 
  WPON();
 
}
 
 
unsigned long AddMyServiceTable()
{
 
 
  ULONG  nSDTKerCallLen;
 
 
 
  __asm
  {
    pushad
    mov   eax,KeServiceDescriptorTable
    mov   _KeServiceDescriptorTable,eax
    sub   eax,0x40
    mov   ShadowTable,eax
    popad
  }
  nSDTKerCallLen  =  _KeServiceDescriptorTable->ntoskrnl.NumberOfServices;
 
 
  pSSDTKernel =  (PULONG)ExAllocatePool( NonPagedPool, nSDTKerCallLen*sizeof(ULONG) );
  if(!pSSDTKernel)
  {
    DbgPrint("AddMyServiceTable  alloc fail\n");
    return 0;
  }
  memset( (PVOID)pSSDTKernel, 0, nSDTKerCallLen*sizeof(ULONG));
 
 
  //填充新的SSDT表
  //
  RtlCopyMemory( (PVOID)pSSDTKernel,(PVOID)_KeServiceDescriptorTable->ntoskrnl.ServiceTableBase,nSDTKerCallLen*sizeof(ULONG) );
 
 
  RtlCopyMemory( (PVOID)&_KeServiceDescriptorTable->NotUse1,
    (PVOID)&_KeServiceDescriptorTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE) );
 
 
 
  RtlCopyMemory( (PVOID)&ShadowTable->NotUse1,(PVOID)&ShadowTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE)*2);
 
  WPOFF();
  RtlCopyMemory((PVOID)&_KeServiceDescriptorTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
 
  RtlCopyMemory((PVOID)&ShadowTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
 
  WPON();
 
  return 1;
}
 
void RePlaceSSDT()
{
  if (AddMyServiceTable())
  {
    HookSysCall();
  }
 
}
 
//////////////////////////////////////////////////////////////////////////
 
NTSTATUS
DriverEntry(
  PDRIVER_OBJECT pDriverObj,
  PUNICODE_STRING pRegistryString
  )
{
  NTSTATUS status = STATUS_SUCCESS;
  UNICODE_STRING ustrLinkName;
  UNICODE_STRING ustrDevName;   
  PDEVICE_OBJECT pDevObj;
 
  dprintf("[4BOD] DriverEntry\n");
 
  pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
  pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
  pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
  pDriverObj->DriverUnload = DriverUnload;
 
 
  RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
  status = IoCreateDevice(pDriverObj,
        0,
        &ustrDevName,
        FILE_DEVICE_UNKNOWN,
        0,
        FALSE,
        &pDevObj);
 
  if(!NT_SUCCESS(status))  {
    dprintf("[4BOD] IoCreateDevice = 0x%x\n", status);
    return status;
  }
 
  RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
  status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); 
  if(!NT_SUCCESS(status)) {
    dprintf("[4BOD] IoCreateSymbolicLink = 0x%x\n", status);
    IoDeleteDevice(pDevObj); 
    return status;
  }
 
  Init_fun();
 
  RePlaceSSDT();
 
//  FindProcess();
 
//  SearchMutex();
//  Pass_debugport();
 
   Pass_NtProcess();
 
  Pass_KiAttachProcess();
  
   Pass_NtReadVirtualMemory();
     Pass_NtWriteVirtualMemory();
 
  Pass_NtQueryInformationProcess();
 
   Pass_PsSuspendThread();
   Pass_NtSetContextThread();
 
   Pass_NtGetContextThread();
  
 
  return STATUS_SUCCESS;
}
 
 
VOID
DriverUnload(
  PDRIVER_OBJECT pDriverObj
  )

  UNICODE_STRING strLink;
  LARGE_INTEGER Delay;
  RtlInitUnicodeString(&strLink, LINK_NAME);
 
  UnDetour_NtGetContextThread();
 
  UnDetour_NtSetContextThread();
 
  UnDetour_PsSuspendThread();
 
  UnDetour_NtQueryInformationProcess();
 
   UnDetour_NtWriteVirtualMemory();
   UnDetour_NtReadVirtualMemory();  
  UnDetour_KiAttachProcess();  
 
   UnDetour_NtProcess();
 
 
 
 
  RestoreSSDT();
 
  Delay.QuadPart = -5000000;
 
  KeDelayExecutionThread(KernelMode, TRUE, &Delay);
 
 
  IoDeleteSymbolicLink(&strLink);
  IoDeleteDevice(pDriverObj->DeviceObject);
  dprintf("[4BOD] Unloaded\n");
}
 
 
NTSTATUS
DispatchCreate(
  PDEVICE_OBJECT pDevObj,
  PIRP pIrp
  )
{
  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = 0;
 
  dprintf("[4BOD] IRP_MJ_CREATE\n");
 
  IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  return STATUS_SUCCESS;
}
 
 
NTSTATUS
DispatchClose(
  PDEVICE_OBJECT pDevObj,
  PIRP pIrp
  )
{
  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = 0;
 
  dprintf("[4BOD] IRP_MJ_CLOSE\n");
 
  IoCompleteRequest(pIrp, IO_NO_INCREMENT);
  return STATUS_SUCCESS;
}
 
 
NTSTATUS
DispatchIoctl(
  PDEVICE_OBJECT pDevObj,
  PIRP pIrp
  )
{
  NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
  PIO_STACK_LOCATION pIrpStack;
  ULONG uIoControlCode;
  PVOID pIoBuffer;
  ULONG uInSize;
  ULONG uOutSize;
 
  pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
  uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
  pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
  uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
  uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
 
  switch(uIoControlCode) {
 
    case IOCTL_HELLO: {
     
      dprintf("[4BOD] Hello\n");
      status = STATUS_SUCCESS;
    }
    break;
   
    //
    // 添加执行代码
    //
 
  }
 
  if(status == STATUS_SUCCESS)
    pIrp->IoStatus.Information = uOutSize;
  else
    pIrp->IoStatus.Information = 0;
 
  /////////////////////////////////////
  pIrp->IoStatus.Status = status;
  IoCompleteRequest(pIrp, IO_NO_INCREMENT);
 
  return status;
}
 
 
//////////////////////////////////////////////////////////////////////////
 
 
 
//返回-1:拒绝访问
//返回0 :走NP HOOK
//返回1 :绕过NP HOOK
//
////////////////////////////////////////////////////////////////////////////
ULONG __stdcall IsNPCalled(HANDLE ProcessHandle)
{
 
  NTSTATUS    status;
  PEPROCESS   pEProcess=0;
  char*       proname=0;
 
 
 
 
 
  if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
  {
    if (!ProcessHandle)
    {
      return 0;
 
    }
   
    status = ObReferenceObjectByHandle(ProcessHandle,PROCESS_ALL_ACCESS,NULL,0,&pEProcess,NULL);
   
    if(!NT_SUCCESS(status))
    {
      DbgPrint("ObReferenceObjectByHandle fail! %08x \n",status);
      return 0;
     
    }
    ObDereferenceObject(pEProcess);
    proname=GetProcessNameFromEProc(pEProcess);
   
    if (!_stricmp("OllyDBG.EXE",proname))
    {
      DbgPrint("ollydbg!!!!!!!!! \n");
      return -1;
    }
 
    if (!_stricmp("Shadow.exe",proname))
    {
 
      return -1;
    }
    if (!_stricmp("taskmgr.exe",proname))
    {
 
      return -1;
    }
   
   
    return 0;
  }
  else if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(0)))
  {
   
    return 1;
  }
  else if (!_stricmp("Shadow.exe",GetProcessNameFromEProc(0)))
  {
    return 1;
  }
  else if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(0)))
  {
    return 1;
  }
  else
  { 
    return 0;
  }
 
 
}
 
 
 
//////////////////////////////////////////////////////////////////////////
 
 
ULONG __stdcall IsNPCalled_EP(PEPROCESS EProcess)
{
 
 
  NTSTATUS    status;
  PEPROCESS   pEProcess=0;
  char*       proname=0;
 
 
  if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
  {
    if (!EProcess)
    {
      return 0;
 
    }
   
 
    proname=GetProcessNameFromEProc(EProcess);
   
    if (!_stricmp("OllyDBG.EXE",proname))
    {
      DbgPrint("ollydbg!!!!!!!!! epepepepep\n");
      return -1;
    }
    if (!_stricmp("Shadow.exe",proname))
    {
 
      return -1;
    }
    if (!_stricmp("taskmgr.exe",proname))
    {
 
      return -1;
    }
   
    return 0;
  }
  else if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(0)))
  {
   
    return 1;
  }
  else if (!_stricmp("Shadow.exe",GetProcessNameFromEProc(0)))
  {
 
    return 1;
  }
  else if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(0)))
  {
    return 1;
  }
  else
  { 
    return 0;
  }
 
 
}
 
//////////////////////////////////////////////////////////////////////////
ULONG old_KiMoveApcState;
 
ULONG Init_KiMoveApcState()
{
 
  old_KiMoveApcState=KeStackAttachProcess_Addr-0x6b2;
  return 1;
 
}
 
 
VOID __declspec(naked) _KiMoveApcState (
                    __in PKAPC_STATE Source,
                    __out PKAPC_STATE Destination
                    )
{
  __asm
  {
    jmp  [old_KiMoveApcState]
 
  }
 
 
}
 
 
 
//////////////////////////////////////////////////////////////////////////
ULONG __stdcall fack(PEPROCESS Pep)
{
  __try
  {
    if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
    {
      if (!_stricmp("ollydbg.exe",GetProcessNameFromEProc(Pep)))
      {
        DbgPrint("dnf kiattachprocess ollydbg!!!\n");
        return 1;
      }
    }
  }
  __except(1)
  {
    DbgPrint("fack error!!\n");
  }
  return 0;
}
 
unsigned long KiAttachProcess_reentry_address;
 
void __declspec(naked) my_function_detour_KiAttachProcess()
{
  __asm
  {   
    inc     word ptr [edi+0x60]
    lea     ebx,[esi+0x34]
    push    ebx
    call    _KiMoveApcState
    jmp     [KiAttachProcess_reentry_address]
 
  }
}
 
//////////////////////////////////////////////////////////////////////////
 
char KiAttachProcess_g_oricode[8];
 
ULONG Pass_KiAttachProcess()

  char *actual_function;
 
  KIRQL oldIrql;
  int i = 0;
  unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
 
 
  actual_function = (char *)(KeStackAttachProcess_Addr-0x219);
 
  KiAttachProcess_reentry_address = (KeStackAttachProcess_Addr-0x20c);
 
  *( (unsigned long *)(&newcode[1]) ) = (unsigned long)my_function_detour_KiAttachProcess;
 
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  for(i=0;i < 7;i++)
  {
    KiAttachProcess_g_oricode[i] = actual_function[i];
    actual_function[i] = newcode[i];
  }
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
 
}
 
VOID UnDetour_KiAttachProcess()
{
  char *actual_function = (char *)(KeStackAttachProcess_Addr-0x219);
  KIRQL oldIrql;
  int i = 0;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  for(i=0;i < 7;i++)
  {
    actual_function[i] = KiAttachProcess_g_oricode[i];
  }
  KeLowerIrql(oldIrql);
  WPON();
 
 
 
}
 
 
 
//////////////////////////////////////////////////////////////////////////
 
ULONG OldNtReadVirtualMemoryAdd;
ULONG reentryadd_NtReadVirtualMemory;
__declspec(naked) NTSTATUS NewNtReadVirtualMemory()
{
 
  __asm
  {
    push [esp+4]
    call IsNPCalled
    cmp  eax,1
    jnz  NtReadVirtualMemory_ENT1
    push 0x1c
    push 0x804daef0
    mov  eax, 0x8053cbe0
    call eax
    jmp  [reentryadd_NtReadVirtualMemory]
 
 
NtReadVirtualMemory_ENT1:
 
    cmp  eax,0
    jnz  NtReadVirtualMemory_ENT2
    jmp  [OldNtReadVirtualMemoryAdd]
 
NtReadVirtualMemory_ENT2:
    mov  eax,0
    ret  0x14
  }
 
}
 
 
 
//////////////////////////////////////////////////////////////////////////NtReadVirtualMemory
 
 
 
ULONG Pass_NtReadVirtualMemory()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4;    //得到NtReadVirtualMemory的服务地址
 
  (ULONG)OldNtReadVirtualMemoryAdd = *(ULONG*)Address;    //保存此地址
  reentryadd_NtReadVirtualMemory=OldNtReadVirtualMemoryAdd+0xc;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  *((ULONG*)Address) = (ULONG)NewNtReadVirtualMemory;  //HOOK SSDT
 
  KeLowerIrql(oldIrql);
  WPON();
  return 1;
}
 
//反补丁,用于最后恢复用
VOID UnDetour_NtReadVirtualMemory()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)OldNtReadVirtualMemoryAdd;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
}
 
ULONG reentryadd_NtWriteVirtualMemory;
ULONG OldNtWriteVirtualMemoryAdd;
__declspec(naked) NTSTATUS NewNtWriteVirtualMemory()
{
 
  __asm
  {
    push [esp+4]
    call IsNPCalled
    cmp  eax,1
    jnz  NtWriteVirtualMemory_ENT1
    push 0x1c
    push 0x804daf08
    mov  eax, 0x8053cbe0
    call eax
    jmp  [reentryadd_NtWriteVirtualMemory]
 
 
NtWriteVirtualMemory_ENT1:
 
    cmp  eax,0
    jnz  NtWriteVirtualMemory_ENT2
    jmp  [OldNtWriteVirtualMemoryAdd]
 
NtWriteVirtualMemory_ENT2:
    mov  eax,0
    ret  0x14
  }
 
 
 
}
//////////////////////////////////////////////////////////////////////////
 
 
 
ULONG Pass_NtWriteVirtualMemory()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x115 * 4;
 
  (ULONG)OldNtWriteVirtualMemoryAdd = *(ULONG*)Address;
  reentryadd_NtWriteVirtualMemory=OldNtWriteVirtualMemoryAdd+0xc;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)NewNtWriteVirtualMemory;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
}
 
VOID UnDetour_NtWriteVirtualMemory()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x115 * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)OldNtWriteVirtualMemoryAdd;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
}
//////////////////////////////////////////////////////////////////////////
 
 
 
//////////////////////////////////////////////////////////////////////////NtOpenProcess
 
 
ULONG OldNtProcessAdd;
 
ULONG reentryadd_NtWriteVirtualMemory;
 
 
NTSTATUS
_NtOpenProcess (
         __out PHANDLE ProcessHandle,
         __in ACCESS_MASK DesiredAccess,
         __in POBJECT_ATTRIBUTES ObjectAttributes,
         __in_opt PCLIENT_ID ClientId
         )
{
 
  HANDLE Handle;
  KPROCESSOR_MODE PreviousMode;
  NTSTATUS Status;
  PEPROCESS Process;
  PETHREAD Thread;
  CLIENT_ID CapturedCid={0};
  BOOLEAN ObjectNamePresent;
  BOOLEAN ClientIdPresent;
  ACCESS_STATE AccessState;
  AUX_ACCESS_DATA AuxData;
  ULONG Attributes;
  LUID SeDebugPrivilege = {0};
  POBJECT_TYPE _PsProcessType;
  PEPROCESS tempeprocess;
 
  PsLookupProcessByProcessId(ClientId->UniqueProcess,&tempeprocess);
 
  if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
  {
   
  //  ERROR_INVALID_PARAMETER
 
    __try
    {
  //    DbgPrint("dnf threadid %d KTHREAD %08x want openprocess %s\n",
  //    PsGetCurrentThreadId(),PsGetCurrentThread(),GetProcessNameFromEProc(tempeprocess));
 
      if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(tempeprocess)) )
      {
        return STATUS_INVALID_PARAMETER;
      }
      if (!_stricmp("DNF.exe",GetProcessNameFromEProc(tempeprocess)) )
      {
      //  return STATUS_INVALID_PARAMETER;
      }
      if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(tempeprocess)) )
      {
        return STATUS_INVALID_PARAMETER;
      }
     
 
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
      DbgPrint("GetExceptionCode %08x",GetExceptionCode());
    //  return GetExceptionCode();
    }
   
 
    return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
  }
 
//  DbgPrint("%s want openprocess %s\n",GetProcessNameFromEProc(0),GetProcessNameFromEProc(tempeprocess));
 
  (ULONG)_PsProcessType=*(ULONG*)PsProcessType;
  PreviousMode = KeGetPreviousMode();
  SeDebugPrivilege =RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
  if (PreviousMode != KernelMode) {
    __try {
      ProbeForWriteHandle (ProcessHandle);
 
      ProbeForReadSmallStructure (ObjectAttributes,
        sizeof(OBJECT_ATTRIBUTES),
        sizeof(ULONG));
      ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
      Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, UserMode);
 
      if (ARGUMENT_PRESENT (ClientId)) {
        ProbeForReadSmallStructure (ClientId, sizeof (CLIENT_ID), sizeof (ULONG));
        CapturedCid = *ClientId;
        ClientIdPresent = TRUE;
      } else {
        ClientIdPresent = FALSE;
      }
    }
    __except (EXCEPTION_EXECUTE_HANDLER) {
      return GetExceptionCode();
    }
  } else {
    ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
    Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, KernelMode);
    if (ARGUMENT_PRESENT (ClientId)) {
      CapturedCid = *ClientId;
      ClientIdPresent = TRUE;
    } else {
      ClientIdPresent = FALSE;
    }
  }
 
  if (ObjectNamePresent && ClientIdPresent) {
    return STATUS_INVALID_PARAMETER_MIX;
  }
 
  Status = SeCreateAccessState(
    &AccessState,
    &AuxData,
    DesiredAccess,
    &_PsProcessType->TypeInfo.GenericMapping
    );
 
  if ( !NT_SUCCESS(Status) ) {
 
    return Status;
  }
 
  if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
 
    if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
      AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
 
    } else {
 
      AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
    }
 
    AccessState.RemainingDesiredAccess = 0;
 
  }
  if (ObjectNamePresent) {
 
 
    Status = ObOpenObjectByName(
      ObjectAttributes,
      _PsProcessType,
      PreviousMode,
      &AccessState,
      0,
      NULL,
      &Handle
      );
 
    SeDeleteAccessState( &AccessState );
 
    if ( NT_SUCCESS(Status) ) {
      __try {
        *ProcessHandle = Handle;
      }
      __except (EXCEPTION_EXECUTE_HANDLER) {
        return GetExceptionCode ();
      }
    }
    return Status;
  }
 
  if ( ClientIdPresent ) {
 
    Thread = NULL;
    if (CapturedCid.UniqueThread) {
      Status = PsLookupProcessThreadByCid(
        &CapturedCid,
        &Process,
        &Thread
        );
 
      if (!NT_SUCCESS(Status)) {
        SeDeleteAccessState( &AccessState );
        return Status;
      }
    } else {
      Status = PsLookupProcessByProcessId(
        CapturedCid.UniqueProcess,
        &Process
        );
 
      if ( !NT_SUCCESS(Status) ) {
        SeDeleteAccessState( &AccessState );
        return Status;
      }
    }
 
    //
    // OpenObjectByAddress
    //
    Status = ObOpenObjectByPointer(
      Process,
      Attributes,
      &AccessState,
      0,
      _PsProcessType,
      PreviousMode,
      &Handle
      );
 
    SeDeleteAccessState( &AccessState );
 
    if (Thread) {
      ObDereferenceObject(Thread);
    }
 
    ObDereferenceObject(Process);
 
    if (NT_SUCCESS (Status)) {
 
      __try {
        *ProcessHandle = Handle;
      }
      __except (EXCEPTION_EXECUTE_HANDLER) {
        return GetExceptionCode ();
      }
    }
    return Status;
  }
  return STATUS_INVALID_PARAMETER_MIX;
}
 
 
ULONG Pass_NtProcess()
{
 
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase +  0x7A * 4;
 
  OldNtProcessAdd = *(ULONG*)Address;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)_NtOpenProcess;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
}
 
VOID UnDetour_NtProcess()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase +  0x7A * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = OldNtProcessAdd;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
}
 
//////////////////////////////////////////////////////////////////////////
 
 
void Init_fun()
{
  KeStackAttachProcess_Addr=GetFunctionAddr(L"KeStackAttachProcess");
  Init_KiMoveApcState();
}
//////////////////////////////////////////////////////////////////////////
 
 
//////////////////////////////////////////////////////////////////////////
 
 
 
#define SYSTEMSERVICE(Index)    *(PULONG)((ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase+ Index*4);  
 
ULONG DbgkForwardExceptionAddr    =    0;
ULONG KiDispatchExceptionAddr    =    0;
ULONG DbgkpQueueMessageAddr        =    0;
 
ULONG SearchMutex()
{
  ULONG NtResumeThreadAddr        =    0;
  ULONG NtRaiseExceptionAddr        =    0;
  ULONG KiRaiseExceptionAddr        =    0;
 
 
  ULONG DbgkpSendApiMessageAddr    =    0;
 
  ULONG DbgkpProcessDebugPortMutex    =0;   
  ULONG PsResumeThreadAddr          =0;       
  DWORD dwKey;
  ULONG i;
 
 
  NtResumeThreadAddr = SYSTEMSERVICE(206);
  DbgPrint("NtResumeThreadAddr : %X\n", NtResumeThreadAddr);
 
  for(i = NtResumeThreadAddr; i < NtResumeThreadAddr + 0x7C; i++)
  {
    dwKey = *(PDWORD)i;
    if (MmIsAddressValid(&dwKey))
    {
      if (dwKey == 0xE8E475FF)
      {
        dwKey = i + 4;
        PsResumeThreadAddr = i + *(ULONG*)dwKey + 8;
      }
    }
  }
  DbgPrint("PsResumeThreadAddr : %X\n", PsResumeThreadAddr);
 
  NtRaiseExceptionAddr = SYSTEMSERVICE(181);
  DbgPrint("NtRaiseExceptionAddr : %X\n", NtRaiseExceptionAddr);
 
  for(i = NtRaiseExceptionAddr; i < NtRaiseExceptionAddr + 0x30; i++)
  {
    dwKey = *(PDWORD)i;
    if (MmIsAddressValid(&dwKey))
    {
      if (dwKey == 0xE8505100)
      {
        dwKey = i + 4;
        KiRaiseExceptionAddr = i + *(ULONG*)dwKey + 8;
      }
    }
  }
  DbgPrint("KiRaiseExceptionAddr : %X\n", KiRaiseExceptionAddr);
 
  if (KiRaiseExceptionAddr > 0x80000000)
  {
    for(i = KiRaiseExceptionAddr; i < KiRaiseExceptionAddr + 0x197; i++)
    {
      dwKey = *(PDWORD)i;
      if (MmIsAddressValid(&dwKey))
      {
        if (dwKey == 0xE853FFFF)
        {
          dwKey = i + 4;
          KiDispatchExceptionAddr = i + *(ULONG*)dwKey + 8;
        }
      }
    }
    DbgPrint("KiDispatchExceptionAddr : %X\n", KiDispatchExceptionAddr);
  }
 
  if (KiDispatchExceptionAddr > 0x80000000)
  {
    for(i = KiDispatchExceptionAddr; i < KiDispatchExceptionAddr + 0x397; i++)
    {
      dwKey = *(PDWORD)i;
      if (MmIsAddressValid(&dwKey))
      {
        if (dwKey == 0xE8565701)
        {
          dwKey = i + 4;
          DbgkForwardExceptionAddr = i + *(ULONG*)dwKey + 8;
        }
      }
    }
    DbgPrint("DbgkForwardExceptionAddr : %X\n", DbgkForwardExceptionAddr);
  }
 
 
  if (DbgkForwardExceptionAddr > 0x80000000)
  {
    for(i = DbgkForwardExceptionAddr; i < DbgkForwardExceptionAddr + 0x8A; i++)
    {
      dwKey = *(PDWORD)i;
      if (MmIsAddressValid(&dwKey))
      {
        if (dwKey == 0xE8508845)
        {
          dwKey = i + 4;
          DbgkpSendApiMessageAddr = i + *(ULONG*)dwKey + 8;
        }
      }
    }
    DbgPrint("DbgkpSendApiMessageAddr : %X\n", DbgkpSendApiMessageAddr);
  }
 
  if (DbgkpSendApiMessageAddr > 0x80000000)
  {
    for(i = DbgkpSendApiMessageAddr; i < DbgkpSendApiMessageAddr + 0x55; i++)
    {
      dwKey = *(PDWORD)i;
      if (MmIsAddressValid(&dwKey))
      {
        if (dwKey == 0xE8515052)
        {
          dwKey = i + 4;
          DbgkpQueueMessageAddr = i + *(ULONG*)dwKey + 8;
        }
      }
    }
    DbgPrint("DbgkpQueueMessageAddr : %X\n", DbgkpQueueMessageAddr);
  }
 
  if (DbgkpQueueMessageAddr > 0x80000000)
  {
    for(i = DbgkpQueueMessageAddr; i < DbgkpQueueMessageAddr + 0x16F; i++)
    {
      dwKey = *(PDWORD)i;
      if (MmIsAddressValid(&dwKey))
      {
        if (dwKey == 0xB93075FC)
        {
          dwKey = i + 4;
          DbgkpProcessDebugPortMutex = *(ULONG*)dwKey;
        }
      }
    }
    DbgPrint("DbgkpProcessDebugPortMutex : %X\n", DbgkpProcessDebugPortMutex);
  }
 
  return DbgkpProcessDebugPortMutex;
 
}
 
//////////////////////////////////////////////////////////////////////////
ULONG Pass_debugport()
{
  KIRQL oldIrql;
 
  char  timestr[]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
 
  char* g_KiDispatchException=(char*)(KiDispatchExceptionAddr+0x187);
  char* g_PspCreateProcess=(char*)(KiDispatchExceptionAddr+0xD2599);
  char* g_DbgkForwardException=(char*)(DbgkForwardExceptionAddr+0x3e);
  char* g_DbgkpQueueMessage=(char*)(DbgkpQueueMessageAddr+0x7B);
  char* g_DbgkCreateThread=(char*)(KiDispatchExceptionAddr+0x14515F);
  char* g_DbgkExitThread=(char*)(KiDispatchExceptionAddr+0x1453F8);
  char* g_DbgkMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x14550B);
  char* g_DbgkExitProcess=(char*)(KiDispatchExceptionAddr+0x145472);
  char* g_DbgkUnMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x1455D1);
  char* g_PspExitThread=(char*)(KiDispatchExceptionAddr+0xD3E84);
  char* g_DbgkpMarkProcessPeb=(char*)(KiDispatchExceptionAddr+0x1438EA);
  char* g_MmCreatePeb=(char*)(KiDispatchExceptionAddr+0xB1907);
  char* g_DbgkpSetProcessDebugObject=(char*)(KiDispatchExceptionAddr+0x144934);
  char* g_DbgkpSetProcessDebugObject1=(char*)(KiDispatchExceptionAddr+0x144942);
  char* g_DbgkpSetProcessDebugObject2=(char*)(KiDispatchExceptionAddr+0x14495C);
  char* g_DbgkpSetProcessDebugObject3=(char*)(KiDispatchExceptionAddr+0x1449A6);
  char* g_DbgkpSetProcessDebugObject4=(char*)(KiDispatchExceptionAddr+0x1449E8);
 
 
 
//nop
 
  char* anti_DbgkExitThread=(char*)(KiDispatchExceptionAddr+0x1453F6);
  char* anti_DbgkExitProcess=(char*)(KiDispatchExceptionAddr+0x145470);
  char* anti_DbgkUnMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x1455CF);
 
//jmp
 
  char* anti_DbgkMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x145505);
  char* anti_DbgkForwardException=(char*)(DbgkForwardExceptionAddr+0x38);
 
//nop create time
 
  char* g_PspCreateProcess_time=(char*)(KiDispatchExceptionAddr+0xD2B15);
 
 
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  memcpy(g_PspCreateProcess_time,timestr,9);
 
  *(ULONG*)(&g_KiDispatchException[2])=0x70;
  *(ULONG*)(&g_PspCreateProcess[2])=0x70;
  *(ULONG*)(&g_DbgkForwardException[2])=0x70;
  *(ULONG*)(&g_DbgkpQueueMessage[2])=0x70;
  *(ULONG*)(&g_DbgkCreateThread[2])=0x70;
  *(ULONG*)(&g_DbgkExitThread[2])=0x70;
  *(ULONG*)(&g_DbgkMapViewOfSection[2])=0x70;
  *(ULONG*)(&g_DbgkExitProcess[2])=0x70;
  *(ULONG*)(&g_DbgkUnMapViewOfSection[2])=0x70;
  *(ULONG*)(&g_PspExitThread[2])=0x70;
  *(ULONG*)(&g_DbgkpMarkProcessPeb[2])=0x70;
  *(ULONG*)(&g_MmCreatePeb[2])=0x70;
  *(ULONG*)(&g_DbgkpSetProcessDebugObject[2])=0x70;
  *(ULONG*)(&g_DbgkpSetProcessDebugObject1[2])=0x70;
  *(ULONG*)(&g_DbgkpSetProcessDebugObject2[2])=0x70;
  *(ULONG*)(&g_DbgkpSetProcessDebugObject3[2])=0x70;
  *(ULONG*)(&g_DbgkpSetProcessDebugObject4[2])=0x70;
 
//
//   anti_DbgkExitThread[0]=0x90;
//   anti_DbgkExitThread[1]=0x90;
//   anti_DbgkExitProcess[0]=0x90;
//   anti_DbgkExitProcess[1]=0x90;
//   anti_DbgkUnMapViewOfSection[0]=0x90;
//   anti_DbgkUnMapViewOfSection[1]=0x90;
//
//   anti_DbgkMapViewOfSection[0]=0xeb;
//   anti_DbgkForwardException[0]=0xeb;
 
 
  KeLowerIrql(oldIrql);
  WPON();
 
 
 
  return STATUS_SUCCESS;
 
}
const int process_list_offset=0x88;
const int createtime_list_offset=0x70;
 
ULONG FindProcess()
{
  ULONG cproc=0x00000000;
  ULONG  i=0;
  ULONG TPID;
  PEPROCESS tmpeprocess;
  PLIST_ENTRY plist_active_procs;
  LARGE_INTEGER temptime;
  temptime.QuadPart=0;
 
 
  PsLookupProcessByProcessId((HANDLE)4,&tmpeprocess);
  cproc=(ULONG)tmpeprocess;
 
 
  while (1)
  {
   
    if ((i>=1) && ((ULONG)tmpeprocess==cproc))
    {
      break;
      return 0x00000000;
    }
    else
    {
      plist_active_procs=(LIST_ENTRY*)(cproc+process_list_offset);
      cproc=(ULONG)plist_active_procs->Flink;
      cproc=cproc-process_list_offset;
 
      *(LARGE_INTEGER*)(cproc+createtime_list_offset)=temptime;
 
      i++;
 
    }
 
  }
 
 
  return 1;
}
 
//////////////////////////////////////////////////////////////////////////
 
 
typedef NTSTATUS (*NTQUERYINFORMATIONPROCESS)(
  __in       HANDLE ProcessHandle,
  __in       PROCESSINFOCLASS ProcessInformationClass,
  __out      PVOID ProcessInformation,
  __in       ULONG ProcessInformationLength,
  __out_opt  PULONG ReturnLength
  );
 
NTQUERYINFORMATIONPROCESS OldNQueryInformationProcessAddr;
 
typedef struct _PROCESS_DEBUG_PORT_INFO    
{  
     
   HANDLE DebugPort;  
     
} PROCESS_DEBUG_PORT_INFO;  
     
       
       
//enum SYSTEM_INFORMATION_CLASS { SystemKernelDebuggerInformation = 35 };  
     
//enum THREAD_INFO_CLASS { ThreadHideFromDebugger = 17 };  
     
//enum PROCESS_INFO_CLASS { ProcessDebugPort = 7 };
 
 
 
NTSTATUS  NewNtQueryInformationProcess(
  __in       HANDLE ProcessHandle,
  __in       PROCESSINFOCLASS ProcessInformationClass,
  __out      PROCESS_DEBUG_PORT_INFO* ProcessInformation,
  __in       ULONG ProcessInformationLength,
  __out_opt  PULONG ReturnLength
  )
{
//  PROCESS_DEBUG_PORT_INFO* tempPi;
  if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)) ||
    !_stricmp("AION.bin",GetProcessNameFromEProc(0)) ||
    !_stricmp("GameMon.des",GetProcessNameFromEProc(0)))
  {
    if (ProcessInformationClass==7)
    {
      DbgPrint("%s NtQueryInformationProcess debugport!\n",GetProcessNameFromEProc(0));
      ProcessInformation->DebugPort=0;
      return 0;
    }
 
  }
 
//  DbgPrint("%s NtQueryInformationProcess !\n",GetProcessNameFromEProc(0));
 
  return OldNQueryInformationProcessAddr(ProcessHandle,ProcessInformationClass,ProcessInformation,ProcessInformationLength,ReturnLength);
 
}
 
 
 
ULONG Pass_NtQueryInformationProcess()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 154 * 4;
 
  (ULONG)OldNQueryInformationProcessAddr = *(ULONG*)Address;
 
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)NewNtQueryInformationProcess;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
}
 
VOID UnDetour_NtQueryInformationProcess()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 154 * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)OldNQueryInformationProcessAddr;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
}
//////////////////////////////////////////////////////////////////////////
 
// NTSTATUS __declspec(naked) _PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
// {
//
// }
 
 
 
//////////////////////////////////////////////////////////////////////////
 
//unsigned long PsSuspendThread_reentry_address;
ULONG pssuspendthreadaddr;
 
NTSTATUS __declspec(naked) _PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
{
  __asm
  {   
    push 0x18
    push 0x804db9e8
    mov   esi,0x8053cbe0
    call esi
    mov  esi,pssuspendthreadaddr
    add  esi,0xc
    jmp  esi
 
  }
}
//////////////////////////////////////////////////////////////////////////
 
 
 
NTSTATUS
_NtSuspendThread(
    __in HANDLE ThreadHandle,
    __out_opt PULONG PreviousSuspendCount
    )
 
{
    PETHREAD Thread;
    NTSTATUS st;
    ULONG LocalPreviousSuspendCount;
    KPROCESSOR_MODE Mode;
  POBJECT_TYPE TempType;
 
 //   PAGED_CODE();
 
    Mode = KeGetPreviousMode ();
 
    try {
 
        if (Mode != KernelMode) {
            if (ARGUMENT_PRESENT (PreviousSuspendCount)) {
                ProbeForWriteUlong (PreviousSuspendCount);
            }
        }
    } except (EXCEPTION_EXECUTE_HANDLER) {
 
        return GetExceptionCode();
    }
 
  (ULONG)TempType=*(ULONG*)PsThreadType;
    st = ObReferenceObjectByHandle (ThreadHandle,
                                    THREAD_SUSPEND_RESUME,
                                    TempType,
                                    Mode,
                                    &Thread,
                                    NULL);
 
    if (!NT_SUCCESS (st)) {
        return st;
    }
 
    st = _PsSuspendThread (Thread, &LocalPreviousSuspendCount);
 
    ObDereferenceObject (Thread);
 
    try {
 
        if (ARGUMENT_PRESENT (PreviousSuspendCount)) {
            *PreviousSuspendCount = LocalPreviousSuspendCount;
        }
 
    } except (EXCEPTION_EXECUTE_HANDLER) {
 
        st = GetExceptionCode ();
 
    }
 
    return st;
 
}
 
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS(*NTSUSPENDTHREAD)(
  __in HANDLE ThreadHandle,
  __out_opt PULONG PreviousSuspendCount
  );
 
NTSUSPENDTHREAD OldSuspendThreadAddr;
 
NTSTATUS MyNtSuspendThread(
  __in HANDLE ThreadHandle,
  __out_opt PULONG PreviousSuspendCount
  )
{
  if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
  {
    return OldSuspendThreadAddr(ThreadHandle,PreviousSuspendCount);
  }
  return _NtSuspendThread(ThreadHandle,PreviousSuspendCount);
 
}
 
ULONG Pass_PsSuspendThread()

  KIRQL oldIrql;
  ULONG  Address=0;
  LONG temp=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 254 * 4;
 
  (ULONG)OldSuspendThreadAddr = *(ULONG*)Address;
  temp=*(LONG*)((LONG)OldSuspendThreadAddr+0x65);
  pssuspendthreadaddr=(LONG)OldSuspendThreadAddr+0x64+temp+5;
 
  DbgPrint("pssuspendthreadaddr %08x\n",pssuspendthreadaddr);
 
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)MyNtSuspendThread;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
 
}
 
VOID UnDetour_PsSuspendThread()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 254 * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)OldSuspendThreadAddr;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
}
 
 
 
//////////////////////////////////////////////////////////////////////////
 

 
NTSTATUS
MyNtGetContextThread(
    __in HANDLE ThreadHandle,
    __inout PCONTEXT ThreadContext
    )
 
{
 
    KPROCESSOR_MODE Mode;
    NTSTATUS Status;
    PETHREAD Thread;
    PKTHREAD CurrentThread;
  POBJECT_TYPE TempType;
 
 
  //  PAGED_CODE();
 
    //
    // Get previous mode and reference specified thread.
    //
 
    CurrentThread = KeGetCurrentThread();
    Mode = *(CCHAR*)((ULONG)CurrentThread+0x140);
 
  (ULONG)TempType=*(ULONG*)PsThreadType;
 
    Status = ObReferenceObjectByHandle (ThreadHandle,
                                        THREAD_GET_CONTEXT,
                                        TempType,
                                        Mode,
                                        &Thread,
                                        NULL);
 
    //
    // If the reference was successful, the check if the specified thread
    // is a system thread.
    //
 
    if (NT_SUCCESS (Status)) {
 
        //
        // If t