八月的樱花 发表于 2012-10-18 20:34:03

游戏保护大放送之HP驱动,新版。



#include "struct.h"
#include "FGPK.h"

//////////////////////////////////////////////////////////////////////////

char g_pFindOrigCode;
ULONG KiSystemService_hack_address=0;
PULONGpSSDTKernel,pSSWDTKernel;
PSERVICE_DESCRIPTOR_TABLE_SHADOW _KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE_SHADOWShadowTable;
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 ObjectNameInformation1

#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;
} _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(" DriverEntry\n");

pDriverObj->MajorFunction = DispatchCreate;
pDriverObj->MajorFunction = DispatchClose;
pDriverObj->MajorFunction = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;


RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj,
      0,
      &ustrDevName,
      FILE_DEVICE_UNKNOWN,
      0,
      FALSE,
      &pDevObj);

if(!NT_SUCCESS(status)){
    dprintf(" IoCreateDevice = 0x%x\n", status);
    return status;
}

RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status)) {
    dprintf(" 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(" Unloaded\n");
}


NTSTATUS
DispatchCreate(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;

dprintf(" 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(" 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(" 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   

SSDT:

    pushad
    call    IsGame
    cmp    eax,1
    popad
    je      ZTGAME2

    mov    edi,KeServiceDescriptorTable
    add    edi,0x20

ZTGAME2:
    jmp   


}

}

UCHAR findcode[]={0x83,0xf9,0x10,0x75};

VOID FindHackAddr()
{
    ULONGuSysenter;
    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==strSysenter &&
      findcode==strSysenter &&
      findcode==strSysenter &&
      findcode==strSysenter )
    {
      break;
    }

}

KiSystemService_hack_address=uSysenter+i;

}
ULONG HookSysCall()
{
KIRQLoldIrql;


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) ) = (ULONG)my_function_detour_KiFastCallEntry-KiSystemService_hack_address-5;


WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 5;i++)
{
    g_pFindOrigCode = actual_function;
    actual_function = newcode;
}
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;
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.ObjectTypeNumber == 21) //Port object
    {
      InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);

      cid.UniqueProcess = (HANDLE)Handles->Information.ProcessId;
      cid.UniqueThread = 0;

      if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
      {
      if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information.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.ProcessId;
            }
          }

          ZwClose(hObject);
      }

      ZwClose(Process);
      }
    }
}

ExFreePool(Handles);
return CsrId;
}

unsigned long AddMyServiceTable()
{
ULONGnSDTKerCallLen,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("AddMyServiceTablealloc 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);
KIRQLoldIrql;
WPOFF();

KeRaiseIrql( DISPATCH_LEVEL,&oldIrql );

for(i=0;i < 5;i++)
{
    actual_function = g_pFindOrigCode;
}

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_optPOBJECT_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_INFORMATIONpobj_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_INFORMATIONpobj_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;
ULONGAddress=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;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 163 * 4;

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();

*((ULONG*)Address) = (ULONG)OrgNtQueryObject;//HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}

八月的樱花 发表于 2012-10-18 20:35:33



//////////////////////////////////////////////////////////////////////////
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;
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;
ULONGAddress=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;
ULONGAddress=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;
PVOID Reserved2;
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;
ULONGAddress=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;
ULONGAddress=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 charoldcode[]={0x8b,0xff,0x55,0x8b,0xec,0x83,0xec,0x10};
unsigned char* obcheckobjectaccessptr=(unsigned char*)GetFunctionAddr(L"ObCheckObjectAccess");

ULONGAddress=(ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 257 * 4;
unsigned char* ntterminateprocessptr=(unsigned char*)(*(ULONG*)Address);


if (obcheckobjectaccessptr==0x68)
{
   
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
    RtlCopyMemory(obcheckobjectaccessptr,oldcode,8);
    KeLowerIrql(oldIrql);
    WPON();

}
if (ntterminateprocessptr==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;
ULONGAddress=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;
ULONGAddress=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                BaseAddress,
                OUT PVOID               Buffer,
                IN ULONG                NumberOfBytesToRead,
                OUT PULONG            NumberOfBytesReaded OPTIONAL
                )
{

NTSTATUS    status;
PEPROCESS   pEProcess=0;
char*       proname=0;




if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
{
    return HookedNtReadVirtualMemoryAdd(ProcessHandle,BaseAddress,Buffer,NumberOfBytesToRead,NumberOfBytesReaded);

    if (!ProcessHandle)
    {
      return 0;

    }

    status = ObReferenceObjectByHandle(ProcessHandle,PROCESS_ALL_ACCESS,NULL,0,&pEProcess,NULL);

    if(!NT_SUCCESS(status))
    {
      dprintf("ObReferenceObjectByHandle fail! %08x \n",status);
      return 0;

    }
    ObDereferenceObject(pEProcess);
    proname=GetProcessNameFromEProc(pEProcess);
    if (PsGetCurrentProcessId()!=PsGetProcessId(pEProcess))
    {
      if (!strcmp("DragonNest.exe",proname) || !strcmp("MDL.exe",proname))
      {
      return STATUS_ACCESS_DENIED;
      }
    }

}
return OldNtReadVirtualMemoryAdd(ProcessHandle,BaseAddress,Buffer,NumberOfBytesToRead,NumberOfBytesReaded);

}



//////////////////////////////////////////////////////////////////////////NtReadVirtualMemory



ULONG Pass_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4;    //得到NtReadVirtualMemory的服务地址

(ULONG)OldNtReadVirtualMemoryAdd = *(ULONG*)Address;    //保存此地址


WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtReadVirtualMemory;//HOOK SSDT

KeLowerIrql(oldIrql);
WPON();
return 1;
}

//反补丁,用于最后恢复用
VOID UnDetour_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4;

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();

*((ULONG*)Address) = (ULONG)OldNtReadVirtualMemoryAdd;//HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////

typedef NTSTATUS (*NTWRITEVIRTUALMEMORY)(

         IN HANDLE               ProcessHandle,
         IN PVOID                BaseAddress,
         IN PVOID                Buffer,
         IN ULONG                NumberOfBytesToWrite,
         OUT PULONG            NumberOfBytesWritten OPTIONAL );

NTWRITEVIRTUALMEMORY OldNtWriteVirtualMemoryAdd;
NTWRITEVIRTUALMEMORY HookedNtWriteVirtualMemoryAdd;


NTSTATUS
NTAPI
NewNtWriteVirtualMemory(

         IN HANDLE               ProcessHandle,
         IN PVOID                BaseAddress,
         IN PVOID                Buffer,
         IN ULONG                NumberOfBytesToWrite,
         OUT PULONG            NumberOfBytesWritten OPTIONAL )
{

if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
{
    return HookedNtWriteVirtualMemoryAdd(ProcessHandle,BaseAddress,Buffer,NumberOfBytesToWrite,NumberOfBytesWritten);
}

return OldNtWriteVirtualMemoryAdd(ProcessHandle,BaseAddress,Buffer,NumberOfBytesToWrite,NumberOfBytesWritten);

}

ULONG Pass_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 277 * 4;   

(ULONG)OldNtWriteVirtualMemoryAdd = *(ULONG*)Address;    //保存此地址


WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtWriteVirtualMemory;//HOOK SSDT

KeLowerIrql(oldIrql);
WPON();
return 1;
}

//反补丁,用于最后恢复用
VOID UnDetour_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 277 * 4;

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();

*((ULONG*)Address) = (ULONG)OldNtWriteVirtualMemoryAdd;//HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}

//////////////////////////////////////////////////////////////////////////

typedef NTSTATUS (*NTCREATESEMAPHORE)(
          OUT PHANDLE             SemaphoreHandle,
          IN ACCESS_MASK          DesiredAccess,
          IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
          IN ULONG                InitialCount,
          IN ULONG                MaximumCount );

NTCREATESEMAPHORE OrgNtCreateSemaphore;

ULONG semhandle=0;

NTSTATUS __stdcall MyNtCreateSemaphore(
                     OUT PHANDLE             SemaphoreHandle,
                     IN ACCESS_MASK          DesiredAccess,
                     IN POBJECT_ATTRIBUTES   ObjectAttributes OPTIONAL,
                     IN ULONG                InitialCount,
                     IN ULONG                MaximumCount
                     )
{
PUNICODE_STRING p_mutex_name;
UNICODE_STRING uni_count={0};


HANDLE tmphand;
NTSTATUS nTstatus;
__try
{
    if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
    {
      if(ObjectAttributes==NULL)
      return OrgNtCreateSemaphore(SemaphoreHandle,DesiredAccess,ObjectAttributes,InitialCount,MaximumCount);

      p_mutex_name=ObjectAttributes->ObjectName;

      if(p_mutex_name)
      {
      if (p_mutex_name->Buffer)
      {
          //dprintf("Semaphore %S\n",p_mutex_name->Buffer);
          //dnx_57987675368241

          if (wcsstr(p_mutex_name->Buffer,L"dnx_57987675368241"))
          {      
            /*         
            nTstatus=OrgNtCreateSemaphore(SemaphoreHandle,DesiredAccess,ObjectAttributes,InitialCount,MaximumCount);
            dprintf("Semaphore %S\n",p_mutex_name->Buffer);
            dprintf("OrgNtCreateSemaphore nTstatus %08x\n",nTstatus);
            //    semhandle=(ULONG)*SemaphoreHandle;
            //    dprintf("DragonNest pid %d MyNtCreateSemaphore dnx_57987675368241 handle %08x\n",PsGetCurrentProcessId(),semhandle);
            return nTstatus;
            */      

            
            while(1)
            {
            nTstatus=OrgNtCreateSemaphore(SemaphoreHandle,DesiredAccess,ObjectAttributes,InitialCount,MaximumCount);
            if (nTstatus==STATUS_OBJECT_NAME_EXISTS)
            {
                dprintf("STATUS_OBJECT_NAME_EXISTS\n");
                if (SemaphoreHandle)
                {
                  dprintf("SemaphoreHandle %08x\n",*(ULONG*)SemaphoreHandle);
                  tmphand=*(HANDLE*)SemaphoreHandle;
                  if (tmphand)
                  {
                  ZwClose(tmphand);
                  }
                }
               
                g_Sem_count++;
                if(g_Sem_count==20)g_Sem_count=0;
                uni_count.Buffer=(PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
                uni_count.MaximumLength=BUFFER_SIZE;
                nTstatus=RtlIntegerToUnicodeString(g_Sem_count,10,&uni_count);
                  if (NT_SUCCESS(nTstatus))
                  {
                  p_mutex_name->MaximumLength=0x100;
                  RtlAppendUnicodeStringToString(p_mutex_name,&uni_count);
                  }
                  else
                  {
                  dprintf("RtlIntegerToUnicodeString error!\n");
                  }
                  RtlFreeUnicodeString(&uni_count);

            //RtlInitUnicodeString(&uni_count,wzCount);
            }
            else
            {
                dprintf("CreateSemaphore sucess! Semaphore name %S\n",p_mutex_name->Buffer);
                return nTstatus;
            }

            }
            //MaximumCount=10;
            //dprintf("DragonNest CreateSemaphore MaximumCount :%d InitialCount :%d\n",MaximumCount,InitialCount);
            //dprintf("fack mutex!\n");
            //return STATUS_SUCCESS;
          }
      }

      }
    }
}
__except(1)
{
    dprintf("MyNtCreateSemaphore error\n");
}
return OrgNtCreateSemaphore(SemaphoreHandle,DesiredAccess,ObjectAttributes,InitialCount,MaximumCount);
}

ULONG Pass_NtCreateSemaphore()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 51 * 4;   

(ULONG)OrgNtCreateSemaphore = *(ULONG*)Address;    //保存此地址

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtCreateSemaphore;      //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}

//反补丁,用于最后恢复用
VOID UnDetour_NtCreateSemaphore()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 51 * 4;

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();

*((ULONG*)Address) = (ULONG)OrgNtCreateSemaphore;//HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////

typedef NTSTATUS (*NTRELEASESEMAPHORE)(

         IN HANDLE               SemaphoreHandle,
         IN ULONG                ReleaseCount,
         OUT PULONG            PreviousCount OPTIONAL );

NTRELEASESEMAPHORE OrgNtReleaseSemaphore;

NTSTATUS __stdcall MyNtReleaseSemaphore(
                  IN HANDLE               SemaphoreHandle,
                  IN ULONG                ReleaseCount,
                  OUT PULONG            PreviousCount OPTIONAL
                  )
{
UNICODE_STRING semaphorename;
__try
{
    if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
    {

      if (semhandle==(ULONG)SemaphoreHandle)
      {
      dprintf("DragonNest pid %d ReleaseSemaphore handle %08x\n",PsGetCurrentProcessId(),SemaphoreHandle);
      }
      
/*
      if (!GetObjectNameFromHandle(SemaphoreHandle,&semaphorename))
      {
      if (!wcscmp(semaphorename.Buffer,L"dnx_57987675368241"))
      {
          dprintf("DragonNest pid %d ReleaseSemaphore name %wZ\n",PsGetCurrentProcessId(),&semaphorename);
      }
      
      }
      */
    }
}
__except(1)
{
    dprintf("MyNtReleaseSemaphore error!\n");
}
return OrgNtReleaseSemaphore(SemaphoreHandle,ReleaseCount,PreviousCount);
}

ULONG Pass_NtReleaseSemaphore()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 189 * 4;   

(ULONG)OrgNtReleaseSemaphore = *(ULONG*)Address;    //保存此地址

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtReleaseSemaphore;      //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}

//反补丁,用于最后恢复用
VOID UnDetour_NtReleaseSemaphore()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 189 * 4;

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();

*((ULONG*)Address) = (ULONG)OrgNtReleaseSemaphore;//HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////


typedefNTSTATUS (*NTOPENSEMAPHORE)(

      OUT PHANDLE             SemaphoreHandle,
      IN ACCESS_MASK          DesiredAccess,
      IN POBJECT_ATTRIBUTES   ObjectAttributes );

NTOPENSEMAPHORE OrgNtOpenSemaphore;

NTSTATUS __stdcall MyNtOpenSemaphore(
                   OUT PHANDLE             SemaphoreHandle,
                   IN ACCESS_MASK          DesiredAccess,
                   IN POBJECT_ATTRIBUTES   ObjectAttributes )
{
PUNICODE_STRING p_mutex_name;
__try
{
    if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
    {
//    dprintf("DragonNest pid %d OpenSemaphore\n",PsGetCurrentProcessId());

      p_mutex_name=ObjectAttributes->ObjectName;

      if(p_mutex_name)
      {
      if (p_mutex_name->Buffer)
      {
          if (wcsstr(p_mutex_name->Buffer,L"dnx_57987675368241"))
          {
            dprintf("DragonNest PID %d NtOpenSemaphore name %S\n",PsGetCurrentProcessId(),p_mutex_name->Buffer);
          }
      }
      }

      
    }
}
__except(1)
{
    dprintf("MyNtOpenSemaphore error!\n");
}
return OrgNtOpenSemaphore(SemaphoreHandle,DesiredAccess,ObjectAttributes);
}

ULONG Pass_NtOpenSemaphore()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 126 * 4;   

(ULONG)OrgNtOpenSemaphore = *(ULONG*)Address;    //保存此地址

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtOpenSemaphore;      //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}

//反补丁,用于最后恢复用
VOID UnDetour_NtOpenSemaphore()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 126 * 4;

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();

*((ULONG*)Address) = (ULONG)OrgNtOpenSemaphore;//HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////



typedef NTSTATUS (*NTWAITFORSINGLEOBJECT)(

            IN HANDLE               ObjectHandle,
            IN BOOLEAN            Alertable,
            IN PLARGE_INTEGER       TimeOut );

NTWAITFORSINGLEOBJECT OrgNtWaitForSingleObject;

NTSTATUS __stdcall MyNtWaitForSingleObject(
IN HANDLE               ObjectHandle,
IN BOOLEAN            Alertable,
IN PLARGE_INTEGER       TimeOut )
{
UNICODE_STRING Objectname;
__try
{
    if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
    {
      if (semhandle==(ULONG)ObjectHandle)
      {
      dprintf("DragonNest pid %d MyNtWaitForSingleObject name %wZ TimeOut %d\n",PsGetCurrentProcessId(),&Objectname,TimeOut);
      }
      /*
      if (!GetObjectNameFromHandle(ObjectHandle,&Objectname))
      {
      if (!wcscmp(Objectname.Buffer,L"dnx_57987675368241"))
      {
          dprintf("DragonNest pid %d MyNtWaitForSingleObject name %wZ TimeOut %d\n",PsGetCurrentProcessId(),&Objectname,TimeOut);
      }
      
      }
      */
    }
}
__except(1)
{
    dprintf("MyNtOpenSemaphore error!\n");
}
return OrgNtWaitForSingleObject(ObjectHandle,Alertable,TimeOut);
}

ULONG Pass_NtWaitForSingleObject()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 271 * 4;   

(ULONG)OrgNtWaitForSingleObject = *(ULONG*)Address;    //保存此地址

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtWaitForSingleObject;      //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}

//反补丁,用于最后恢复用
VOID UnDetour_NtWaitForSingleObject()
{
KIRQL oldIrql;
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 271 * 4;

WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();

*((ULONG*)Address) = (ULONG)OrgNtWaitForSingleObject;//HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}


//////////////////////////////////////////////////////////////////////////



//////////////////////////////////////////////////////////////////////////


typedef UINT_PTR (*NTUSERQUERYWINDOW)(
                  IN ULONG WindowHandle,
                  IN ULONG TypeInformation);

NTUSERQUERYWINDOW OldNtUserQueryWindow;


NTSTATUS FindNtUserQueryWindow()
{
NTSTATUS status=0;

KeAttachProcess(crsEProc);

__try
{
    if (KeServiceDescriptorTableShadow!=NULL)
    {
      OldNtUserQueryWindow = (NTUSERQUERYWINDOW)KeServiceDescriptorTableShadow.ServiceTableBase;

    }
}
__finally
{
    KeDetachProcess();
}


return status ;


}


//////////////////////////////////////////////////////////////////////////

unsigned int getAddressOfShadowTable()
{
unsigned int i;
unsigned char *p;
unsigned int dwordatbyte;

p = (unsigned char*) KeAddSystemServiceTable;

for(i = 0; i < 4096; i++, p++)
{
    __try
    {
      dwordatbyte = *(unsigned int*)p;
    }
    __except(EXCEPTION_EXECUTE_HANDLER)
    {
      return 0;
    }

    if(MmIsAddressValid((PVOID)dwordatbyte))
    {
      if(memcmp((PVOID)dwordatbyte, &KeServiceDescriptorTable, 16) == 0)
      {
      if((PVOID)dwordatbyte == &KeServiceDescriptorTable)
      {
          continue;
      }

      return dwordatbyte;
      }
    }
}

return 0;
}

ULONG getShadowTable()
{
KeServiceDescriptorTableShadow = (PSERVICE_DESCRIPTOR_TABLE) getAddressOfShadowTable();

if(KeServiceDescriptorTableShadow == NULL)
{
    dprintf("hooker.sys: Couldnt find shadowtable!\n");

    return FALSE;
}
else
{
    dprintf("hooker.sys: Shadowtable has been found!\n");

    dprintf("hooker.sys: Shadowtable entries: %d\n", KeServiceDescriptorTableShadow.NumberOfServices);
    return TRUE;
}
}





//6A 30       PUSH 0x30
//68 70D898BF    PUSH 0xBF98D870

unsigned long reentry_ntuserfinwind;
UCHAR g_oldcode_ntuserfindwind;

__declspec(naked) NTSTATUS _NtUserFindWindowEx(
HANDLE hwndParent,
HANDLE hwndChild,
PUNICODE_STRING pstrClassName ,
PUNICODE_STRING pstrWindowName ,
DWORD dwType)

{

__asm
{
    push 0x30
    push 0xBF98D870
    jmp
}

}

NTSTATUS InitSWSSDT()
{
NTSTATUS status;
getShadowTable();




status = PsLookupProcessByProcessId((HANDLE)GetCsrPid(), &crsEProc);
if (!NT_SUCCESS( status ))
{
    dprintf("PsLookupProcessByProcessId() error\n");

}
FindNtUserQueryWindow();
return status;
}
char* GetProcessName( ULONG nProcessId)
{
NTSTATUS rStutus;

PEPROCESS       curproc;

rStutus=PsLookupProcessByProcessId((HANDLE)nProcessId,&curproc);
if (!rStutus)
{
    ObDereferenceObject(curproc);
    return GetProcessNameFromEProc(curproc);
}
return 0;

}

NTSTATUS MyNtUserFindWindowEx(
                IN HANDLE hwndParent,
                IN HANDLE hwndChild,
                IN PUNICODE_STRING pstrClassName OPTIONAL,
                IN PUNICODE_STRING pstrWindowName OPTIONAL,
                IN DWORD dwType)
{
ULONG result;
UNICODE_STRING CLASSNAME;
//UNICODE_STRING FIXCLASSNAME;
ULONG FindProcessID;
char* szFindProcessName;
ULONG ProcessID;

result = _NtUserFindWindowEx(hwndParent, hwndChild, pstrClassName, pstrWindowName, dwType);

if (!_stricmp("DragonNest.exe",GetProcessNameFromEProc(0)))
{
   
    ProcessID = OldNtUserQueryWindow(result, 0);
   
    if (ProcessID!=(ULONG)PsGetCurrentProcessId())   
    {

      if (pstrClassName!=0)
      {
      RtlInitUnicodeString(&CLASSNAME,L"DRAGONNEST");
      if (!RtlCompareUnicodeString(pstrClassName,&CLASSNAME,FALSE))
      {

          return 0;

      }
      }
      if (pstrWindowName!=0)
      {
      RtlInitUnicodeString(&CLASSNAME,L"龙之谷");
      if (!RtlCompareUnicodeString(pstrWindowName,&CLASSNAME,FALSE))
      {

          return 0;

      }
      RtlInitUnicodeString(&CLASSNAME,L"DML");
      if (!RtlCompareUnicodeString(pstrWindowName,&CLASSNAME,FALSE))
      {

          return 0;

      }
      }

    }
   
}


return result;
}





typedef NTSTATUS (*NTUSERFINDWINDOWEX)(
                     HANDLE hwndParent,
                     HANDLE hwndChild,
                     PUNICODE_STRING pstrClassName ,
                     PUNICODE_STRING pstrWindowName ,
                     DWORD dwType);


NTUSERFINDWINDOWEX          g_OriginalNtUserFindWindowEx;




NTSTATUS HookFindWindow()
{
NTSTATUS status=0;

unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11,0x90,0x90};


KeAttachProcess(crsEProc);

__try
{
    if (KeServiceDescriptorTableShadow!=NULL)
    {
      g_OriginalNtUserFindWindowEx   = (NTUSERFINDWINDOWEX)KeServiceDescriptorTableShadow.ServiceTableBase;
      memcpy(g_oldcode_ntuserfindwind,(UCHAR*)g_OriginalNtUserFindWindowEx,7);
      reentry_ntuserfinwind=(unsigned long)g_OriginalNtUserFindWindowEx+7;
      *( (unsigned long *)(&newcode) ) = (unsigned long)MyNtUserFindWindowEx-(unsigned long)g_OriginalNtUserFindWindowEx-5;

    }
    else
      KeServiceDescriptorTableShadow=NULL;


    WPOFF();
    if (KeServiceDescriptorTableShadow!=NULL )
    {

      memcpy((UCHAR*)g_OriginalNtUserFindWindowEx,newcode,7);
    }

    WPON();
}
__finally
{
    KeDetachProcess();
}



return status ;
}

NTSTATUS UnHookFindWindow()
{
NTSTATUS status;

KeAttachProcess(crsEProc);

__try
{
    WPOFF();

    if (KeServiceDescriptorTableShadow!=NULL)
    {
      memcpy((UCHAR*)g_OriginalNtUserFindWindowEx,g_oldcode_ntuserfindwind,7);

    }

    WPON();
}
__finally
{
    KeDetachProcess();
    Sleep(50);
}
return 0;
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


//////////////////////////////////////////////////////////////////////////



ULONG          OldNtUserPostMessage;


NTSTATUS __declspec(naked) MyNtUserPostMessage()
{
__asm
{
    push ebp
    movebp,esp
    pushesi
    mov   eax,OldNtUserPostMessage
    add   eax,6
    jmp   eax
}

}

NTSTATUS HookNtUserPostMessage()
{

KIRQL oldIrql;
ULONGAddress=0;

__try
{
    KeAttachProcess(crsEProc);

    Address = (ULONG)ShadowTable->NotUse2.ServiceTableBase + 475 * 4;   
    (ULONG)OldNtUserPostMessage = *(ULONG*)Address;   

    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
    *((ULONG*)Address) = (ULONG)MyNtUserPostMessage;//HOOK SSDT
    KeLowerIrql(oldIrql);
    WPON();
   
}
__finally
{
    KeDetachProcess();
}
return 0 ;
}

NTSTATUS UnHookNtUserPostMessage()
{
KIRQL oldIrql;
ULONGAddress=0;

__try
{
    KeAttachProcess(crsEProc);

    Address = (ULONG)ShadowTable->NotUse2.ServiceTableBase +475 * 4;
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();

    *((ULONG*)Address) = (ULONG)OldNtUserPostMessage;//HOOK SSDT
    KeLowerIrql(oldIrql);
    WPON();

}
__finally
{
    KeDetachProcess();
}

return 0;
}


//////////////////////////////////////////////////////////////////////////




ULONG          OldNtUserMessageCall;


NTSTATUS __declspec(naked) MyNtUserMessageCall()
{
__asm
{
    push ebp
    movebp,esp
    subesp,0xc
    mov   eax,OldNtUserMessageCall
    add   eax,8
    jmp   eax
}

}

NTSTATUS HookNtUserMessageCall()
{

KIRQL oldIrql;
ULONGAddress=0;

__try
{
    KeAttachProcess(crsEProc);

    Address = (ULONG)ShadowTable->NotUse2.ServiceTableBase + 460 * 4;   
    (ULONG)OldNtUserMessageCall = *(ULONG*)Address;   

    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
    *((ULONG*)Address) = (ULONG)MyNtUserMessageCall;//HOOK SSDT
    KeLowerIrql(oldIrql);
    WPON();

}
__finally
{
    KeDetachProcess();
}


return 0 ;
}

NTSTATUS UnHookNtUserMessageCall()
{
KIRQL oldIrql;
ULONGAddress=0;

__try
{
    KeAttachProcess(crsEProc);

    Address = (ULONG)ShadowTable->NotUse2.ServiceTableBase +460 * 4;
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();

    *((ULONG*)Address) = (ULONG)OldNtUserMessageCall;//HOOK SSDT
    KeLowerIrql(oldIrql);
    WPON();

}
__finally
{
    KeDetachProcess();
}


return 0;
}

//////////////////////////////////////////////////////////////////////////

typedef struct tagKEYBDINPUT {
SHORT wVk;
SHORT wScan;
ULONG dwFlags;
ULONG time;
ULONG_PTR dwExtraInfo;
} KEYBDINPUT, *PKEYBDINPUT;

typedef struct tagMOUSEINPUT {
LONG dx;
LONG dy;
ULONG mouseData;
ULONG dwFlags;
ULONG time;
ULONG_PTR dwExtraInfo;
} MOUSEINPUT, *PMOUSEINPUT;

typedef struct tagHARDWAREINPUT {
ULONG uMsg;
SHORT wParamL;
SHORT wParamH;
} HARDWAREINPUT, *PHARDWAREINPUT;

typedef struct tagINPUT {
ULONG type;
union {MOUSEINPUT mi;
KEYBDINPUT ki;
HARDWAREINPUT hi;
};
}INPUT, *PINPUT;

typedef ULONG (NTAPI*NTUSERSENDINPUT)(ULONG,PINPUT,int);




NTUSERSENDINPUT          OldNtUserSendInput;
//ULONG OldNtUserSendInputree;


NTSTATUS __declspec(naked) _NtUserSendInput(IN ULONG nInputs,IN PINPUT pInputs,IN int cbSize)
{
__asm
{
    push 0x18
    push 0xbf98f050
    moveax,OldNtUserSendInput
    addeax,7
    jmp   eax
}

}

ULONG NTAPI MyNtUserSendInput(IN ULONG nInputs,IN PINPUT pInputs,IN int cbSize)
{
if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
{
    dprintf("DragonNest NtUserSendInput\n");
   
}

return OldNtUserSendInput(nInputs,pInputs,cbSize);

//return _NtUserSendInput(nInputs,pInputs,cbSize);

}


NTSTATUS HookNtUserSendInput()
{

KIRQL oldIrql;
ULONGAddress=0;

__try
{
    KeAttachProcess(crsEProc);

    Address = (ULONG)ShadowTable->NotUse2.ServiceTableBase + 502 * 4;   
    (ULONG)OldNtUserSendInput = *(ULONG*)Address;   

//    OldNtUserSendInputree=OldNtUserSendInput+7;

    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();
    *((ULONG*)Address) = (ULONG)_NtUserSendInput;//HOOK SSDT
    KeLowerIrql(oldIrql);
    WPON();

}
__finally
{
    KeDetachProcess();
}

return 0 ;
}

NTSTATUS UnHookNtUserSendInput()
{
KIRQL oldIrql;
ULONGAddress=0;

__try
{
    KeAttachProcess(crsEProc);

    Address = (ULONG)ShadowTable->NotUse2.ServiceTableBase +502 * 4;
    WPOFF();
    oldIrql = KeRaiseIrqlToDpcLevel();

    *((ULONG*)Address) = (ULONG)OldNtUserSendInput;//HOOK SSDT
    KeLowerIrql(oldIrql);
    WPON();

}
__finally
{
    KeDetachProcess();
}

return 0;
}

//////////////////////////////////////////////////////////////////////////

NTSTATUS GetHookedFunAdd()
{
ULONGAddress=0;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase +0x7A * 4;

(ULONG)HookedNtOpenProcess = *(ULONG*)Address;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase +0xBA * 4;

(ULONG)HookedNtReadVirtualMemoryAdd = *(ULONG*)Address;

Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase +277 * 4;

(ULONG)HookedNtWriteVirtualMemoryAdd = *(ULONG*)Address;

return 0;
}

网瘾犯了 发表于 2012-10-19 22:03:29

先收藏先谢谢LZ

xiaozu 发表于 2012-10-19 23:10:58

求成品 不会C++
页: [1]
查看完整版本: 游戏保护大放送之HP驱动,新版。