当前位置: 移动技术网 > 网络运营>安全>加解密 > 游戏保护大放送之TP

游戏保护大放送之TP

2018年02月08日  | 移动技术网网络运营  | 我要评论
本人寻求游戏安全方面的工作,请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();
 
 
}
 
 
//////////////////////////////////////////////////////////////////////////

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网