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

游戏保护大放送之TP

程序员文章站 2022-06-27 16:48:55
本人寻求游戏安全方面的工作,请Email:wtxpwh@163.com联系 做挂者请绕道!   本人不保证此办法现在还生效!蓝屏死机于本人无关!    ...
本人寻求游戏安全方面的工作,请Email:wtxpwh@163.com联系
做挂者请绕道!
 
本人不保证此办法现在还生效!蓝屏死机于本人无关!
 
 
tp主要hook NtOpenProcess NtReadVirturalMemory NtWriteVirtualMemory KiattachProcess 还有debugport清零。直接上代码懒的多说,代码面前了无秘密。
 
代码:
/***************************************************************************************
* AUTHOR : sudami [sudami@163.com]
* TIME   : 2008/08/13
* MODULE : aNgE.C
*
* Command:
*  
*  
*
* Description:
*   s
*                       
*
***
* Copyright (c) 2008 - 2010 sudami.
* Freely distributable in source or binary for noncommercial purposes.
* TAKE IT EASY,JUST FOR FUN.
*
****************************************************************************************/
 
#include "struct.h"
#include "aNgE.h"
#include <stdlib.h>
#include <stdio.h>
 
//////////////////////////////////////////////////////////////////////////
 
ULONG Pass_NtOpenThread();
ULONG Pass_NtOpenProcess();
 
ULONG Pass_NtProcess();
ULONG Pass_NtReadVirtualMemory();
ULONG Pass_NtWriteVirtualMemory();
ULONG Pass_KiAttachProcess();
ULONG Pass_DebugPort();
ULONG Pass_KernelDebug();
 
 
VOID UnDetour_NtOpenProcess();
VOID UnDetour_NtProcess();
VOID UnDetour_NtOpenThread();
VOID UnDetour_NtReadVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
 
unsigned long Pass_PsCreateSystemThread();
VOID UnDetour_PsCreateSystemThread();
 
 
VOID
CitydOnTimer(
       IN PDEVICE_OBJECT DeviceObject,
       IN PVOID Context
       );
 
ULONG TenBase=0;
 
 
//////////////////////////////////////////////////////////////////////////
 
NTSTATUS
DriverEntry(
  PDRIVER_OBJECT pDriverObj,
  PUNICODE_STRING pRegistryString
  )
{
  NTSTATUS status = STATUS_SUCCESS;
  UNICODE_STRING ustrLinkName;
  UNICODE_STRING ustrDevName;   
  PDEVICE_OBJECT pDevObj;
 
  dprintf("[aNgE] 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("[aNgE] IoCreateDevice = 0x%x\n", status);
    return status;
  }
 
  IoInitializeTimer(pDevObj,CitydOnTimer,NULL);
 
  IoStartTimer(pDevObj);
 
  RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
  status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); 
  if(!NT_SUCCESS(status)) {
    dprintf("[aNgE] IoCreateSymbolicLink = 0x%x\n", status);
    IoDeleteDevice(pDevObj); 
    return status;
  }
 
/**/
 
  Pass_NtProcess();
 
  Pass_NtOpenThread();
 
  Pass_NtReadVirtualMemory();
 
  Pass_NtWriteVirtualMemory();
  Pass_PsCreateSystemThread();
 
 
//  Pass_NtOpenProcess();
//  Pass_KiAttachProcess();
 
//  Pass_DebugPort();
//  Pass_KernelDebug();
 
 
 
  return STATUS_SUCCESS;
}
 
 
VOID
DriverUnload(
  PDRIVER_OBJECT pDriverObj
  )

  UNICODE_STRING strLink;
  LARGE_INTEGER Delay;
 
  RtlInitUnicodeString(&strLink, LINK_NAME);
/**/
  IoStopTimer(pDriverObj->DeviceObject);
 
  UnDetour_NtProcess();
 
    UnDetour_NtOpenThread();
   UnDetour_NtReadVirtualMemory();
   UnDetour_NtWriteVirtualMemory();
 
  UnDetour_PsCreateSystemThread();
 
//  UnDetour_NtOpenProcess();
  Delay.QuadPart = -50000;
 
  KeDelayExecutionThread(KernelMode, TRUE, &Delay);
 
  IoDeleteSymbolicLink(&strLink);
  IoDeleteDevice(pDriverObj->DeviceObject);
  dprintf("[aNgE] Unloaded\n");
}
 
 
NTSTATUS
DispatchCreate(
  PDEVICE_OBJECT pDevObj,
  PIRP pIrp
  )
{
  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = 0;
 
  dprintf("[aNgE] 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("[aNgE] 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("[aNgE] 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;
}
#pragma pack(1)
typedef struct ServiceDescriptorEntry
{
  unsigned int *ServiceTableBase;
  unsigned int *ServiceCounterTableBase;
  unsigned int NumberOfServices;
  unsigned char *ParamTableBase;
} SSDT_Entry;
#pragma pack()
 
__declspec(dllimport) SSDT_Entry KeServiceDescriptorTable;
 
 
//////////////////////////////////////////////////////////////////////////
ULONG g_uCr0;
 
 
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;
  };
 
}
//////////////////////////////////////////////////////////////////////////NtReadVirtualMemory
 
 
ULONG OldNtReadVirtualMemoryAdd;//原来NtReadVirtualMemory的服务地址
 
ULONG reentryadd_NtReadVirtualMemory;
 
 
__declspec(naked) NTSTATUS __stdcall NewNtReadVirtualMemory(
  IN HANDLE               ProcessHandle,
  IN PVOID                BaseAddress,
  OUT PVOID               Buffer,
  IN ULONG                NumberOfBytesToRead,
  OUT PULONG              NumberOfBytesReaded OPTIONAL)
{
  __asm
  {
    push    0x1C
    push  0x804daef0
    jmp    [reentryadd_NtReadVirtualMemory]
 
  }
}
 
 
 
 
ULONG Pass_NtReadVirtualMemory()
{
 
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
 
  OldNtReadVirtualMemoryAdd = *(ULONG*)Address;
 
 
  reentryadd_NtReadVirtualMemory = *(ULONG*)Address;
  reentryadd_NtReadVirtualMemory=reentryadd_NtReadVirtualMemory + 0x7;
 
  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.ServiceTableBase + 0xBA * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = OldNtReadVirtualMemoryAdd;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
}
 
 
 
//////////////////////////////////////////////////////////////////////////NtWriteVirtualMemory
 
 
ULONG OldNtWriteVirtualMemoryAdd;//原来NtWriteVirtualMemory的服务地址
 
ULONG reentryadd_NtWriteVirtualMemory;
 
 
__declspec(naked) NTSTATUS __stdcall NewNtWriteVirtualMemory(
  IN HANDLE               ProcessHandle,
  IN PVOID                BaseAddress,
  IN PVOID                Buffer,
  IN ULONG                NumberOfBytesToWrite,
  OUT PULONG              NumberOfBytesWritten OPTIONAL )
{
  __asm
  {
    push    0x1C
    push  0x804daf08
    jmp    [reentryadd_NtWriteVirtualMemory]
 
  }
}
 
ULONG Pass_NtWriteVirtualMemory()
{
 
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0x115 * 4;
 
  OldNtWriteVirtualMemoryAdd = *(ULONG*)Address;
 
  reentryadd_NtWriteVirtualMemory = *(ULONG*)Address;
  reentryadd_NtWriteVirtualMemory=reentryadd_NtWriteVirtualMemory + 0x7;
 
  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.ServiceTableBase + 0x115 * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = OldNtWriteVirtualMemoryAdd;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
}
//////////////////////////////////////////////////////////////////////////
 
ULONG GetFunctionAddr( IN PCWSTR FunctionName);
 
 
 
//////////////////////////////////////////////////////////////////////////KiAttachProcess
 
 
//ULONG* UX;
 
ULONG Pass_KiAttachProcess()
{
//  *UX++;
  unsigned char* actual_function;
  KIRQL oldIrql;
  int i=0;
  unsigned char newcode[] = { 0x8b, 0xff, 0x55, 0x8b, 0xec, 0x53, 0x56 };
 
  actual_function = (unsigned char *) GetFunctionAddr(L"KeUnstackDetachProcess");
  actual_function=actual_function+0x324;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  for(i=0;i < 7;i++)
  {
    actual_function[i] = newcode[i];
  }
 
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
 
}
 
 
//////////////////////////////////////////////////////////////////////////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 cpeprocess,temp_peprocess;
 
  PAGED_CODE();
 
 
  cpeprocess=PsGetCurrentProcess();
 
 
  if (!_stricmp("DNF.exe",(char*)((ULONG)cpeprocess+0x174)))
  {
//    DbgPrint("DNF called!");
    
    Status = PsLookupProcessByProcessId(
      CapturedCid.UniqueProcess,
      &temp_peprocess
      );
    if (NT_SUCCESS(Status))
    {
      if (!_stricmp("csrss.exe",(char*)((ULONG)temp_peprocess+0x174)))
      {
        return STATUS_ACCESS_DENIED;
 
      }
      if (!_stricmp("OllyDBG.EXE",(char*)((ULONG)temp_peprocess+0x174)))
      {
        return STATUS_ACCESS_DENIED;
 
      }
      if (!_stricmp("Ollyice.EXE",(char*)((ULONG)temp_peprocess+0x174)))
      {
        return STATUS_ACCESS_DENIED;
 
      }
 
    }
 
//    DbgPrint("%08x called! want to open %s\n",(unsigned long)cpeprocess,((ULONG)temp_peprocess+0x174));
 
    return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
 
  }
 
  (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.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.ServiceTableBase +  0x7A * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = OldNtProcessAdd;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
}
 
//////////////////////////////////////////////////////////////////////////
//base ab78e000
//nop-2 ab78fe9e ab79359d
//jmp-1 ab79558f ab79171c
 
 
 
//////////////////////////////////////////////////////////////////////////
 
 
 
ULONG Pass_DebugPort()
{
 
//  ULONG Detour_Add;
  unsigned char* Detour_Add_559d;//nop 2 byte
  unsigned char* Detour_Add_1e9e;//nop 2 byte
 
  unsigned char* Detour_Add_371c;//jmp 1 byte check code seg
  unsigned char* Detour_Add_758f;//jmp 1 byte check kiattachprocess
 
//   unsigned char* Detour_Add_735e;//jmp
//   unsigned char* Detour_Add_2471;//jmp
//   unsigned char* Detour_Add_2490;//jmp
//   unsigned char* Detour_Add_5f8c;//jmp
//   unsigned char* Detour_Add_4f9a;//jmp
//   unsigned char* Detour_Add_6352;//jmp
//   unsigned char* Detour_Add_4232;//jmp
//   unsigned char* Detour_Add_3787;//jmp
 
 
 
 
 
 
  KIRQL oldIrql;
  ULONG  Address=0,tempadd=0;
  ULONG i=0;
 
//  unsigned char code_ret[] = { 0xc3, 0x90};//16ac 4250   ret
//73ce  jmp
 
 
//  Address = (ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4;
 
//  tempadd = *(ULONG*)Address;
 
//  TenBase=((*(ULONG*)(tempadd+1))-0x3308);
 
  (ULONG)Detour_Add_559d=TenBase+0x559d;
  (ULONG)Detour_Add_1e9e=TenBase+0x1e9e;
  (ULONG)Detour_Add_371c=TenBase+0x371c;
  (ULONG)Detour_Add_758f=TenBase+0x758f;
 
//   (ULONG)Detour_Add_735e=TenBase+0x735e;
//   (ULONG)Detour_Add_2471=TenBase+0x2471;
//   (ULONG)Detour_Add_2490=TenBase+0x2490;
//   (ULONG)Detour_Add_5f8c=TenBase+0x5f8c;
//   (ULONG)Detour_Add_4f9a=TenBase+0x4f9a;
//   (ULONG)Detour_Add_6352=TenBase+0x6352;
//   (ULONG)Detour_Add_4232=TenBase+0x4232;
//   (ULONG)Detour_Add_3787=TenBase+0x3787;
 
 
 
  //Detour_Add=*(ULONG*)(TenBase+0xcedc)+4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  Detour_Add_371c[0]=0xeb;
  Detour_Add_758f[0]=0xeb;
 
//   Detour_Add_735e[0]=0xeb;
//   Detour_Add_2471[0]=0xeb;
//   Detour_Add_2490[0]=0xeb;
//   Detour_Add_5f8c[0]=0xeb;
//   Detour_Add_4f9a[0]=0xeb;
//   Detour_Add_6352[0]=0xeb;
//   Detour_Add_4232[0]=0xeb;
//   Detour_Add_3787[0]=0xeb;
 
 
  for(i=0;i < 2;i++)
  {
    Detour_Add_559d[i] = 0x90;
    Detour_Add_1e9e[i] = 0x90;
  }
 
//  *(ULONG*)Detour_Add=0x70;
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
 
}
 
VOID UnDetour_DebugPort()
{
  KIRQL oldIrql;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
//  *(ULONG*)Detour_Add=0xbc;
  KeLowerIrql(oldIrql);
  WPON();
 
}
//////////////////////////////////////////////////////////////////////////
 
ULONG Pass_KernelDebug()
{
 
  KIRQL oldIrql;
  ULONG  Address=0;
  ULONG _Detour_Add;
 
 
  Address = *(ULONG*)((ULONG)KeServiceDescriptorTable.ServiceTableBase + 0xBA * 4);
 
  Address=*(ULONG*)(Address+1);
 
  _Detour_Add=Address-0x2e1;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  *(unsigned short*)_Detour_Add=0x9090;
  KeLowerIrql(oldIrql);
  WPON();
 
  KdEnableDebugger();
 
  return 1;
 
}
//////////////////////////////////////////////////////////////////////////
 
 
VOID
CitydOnTimer(
       IN PDEVICE_OBJECT DeviceObject,
       IN PVOID Context
       )
{
  unsigned char* Detour_Add_559d;//nop 2 byte
  unsigned char* Detour_Add_1e9e;//nop 2 byte
 
  unsigned char* Detour_Add_371c;//jmp 1 byte check code seg
  unsigned char* Detour_Add_758f;//jmp 1 byte check kiattachprocess
 
 
 
  unsigned char* ntreadmem=(unsigned char*)OldNtReadVirtualMemoryAdd;
 
  __try
  { www.2cto.com
   
    if (ntreadmem[0]!=0x6a)
    {
      //TenBase=((*(ULONG*)(OldNtReadVirtualMemoryAdd+1))-0x3308);
      TenBase=((*(ULONG*)(OldNtReadVirtualMemoryAdd+1))-0x273c);
      DbgPrint("TenBase=%08x\n",TenBase);
 
      (ULONG)Detour_Add_559d=TenBase+0x559d;
      (ULONG)Detour_Add_1e9e=TenBase+0x1e9e;
      (ULONG)Detour_Add_371c=TenBase+0x371c;
      (ULONG)Detour_Add_758f=TenBase+0x758f;
 
      if (Detour_Add_371c[0]==0x74 || Detour_Add_758f[0]==0x74 || Detour_Add_559d[0]==0x87 || Detour_Add_1e9e[0]==0x87)
      {
        DbgPrint("fix debugport!!!!!!\n");
        Pass_DebugPort();
        Pass_KiAttachProcess();
        DbgPrint("Pass_DebugPort()!!!\n");
      }
 
    }
 
  }
  __except(1)
  {
    DbgPrint("CitydOnTimer error!\n");
  }
 
 
 
 
 
 
}
 
//////////////////////////////////////////////////////////////////////////
 
 
ULONG ObOpenObjectByPointerAdd;
void __declspec(naked) my_function_detour_NtOpenProcess()
{
  __asm
  {   
    push    eax
    push    dword ptr [ebp-38h]
    push    dword ptr [ebp-24h]
    mov    eax,ObOpenObjectByPointerAdd
    call  eax
 
    _emit 0xEA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0x08
    _emit 0x00
  }
}
//////////////////////////////////////////////////////////////////////////
 
 
ULONG GetFunctionAddr( IN PCWSTR FunctionName)
{
  UNICODE_STRING UniCodeFunctionName;
  RtlInitUnicodeString( &UniCodeFunctionName, FunctionName );
 
  return (ULONG)MmGetSystemRoutineAddress( &UniCodeFunctionName );  
 
}
 
char OpenProcess_g_oricode[8];
 
char* OpenProcess_non_paged_memory;
ULONG OpenProcess_g_KiInsertQueueApc;
 
ULONG Pass_NtOpenProcess()

 
  unsigned long detour_address;
  unsigned long reentry_address;
  KIRQL oldIrql;
  int i = 0;
  char* actual_function;
  unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
  //////////////////////////////////////////////////////////////////////////获得ObOpenObjectByPointer的地址
 
 
  ObOpenObjectByPointerAdd=GetFunctionAddr( L"ObOpenObjectByPointer");
 
  //////////////////////////////////////////////////////////////////////////修改跳转地址
 
 
 
  OpenProcess_g_KiInsertQueueApc=GetFunctionAddr(L"NtOpenProcess");
 
  actual_function = (char *)(OpenProcess_g_KiInsertQueueApc+0x21d);
 
  reentry_address = ((unsigned long)OpenProcess_g_KiInsertQueueApc) + 0x229;
 
  OpenProcess_non_paged_memory =(char*) ExAllocatePool(NonPagedPool, 256);
 
  for(i=0;i<256;i++)
  {
    ((unsigned char *)OpenProcess_non_paged_memory)[i] = ((unsigned char *)my_function_detour_NtOpenProcess)[i];
  }
 
  detour_address = (unsigned long)OpenProcess_non_paged_memory;
 
  *( (unsigned long *)(&newcode[1]) ) = detour_address;
 
  for(i=0;i<200;i++)
  {
    if( (0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i]) &&
      (0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+1]) &&
      (0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+2]) &&
      (0xAA == ((unsigned char *)OpenProcess_non_paged_memory)[i+3]))
    {
      *( (unsigned long *)(&OpenProcess_non_paged_memory[i]) ) = reentry_address;
      break;
    }
  }
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  for(i=0;i < 7;i++)
  {
    OpenProcess_g_oricode[i] = actual_function[i];
    actual_function[i] = newcode[i];
  }
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
 
}
 
VOID UnDetour_NtOpenProcess()
{
  char *actual_function = (char *)(OpenProcess_g_KiInsertQueueApc+0x21d);
  KIRQL oldIrql;
  int i = 0;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  for(i=0;i < 7;i++)
  {
    actual_function[i] = OpenProcess_g_oricode[i];
  }
  KeLowerIrql(oldIrql);
  WPON();
  ExFreePool(OpenProcess_non_paged_memory);
 
}
//////////////////////////////////////////////////////////////////////////
void __declspec(naked) my_function_detour_NtOpenThread()
{
  __asm
  {   
    push    eax
    push    dword ptr [ebp-34h]
    push    dword ptr [ebp-20h]
    mov    eax,ObOpenObjectByPointerAdd
    call  eax
 
    _emit 0xEA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0xAA
    _emit 0x08
    _emit 0x00
  }
}
 
//////////////////////////////////////////////////////////////////////////
 
char OpenThread_g_oricode[8];
 
char* OpenThread_non_paged_memory;
ULONG OpenThread_g_KiInsertQueueApc;
 
 
ULONG Pass_NtOpenThread()

  char *actual_function;
  unsigned long detour_address;
  unsigned long reentry_address;
  KIRQL oldIrql;
  int i = 0;
  unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
 
  //////////////////////////////////////////////////////////////////////////获得ObOpenObjectByPointer的地址
 
 
  ObOpenObjectByPointerAdd=GetFunctionAddr( L"ObOpenObjectByPointer");
 
  //////////////////////////////////////////////////////////////////////////修改跳转地址
 
 
 
  OpenThread_g_KiInsertQueueApc=GetFunctionAddr(L"NtOpenThread");
 
  actual_function = (char *)(OpenThread_g_KiInsertQueueApc+0x213);
 
  reentry_address = ((unsigned long)OpenThread_g_KiInsertQueueApc) + 0x21f;
 
  OpenThread_non_paged_memory =(char*) ExAllocatePool(NonPagedPool, 256);
 
  for(i=0;i<256;i++)
  {
    ((unsigned char *)OpenThread_non_paged_memory)[i] = ((unsigned char *)my_function_detour_NtOpenThread)[i];
  }
 
  detour_address = (unsigned long)OpenThread_non_paged_memory;
 
  *( (unsigned long *)(&newcode[1]) ) = detour_address;
 
  for(i=0;i<200;i++)
  {
    if( (0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i]) &&
      (0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+1]) &&
      (0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+2]) &&
      (0xAA == ((unsigned char *)OpenThread_non_paged_memory)[i+3]))
    {
      *( (unsigned long *)(&OpenThread_non_paged_memory[i]) ) = reentry_address;
      break;
    }
  }
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  for(i=0;i < 7;i++)
  {
    OpenThread_g_oricode[i] = actual_function[i];
    actual_function[i] = newcode[i];
  }
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
 
}
 
VOID UnDetour_NtOpenThread()
{
  char *actual_function = (char *)(OpenThread_g_KiInsertQueueApc+0x213);
  KIRQL oldIrql;
  int i = 0;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  for(i=0;i < 7;i++)
  {
    actual_function[i] = OpenThread_g_oricode[i];
  }
  KeLowerIrql(oldIrql);
  WPON();
  ExFreePool(OpenThread_non_paged_memory);
 
 
}
//////////////////////////////////////////////////////////////////////////
 
 
//////////////////////////////////////////////////////////////////////////
 
 
unsigned long FindKey(unsigned char* Base,unsigned long Offset,unsigned char* Code, unsigned long SizeCode)
{
  unsigned long i;
 
  for (i=0;i<SizeCode;i++)
  {
    if (Base[i+Offset]==Code[i])
    {
      continue;
    }
    else
    {
      return 0;
    }
  }
 
  return 1;
 
}
 
VOID   FakeThread(IN PVOID pContext)
{
  LARGE_INTEGER  liTime = RtlConvertLongToLargeInteger(-(LONG)200000* 10000);
  while(1)
  {
    DbgPrint("[FakeThread] In Wanmei FakeThread\n");
    KeDelayExecutionThread(KernelMode,TRUE,&liTime);
 
  }
}
//NTSTATUS  PsLookupThreadByThreadId(    IN HANDLE ThreadId,    OUT PETHREAD *Thread    );
 
 
unsigned long  pPsCreateSystemThread = 0;
 
ULONG  __stdcall  CheckWanmeiCreateSystemThread(OUT PHANDLE ThreadHandle,
                          IN  ULONG        DesiredAccess,
                          IN  POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,
                          IN  HANDLE        ProcessHandle OPTIONAL,
                          OUT PCLIENT_ID      ClientId OPTIONAL,
                          IN  PKSTART_ROUTINE    StartRoutine,
                          IN  PVOID        StartContext)
{
  char str[256];
 
  ULONG  ulBase  =  (ULONG)StartRoutine;
  UCHAR  cThreadCode1[] = {0xe9,0xbd,0xb8,0x04,0x00,0xac,0xc0,0x28,0x73,0xde};
  UCHAR  cThreadCode2[] = {0xe9,0x75,0x62,0x04,0x00,0x10,0x39,0xd0,0xb5,0x48};
 
 
  if(FindKey((unsigned char *)ulBase, 0x0, cThreadCode1, sizeof(cThreadCode1)))
  {
 
    sprintf(str,"CheckWanmeiCreateThread : find cThreadCode1  StartRoutine %08x\n",(unsigned long)StartRoutine);
    DbgPrint(str);
    return 1;
  }
 
  if(FindKey((unsigned char *)ulBase, 0x0, cThreadCode2, sizeof(cThreadCode2)))
  {
    sprintf(str,"CheckWanmeiCreateThread : find cThreadCode2  StartRoutine %08x\n",(unsigned long)StartRoutine);
    DbgPrint(str);
 
    return 2;
  }
 
  return 0;
}
 
 
__declspec(naked)  MyPsCreateSystemThread( OUT PHANDLE ThreadHandle,
                      IN ULONG DesiredAccess,
                      IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
                      IN HANDLE ProcessHandle OPTIONAL,
                      OUT PCLIENT_ID ClientId OPTIONAL,
                      IN PKSTART_ROUTINE StartRoutine,
                      IN PVOID StartContext)
{
  __asm
  {       
    mov    edi,edi
      push   ebp
      mov    ebp, esp
      mov eax,    pPsCreateSystemThread
      add eax,5
      jmp eax
 
  }
}
 
PETHREAD pethread1=0;
PETHREAD pethread2=0;
 
 
 
NTSTATUS
_PsCreateSystemThread( OUT PHANDLE ThreadHandle,
            IN ULONG DesiredAccess,
            IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
            IN HANDLE ProcessHandle OPTIONAL,
            OUT PCLIENT_ID ClientId OPTIONAL,
            IN PKSTART_ROUTINE StartRoutine,
            IN PVOID StartContext)
{
 
  NTSTATUS nstatus;
  CLIENT_ID clientid;
  switch (CheckWanmeiCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext))
  {
  case 0:
    return MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext);
    break;
  case 1:
    nstatus=MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,&clientid,FakeThread/*StartRoutine*/,StartContext);
    PsLookupThreadByThreadId(clientid.UniqueThread,&pethread1);
    DbgPrint("pethread1 %08x \n",pethread1);
    return nstatus;
    break;
  case 2:
    nstatus=MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,&clientid,FakeThread/*StartRoutine*/,StartContext);
    PsLookupThreadByThreadId(clientid.UniqueThread,&pethread2);
    DbgPrint("pethread2 %08x \n",pethread2);
    return nstatus;
 
    break;
 
  }
 
  return MyPsCreateSystemThread(ThreadHandle,DesiredAccess,ObjectAttributes,ProcessHandle,ClientId,StartRoutine,StartContext);
 
}
 
 
unsigned char g_oldcode[8]={0};
 
unsigned long Pass_PsCreateSystemThread()
{
  KIRQL  oldIrql;
  unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
 
  pPsCreateSystemThread=GetFunctionAddr(L"PsCreateSystemThread");
  memcpy(g_oldcode,(PVOID)pPsCreateSystemThread,5);
 
  *( (unsigned long *)(&newcode[1]) ) = (ULONG)_PsCreateSystemThread-pPsCreateSystemThread-5;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  memcpy((PVOID)pPsCreateSystemThread,newcode,5);
  KeLowerIrql(oldIrql);
  WPON();
 
 
  return STATUS_SUCCESS;
 
}
 
VOID UnDetour_PsCreateSystemThread()
{
 
  KIRQL  oldIrql;
  //  unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
 
  pPsCreateSystemThread=GetFunctionAddr(L"PsCreateSystemThread");
  //  memcpy(g_oldcode,(PVOID)pPsCreateSystemThread,5);
 
  //  *( (unsigned long *)(&newcode[1]) ) = (ULONG)MyPsCreateSystemThread-pPsCreateSystemThread-5;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  memcpy((PVOID)pPsCreateSystemThread,g_oldcode,5);
  KeLowerIrql(oldIrql);
  WPON();
 
 
}
 
 
//////////////////////////////////////////////////////////////////////////