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

游戏保护大放送之HP

2018年04月19日  | 移动技术网网络运营  | 我要评论
作 者: wtxpwh 本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系 做挂者请绕道!

 

 
本人不保证此办法现在还生效!蓝屏死机于本人无关!
 
征途2的保护多了objecthook。
 
上代码!
 
代码:
 
 
#include "struct.h"
#include "FGPK.h"
 
//////////////////////////////////////////////////////////////////////////
 
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address=0;
PULONG  pSSDTKernel,pSSWDTKernel;
PSERVICE_DESCRIPTOR_TABLE_SHADOW _KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE_SHADOW  ShadowTable;
unsigned long SSDT_reentry_address,SSDTDW_reentry_address;
 
 
ULONG g_Dra_count=0;
ULONG g_Sem_count=0;
 
//////////////////////////////////////////////////////////////////////////
void RePlaceSSDT();
void RestoreSSDT();
 
ULONG Pass_NtCreateMutant();
VOID UnDetour_NtCreateMutant();
 
ULONG Pass_NtQuerySystemInformation();
VOID UnDetour_NtQuerySystemInformation();
 
ULONG Pass_NtOpenProcess();
VOID UnDetour_NtOpenProcess();
 
NTSTATUS HookFindWindow();
NTSTATUS UnHookFindWindow();
 
ULONG Pass_NtReadVirtualMemory();
VOID UnDetour_NtReadVirtualMemory();
 
ULONG Pass_NtWriteVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
 
ULONG Pass_NtCreateSemaphore();
VOID UnDetour_NtCreateSemaphore();
 
 
ULONG Pass_NtReleaseSemaphore();
VOID UnDetour_NtReleaseSemaphore();
 
ULONG Pass_NtOpenSemaphore();
VOID UnDetour_NtOpenSemaphore();
 
ULONG Pass_NtQueryObject();
VOID UnDetour_NtQueryObject();
 
 
ULONG Pass_NtWaitForSingleObject();
VOID UnDetour_NtWaitForSingleObject();
 
NTSTATUS HookNtUserPostMessage();
NTSTATUS UnHookNtUserPostMessage();
 
NTSTATUS HookNtUserSendInput();
NTSTATUS UnHookNtUserSendInput();
 
NTSTATUS HookNtUserMessageCall();
NTSTATUS UnHookNtUserMessageCall();
 
 
 
NTSTATUS InitSWSSDT();
 
ULONG IsHooked=0;
 
ULONG HookSysCall();
NTSTATUS GetHookedFunAdd();
 
 
 
//////////////////////////////////////////////////////////////////////////
 
 
PEPROCESS crsEProc;
 
PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTableShadow;
 
__declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);
 
 
#define ObjectNameInformation  1
 
#define SystemHandleInformation 0x10
 
typedef struct _SYSTEM_HANDLE_INFORMATION {
  ULONG ProcessId;
  UCHAR ObjectTypeNumber;
  UCHAR Flags;
  USHORT Handle;
  PVOID Object;
  ACCESS_MASK GrantedAccess;
} _SYSTEM_HANDLE_INFORMATION, *P_SYSTEM_HANDLE_INFORMATION;
 
 
typedef struct _SYSTEM_HANDLE_INformATION_EX {
  ULONG NumberOfHandles;
  _SYSTEM_HANDLE_INFORMATION Information[1];
} _SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
 
//////////////////////////////////////////////////////////////////////////
 
NTSTATUS
DriverEntry(
  PDRIVER_OBJECT pDriverObj,
  PUNICODE_STRING pRegistryString
  )
{
  NTSTATUS status = STATUS_SUCCESS;
  UNICODE_STRING ustrLinkName;
  UNICODE_STRING ustrDevName;   
  PDEVICE_OBJECT pDevObj;
 
  dprintf("[FGPK] 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("[FGPK] IoCreateDevice = 0x%x\n", status);
    return status;
  }
 
  RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
  status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName); 
  if(!NT_SUCCESS(status)) {
    dprintf("[FGPK] IoCreateSymbolicLink = 0x%x\n", status);
    IoDeleteDevice(pDevObj); 
    return status;
  }
 
 
  //
  // 添加执行代码
  //
 
  RePlaceSSDT();
 
  InitSWSSDT();
 
//  Pass_NtQueryObject();
 
//  Pass_NtCreateMutant();
 
//  Pass_NtCreateSemaphore();
 
//  Pass_NtReleaseSemaphore();
 
//  Pass_NtOpenSemaphore();
 
//  Pass_NtWaitForSingleObject();
 
//  Pass_NtQuerySystemInformation();
 
  Pass_NtOpenProcess();
 
//  Pass_NtReadVirtualMemory();
 
//  Pass_NtWriteVirtualMemory();
 
//  HookFindWindow();
 
//  HookNtUserMessageCall();
 
//  HookNtUserSendInput();
 
//  HookNtUserPostMessage();
 
  return STATUS_SUCCESS;
}
 
 
VOID
DriverUnload(
  PDRIVER_OBJECT pDriverObj
  )

  UNICODE_STRING strLink;
  RtlInitUnicodeString(&strLink, LINK_NAME);
 
  //
  // 添加卸载代码
  //
 
 
 
//  UnDetour_NtOpenSemaphore();
 
//  UnDetour_NtWaitForSingleObject();
 
//  UnDetour_NtCreateSemaphore();
 
//  UnDetour_NtReleaseSemaphore();
 
//  UnDetour_NtCreateMutant();
 
//  UnDetour_NtQueryObject();
 
//  UnDetour_NtQuerySystemInformation();
 
  UnDetour_NtOpenProcess();
 
//  UnDetour_NtReadVirtualMemory();
 
//  UnDetour_NtWriteVirtualMemory();
 
//  UnHookFindWindow();
 
//  UnHookNtUserPostMessage();
 
//  UnHookNtUserSendInput();
 
//  UnHookNtUserMessageCall();
 
 
  RestoreSSDT();
 
 
//  Sleep(5000);
 
  IoDeleteSymbolicLink(&strLink);
  IoDeleteDevice(pDriverObj->DeviceObject);
  dprintf("[FGPK] Unloaded\n");
}
 
 
NTSTATUS
DispatchCreate(
  PDEVICE_OBJECT pDevObj,
  PIRP pIrp
  )
{
  pIrp->IoStatus.Status = STATUS_SUCCESS;
  pIrp->IoStatus.Information = 0;
 
  dprintf("[FGPK] 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("[FGPK] 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("[FGPK] Hello\n");
 
      GetHookedFunAdd();
 
      HookSysCall();
 
      IsHooked=1;
      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;
}
//////////////////////////////////////////////////////////////////////////
 
NTSTATUS IsGame()
{
  if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
  {
    return 1;
  }
  return 0;
}
 
//////////////////////////////////////////////////////////////////////////
 
 
 
void __declspec(naked) my_function_detour_KiFastCallEntry()
{
  __asm
  {
    cmp     ecx,10h
    jne    SSDT
 
    pushad
    call    IsGame
    cmp    eax,1
    popad
    je      ZTGAME1
 
    mov    edi,KeServiceDescriptorTable
    sub    edi,0x10
 
ZTGAME1:
    jmp    [SSDTDW_reentry_address]
 
SSDT:
 
    pushad
    call    IsGame
    cmp    eax,1
    popad
    je      ZTGAME2
 
    mov    edi,KeServiceDescriptorTable
    add    edi,0x20
 
ZTGAME2:
    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  //得到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;
 
 
  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;
  }
 
  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;
}
 
 
PVOID GetInfoTable(ULONG ATableType)
{
  ULONG mSize = 0x4000;
  PVOID mPtr = NULL;
  NTSTATUS St;
  do
  {
    mPtr = ExAllocatePool(PagedPool, mSize);
    memset(mPtr, 0, mSize);
    if (mPtr)
    {
      St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL);
    } else return NULL;
    if (St == STATUS_INFO_LENGTH_MISMATCH)
    {
      ExFreePool(mPtr);
      mSize = mSize * 2;
    }
  } while (St == STATUS_INFO_LENGTH_MISMATCH);
  if (St == STATUS_SUCCESS) return mPtr;
  ExFreePool(mPtr);
  return NULL;
}
 
HANDLE GetCsrPid()
{
  HANDLE Process, hObject;
  HANDLE CsrId = (HANDLE)0;
  OBJECT_ATTRIBUTES obj;
  CLIENT_ID cid;
  UCHAR Buff[0x100];
  POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
  PSYSTEM_HANDLE_INFORMATION_EX Handles;
  ULONG r;
 
  Handles = GetInfoTable(SystemHandleInformation);
 
  if (!Handles) return CsrId;
 
  for (r = 0; r < Handles->NumberOfHandles; r++)
  {
    if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
    {
      InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
 
      cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
      cid.UniqueThread = 0;
 
      if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
      {
        if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
        {
          if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
          {
            if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
            {
              CsrId = (HANDLE)Handles->Information[r].ProcessId;
            }
          }
 
          ZwClose(hObject);
        }
 
        ZwClose(Process);
      }
    }
  }
 
  ExFreePool(Handles);
  return CsrId;
}
 
unsigned long AddMyServiceTable()
{
  ULONG  nSDTKerCallLen,nSWDTKerCallLen;
  NTSTATUS status;
  PEPROCESS crsEProc;
 
 
  __asm
  {
    pushad
      mov   eax,KeServiceDescriptorTable
      mov   _KeServiceDescriptorTable,eax
      sub   eax,0x40
      mov   ShadowTable,eax
      popad
  }
  nSDTKerCallLen  =  _KeServiceDescriptorTable->ntoskrnl.NumberOfServices;
  nSWDTKerCallLen  =  ShadowTable->win32k.NumberOfServices;
 
 
  pSSDTKernel =  (PULONG)ExAllocatePool( NonPagedPool, nSDTKerCallLen*sizeof(ULONG));
  pSSWDTKernel=   (PULONG)ExAllocatePool( NonPagedPool, nSWDTKerCallLen*sizeof(ULONG));
 
 
  if(!pSSDTKernel || !pSSWDTKernel)
  {
    DbgPrint("AddMyServiceTable  alloc fail\n");
    return 0;
  }
  memset( (PVOID)pSSDTKernel, 0, nSDTKerCallLen*sizeof(ULONG));
  memset( (PVOID)pSSWDTKernel, 0, nSWDTKerCallLen*sizeof(ULONG));
 
 
  //填充新的SSDT表
  //
  RtlCopyMemory( (PVOID)pSSDTKernel,(PVOID)_KeServiceDescriptorTable->ntoskrnl.ServiceTableBase,nSDTKerCallLen*sizeof(ULONG) );
 
 
  RtlCopyMemory( (PVOID)&_KeServiceDescriptorTable->NotUse1,(PVOID)&_KeServiceDescriptorTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE) );
  //sswdt
 
  status = PsLookupProcessByProcessId((HANDLE)GetCsrPid(), &crsEProc);
  if (!NT_SUCCESS( status ))
  {
    DbgPrint("PsLookupProcessByProcessId() error\n");
    return status;
  }
  KeAttachProcess(crsEProc);
 
  __try
  {
    RtlCopyMemory( (PVOID)pSSWDTKernel,(PVOID)ShadowTable->win32k.ServiceTableBase,nSWDTKerCallLen*sizeof(ULONG) );
 
  }
  __finally
  {
    KeDetachProcess();
  }
 
  RtlCopyMemory( (PVOID)&ShadowTable->NotUse1,(PVOID)&ShadowTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE));
  RtlCopyMemory( (PVOID)&ShadowTable->NotUse2,(PVOID)&ShadowTable->win32k,sizeof(SERVICE_DESCRIPTOR_TABLE));
 
  WPOFF();
  RtlCopyMemory((PVOID)&_KeServiceDescriptorTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
 
  RtlCopyMemory((PVOID)&ShadowTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
  RtlCopyMemory((PVOID)&ShadowTable->NotUse2.ServiceTableBase, &pSSWDTKernel, sizeof(ULONG));
 
  WPON();
 
  return 1;
}
 
void RePlaceSSDT()
{
  if (AddMyServiceTable())
  {
    HookSysCall();
  }
 
}
 
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);
  ExFreePool(pSSWDTKernel);
 
 
  WPON();
 
}
 
//////////////////////////////////////////////////////////////////////////
 
 
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTQUERYOBJECT)
(
 IN HANDLE ObjectHandle,
 IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
 OUT PVOID ObjectInformation,
 IN ULONG ObjectInformationLength,
 OUT PULONG ReturnLength OPTIONAL
 );
NTQUERYOBJECT OrgNtQueryObject;
 
//*****************************************************************************************************************
NTSYSAPI
NTSTATUS
NTAPI
ObQueryNameString(
               __in       PVOID Object,
               __out_opt  POBJECT_NAME_INFORMATION ObjectNameInfo,
               __in       ULONG Length,
               __out      PULONG ReturnLength
               );
 
 
NTSTATUS GetObjectNameFromHandle(HANDLE Objecthandle,PUNICODE_STRING filename)
{
//   PFILE_OBJECT      pFileObject;
//   OBJECT_HANDLE_INFORMATION HandleInformationObject;
  NTSTATUS nTstatus;
  POBJECT_NAME_INFORMATION pObjectInformation;
  PVOID Object;
  OBJECT_HANDLE_INFORMATION HandleInformation = {0};
  ULONG TempReturnLength;
 
 
  pObjectInformation=ExAllocatePool(PagedPool,0x100);
  RtlZeroMemory(pObjectInformation,0x100);
 
  __try
  {
    nTstatus = ObReferenceObjectByHandle( Objecthandle,
      0,
      NULL,
      0,
      &Object,
      &HandleInformation );
 
    if (NT_SUCCESS( nTstatus ))
    {
      nTstatus = ObQueryNameString( Object,
        (POBJECT_NAME_INFORMATION)pObjectInformation,
        0x100,
        &TempReturnLength
         );
 
      RtlCopyUnicodeString(filename,(PUNICODE_STRING)&(pObjectInformation->Name));
      return 0;
    }
   
     
   
   
  }
  __except(1)
  {
    dprintf("GetObjectNameFromHandle error!\n");
  }
 
  return -1;
 
}
//********************************************************************************************************************
 
NTSTATUS __stdcall MyNtQueryObject(
                   HANDLE ObjectHandle,
                   OBJECT_INFORMATION_CLASS ObjectInformationClass,
                   PVOID ObjectInformation,
                   ULONG ObjectInformationLength,
                   PULONG ReturnLength)
{
  NTSTATUS nTstatus;
 
  UNICODE_STRING Objectname;
  UNICODE_STRING oldname;
 
  __try
  {
    if(strcmp(GetProcessNameFromEProc(0),"DragonNest.exe")==0)
    {
      //DragonNest pid 3548 ObjectNameInformation MyNtQueryObject name \BaseNamedObjects\dnx_579876753682410 handle 00000614
 
      nTstatus=OrgNtQueryObject(ObjectHandle,ObjectInformationClass,ObjectInformation,ObjectInformationLength,ReturnLength);
      switch (ObjectInformationClass)
      {
      case ObjectNameInformation:
        if(ObjectInformation!=NULL)
        {
 
          POBJECT_NAME_INFORMATION  pobj_name=(POBJECT_NAME_INFORMATION)ObjectInformation;
         
          if (pobj_name->Name.Buffer)
          {
            if (wcsstr(pobj_name->Name.Buffer,L"dnx_57987675368241"))
            {
              dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
              RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\dnx_57987675368241");
              RtlCopyUnicodeString(&(pobj_name->Name),&oldname);
              dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
            }
           
            else if (wcsstr(pobj_name->Name.Buffer,L"MutexDragonNest"))
            {
              dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
            //  RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\MutexDragonNest");
            //  RtlCopyUnicodeString(&(pobj_name->Name),&oldname);
              dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
 
            }
           
          }
        }
        break;
      case ObjectBasicInformation:
        if(ObjectInformation!=NULL)
        {
          POBJECT_BASIC_INFORMATION  pobj_basic=(POBJECT_BASIC_INFORMATION)ObjectInformation;
          dprintf("DragonNest pid %d ObjectBasicInformation HandleCount %d handle %08x\n",PsGetCurrentProcessId(),pobj_basic->HandleCount,(ULONG)ObjectHandle);
        }
        break;
 
      }
 
    }
 
  }
  __except(1)
  {
    dprintf("MyNtQueryObject error!\n");
  }
 
 
  return nTstatus;
}
 
ULONG Pass_NtQueryObject()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 163 * 4;   
 
  (ULONG)OrgNtQueryObject = *(ULONG*)Address;    //保存此地址
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  *((ULONG*)Address) = (ULONG)MyNtQueryObject;      //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
  return 1;
}
 
//反补丁,用于最后恢复用
VOID UnDetour_NtQueryObject()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 163 * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)OrgNtQueryObject;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
}
 
 
 
 
 
 
//////////////////////////////////////////////////////////////////////////
typedef NTSYSAPI NTSTATUS (__stdcall *ZWCREATEMUTANT)(
  OUT PHANDLE             MutantHandle,
  IN ACCESS_MASK          DesiredAccess,
  IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
  IN BOOLEAN              InitialOwner );
 
ZWCREATEMUTANT OrgZwCreateMutant;
 
ULONG g_mutex_count=0;
NTSTATUS __stdcall MyZwCreateMutant(
                  OUT PHANDLE             MutantHandle,
                  IN ACCESS_MASK          DesiredAccess,
                  IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
                  IN BOOLEAN              InitialOwner )
{
  PUNICODE_STRING p_mutex_name;
  UNICODE_STRING uni_count;
  WCHAR wzCount[3];
  UNICODE_STRING tmpunicodestring,tmpunicodestring1;
  OBJECT_ATTRIBUTES tmpobjatus;
 
  NTSTATUS nTstatus;
  __try
  {
    if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
    {
      if(ObjectAttributes==NULL)
        return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
 
      p_mutex_name=ObjectAttributes->ObjectName;
 
      if(p_mutex_name  )
      {
        if (p_mutex_name->Buffer)
        {
          //    dprintf("mutex %S\n",p_mutex_name->Buffer);
 
          if (!wcscmp(p_mutex_name->Buffer,L"Global\\MutexDragonNest"))
          {
        //    return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
            dprintf("fack mutex!\n");
            return STATUS_SUCCESS;
        //    DbgBreakPoint();
           
            nTstatus=OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
 
           
            while(1)
            {
              
              if (nTstatus==STATUS_OBJECT_NAME_EXISTS)
              {
                dprintf("STATUS_OBJECT_NAME_EXISTS\n");
 
                g_mutex_count++;
                if(g_mutex_count==20)  g_mutex_count=0;
                dprintf("g_mutex_count %d\n",g_mutex_count);
                uni_count.Buffer=(PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
                uni_count.MaximumLength=BUFFER_SIZE;
                nTstatus=RtlIntegerToUnicodeString(g_mutex_count,10,&uni_count);
 
                if (NT_SUCCESS(nTstatus))
                {
                  dprintf("uni_count %wZ\n",uni_count);
 
                  RtlInitUnicodeString(&tmpunicodestring1,L"Global\\MutexDragonNest");
                  tmpunicodestring.Buffer=(PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
                  tmpunicodestring.MaximumLength=BUFFER_SIZE;
                  //wcscpy(tmpunicodestring.Buffer,L"Global\\MutexDragonNest");
                  RtlCopyUnicodeString(&tmpunicodestring,&tmpunicodestring1);
                  RtlAppendUnicodeStringToString(&tmpunicodestring,&uni_count);
                  DbgPrint("tmpunicodestring %wZ\n",&tmpunicodestring);
                  InitializeObjectAttributes(&tmpobjatus,&tmpunicodestring,ObjectAttributes->Attributes,
                    ObjectAttributes->RootDirectory,ObjectAttributes->SecurityDescriptor);
                  nTstatus=OrgZwCreateMutant(MutantHandle,DesiredAccess,&tmpobjatus,InitialOwner);
                  dprintf("name %wZ\n",tmpobjatus.ObjectName);
                  RtlFreeUnicodeString(&tmpunicodestring);
 
                }
                else
                {
                  dprintf("RtlIntegerToUnicodeString error!\n");
                }
                RtlFreeUnicodeString(&uni_count);
 
                //  RtlInitUnicodeString(&uni_count,wzCount);
              }
              else
              {
                dprintf("CreateMutex sucess! Mutex name %S\n",p_mutex_name->Buffer);
                return nTstatus;
              }
 
            }
 
          }
        }
 
      }
    }
  }
  __except(1)
  {
    dprintf("MyZwCreateMutant error\n");
  }
  return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
}
 
ULONG Pass_NtCreateMutant()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 43 * 4;   
 
  (ULONG)OrgZwCreateMutant = *(ULONG*)Address;    //保存此地址
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  *((ULONG*)Address) = (ULONG)MyZwCreateMutant;      //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
  return 1;
}
 
//反补丁,用于最后恢复用
VOID UnDetour_NtCreateMutant()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 43 * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)OrgZwCreateMutant;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
}
 
 
 
//////////////////////////////////////////////////////////////////////////
 
 
typedef NTSTATUS (*NTQUERYSYSTEMINFORMATION)
(
 ULONG SystemInformationCLass,
 PVOID SystemInformation,
 ULONG SystemInformationLength,
 PULONG ReturnLength
 );
 
NTQUERYSYSTEMINFORMATION OldNtQuerySystemInformation;
 
 
typedef struct _SYSTEM_BASIC_INFORMATION {
  BYTE Reserved1[24];
  PVOID Reserved2[4];
  CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION;
 
 
 
NTSTATUS NewNtQuerySystemInformation(
                   IN ULONG SystemInformationClass,
                   IN PVOID SystemInformation,
                   IN ULONG SystemInformationLength,
                   OUT PULONG ReturnLength)
{
 
  NTSTATUS ntStatus;
  UNICODE_STRING gamename;
  UNICODE_STRING launchername;
 
 
  ntStatus = OldNtQuerySystemInformation(
    SystemInformationClass,
    SystemInformation,
    SystemInformationLength,
    ReturnLength );
 
 
  if (!_stricmp(GetProcessNameFromEProc(0),"DragonNest.exe") || !_stricmp(GetProcessNameFromEProc(0),"dnlauncher.exe"))
  {
 
    if( NT_SUCCESS(ntStatus))
    {
 
 
      if(SystemInformationClass == 5)
      {
 
        struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
        struct _SYSTEM_PROCESSES *prev = NULL;
 
        while(curr)
        {
 
          if (curr->ProcessName.Buffer != NULL)
          {
            //  dprintf("processid %d\n",curr->ProcessId);
 
            RtlInitUnicodeString(&gamename,L"DragonNest.exe");
            RtlInitUnicodeString(&launchername,L"dnlauncher.exe");
           
 
            if((!RtlCompareUnicodeString(&(curr->ProcessName),&gamename,FALSE) && (ULONG)PsGetCurrentProcessId()!=curr->ProcessId) ||
              !RtlCompareUnicodeString(&(curr->ProcessName),&launchername,FALSE))
            {
              //  dprintf("FIND DNF PDI %d\n",curr->ProcessId);
 
              if(prev)
              {
                if(curr->NextEntryDelta)
                {
                  prev->NextEntryDelta += curr->NextEntryDelta;
                }
 
                else
                {
                  prev->NextEntryDelta = 0;
                }
              }
              else
              {
                if(curr->NextEntryDelta)
                {
 
                  (char *)SystemInformation += curr->NextEntryDelta;
                }
                else
                {
                  SystemInformation = NULL;
                }
 
              }
 
 
            }
            else
            {
              prev = curr;
            }
          }
 
          if(curr->NextEntryDelta)
          {
            ((char *)curr += curr->NextEntryDelta);
          }
          else
          {
            curr = NULL;
          }
 
 
        }
      }
 
 
    }
 
  }
 
  return ntStatus;
}
 
ULONG Pass_NtQuerySystemInformation()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 173 * 4;   
 
  (ULONG)OldNtQuerySystemInformation = *(ULONG*)Address;    //保存此地址
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
  *((ULONG*)Address) = (ULONG)NewNtQuerySystemInformation;      //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
  return 1;
}
 
//反补丁,用于最后恢复用
VOID UnDetour_NtQuerySystemInformation()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 173 * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)OldNtQuerySystemInformation;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
}
 
//////////////////////////////////////////////////////////////////////////
/*
805c1148 8bff            mov     edi,edi
805c114a 55              push    ebp
805c114b 8bec            mov     ebp,esp
805c114d 83ec10          sub     esp,10h
*/
 
 
VOID UnHook()
{
  KIRQL oldIrql;
 
  unsigned char  oldcode[]={0x8b,0xff,0x55,0x8b,0xec,0x83,0xec,0x10};
  unsigned char* obcheckobjectaccessptr=(unsigned char*)GetFunctionAddr(L"ObCheckObjectAccess");
 
  ULONG  Address=(ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 257 * 4;
  unsigned char* ntterminateprocessptr=(unsigned char*)(*(ULONG*)Address); 
 
 
  if (obcheckobjectaccessptr[0]==0x68)
  {
   
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
    RtlCopyMemory(obcheckobjectaccessptr,oldcode,8);
    KeLowerIrql(oldIrql);
    WPON();
 
  }
  if (ntterminateprocessptr[0]==0x68)
  {
   
 
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
    RtlCopyMemory(ntterminateprocessptr,oldcode,8);
    KeLowerIrql(oldIrql);
    WPON();
 
  }
 
}
 
//////////////////////////////////////////////////////////////////////////NtOpenProcess
typedef NTSTATUS (*NTOPENPROCESS) (
          __out PHANDLE ProcessHandle,
          __in ACCESS_MASK DesiredAccess,
          __in POBJECT_ATTRIBUTES ObjectAttributes,
          __in_opt PCLIENT_ID ClientId
          );
 
NTOPENPROCESS OldNtProcessAdd;
NTOPENPROCESS HookedNtOpenProcess;
 
extern POBJECT_TYPE PsProcessType;
 
NTSTATUS
NewNtOpenProcess (
        __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;
 
  if (!strcmp("Open.exe",GetProcessNameFromEProc(0)))
  {
    DbgPrint("open.exe openprocess!\n");
  }
 
  if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
  {
  //  return HookedNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
 
    PsLookupProcessByProcessId(ClientId->UniqueProcess,&tempeprocess);
    __try
    {
      if (
        !strcmp("DML.exe",GetProcessNameFromEProc(tempeprocess)) ||
        (!strcmp("DragonNest.exe",GetProcessNameFromEProc(tempeprocess)) && PsGetCurrentProcessId()!=ClientId->UniqueProcess)
        /*!strcmp("DeRoX.exe",GetProcessNameFromEProc(tempeprocess))*/
        )
      {
        return STATUS_ACCESS_DENIED;
      }
 
    }
    __except (EXCEPTION_EXECUTE_HANDLER)
    {
      dprintf("GetExceptionCode %08x\n",GetExceptionCode());
      return GetExceptionCode();
    }
 
   
  }
 
 
//  UnHook();
 
  (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_NtOpenProcess()
{
 
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase +  0x7A * 4;
 
  (ULONG)OldNtProcessAdd = *(ULONG*)Address;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) = (ULONG)NewNtOpenProcess;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
  return 1;
}
 
VOID UnDetour_NtOpenProcess()
{
  KIRQL oldIrql;
  ULONG  Address=0;
 
  Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase +  0x7A * 4;
 
  WPOFF();
  oldIrql = KeRaiseIrqlToDpcLevel();
 
  *((ULONG*)Address) =(ULONG) OldNtProcessAdd;  //HOOK SSDT
  KeLowerIrql(oldIrql);
  WPON();
 
}
 
//////////////////////////////////////////////////////////////////////////
typedef
NTSTATUS
(*NTREADVIRTUALMEMORY)(
          IN HANDLE ProcessHandle,
          IN PVOID BaseAddress,
          OUT PVOID Buffer,
          IN ULONG NumberOfBytesToRead,
          OUT PULONG NumberOfBytesReaded OPTIONAL );
 
NTREADVIRTUALMEMORY OldNtReadVirtualMemoryAdd;
NTREADVIRTUALMEMORY HookedNtReadVirtualMemoryAdd;
 
NTSTATUS NewNtReadVirtualMemory(
                IN HANDLE               ProcessHandle,
                IN PVOID  &

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

相关文章:

验证码:
移动技术网