游戏保护大放送之GPK
程序员文章站
2022-07-05 23:24:28
作 者: wtxpwh
GPK也没有啥特别。龙之谷多开检测和别的不一样。
直接上代码。
代码:
&nbs...
作 者: wtxpwh
GPK也没有啥特别。龙之谷多开检测和别的不一样。
直接上代码。
代码:
#include "struct.h"
#include "FGPK.h"
//////////////////////////////////////////////////////////////////////////
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address=0;
PULONG pSSDTKernel;
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_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 InitSWSSDT();
//////////////////////////////////////////////////////////////////////////
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();
HookFindWindow();
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();
UnHookFindWindow();
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");
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;
}
//////////////////////////////////////////////////////////////////////////
void __declspec(naked) my_function_detour_KiFastCallEntry()
{
__asm
{
cmp ecx,10h
jne SSDT
mov edi,KeServiceDescriptorTable
sub edi,0x10
jmp [SSDTDW_reentry_address]
SSDT:
mov edi,KeServiceDescriptorTable
add edi,0x20
jmp [SSDT_reentry_address]
}
}
UCHAR findcode[]={0x83,0xf9,0x10,0x75};
VOID FindHackAddr()
{
ULONG uSysenter;
ULONG i=0;
PUCHAR strSysenter;
__asm{
mov ecx,0x176
rdmsr
mov uSysenter,eax //得到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;
}
unsigned long AddMyServiceTable()
{
ULONG nSDTKerCallLen;
__asm
{
pushad
mov eax,KeServiceDescriptorTable
mov _KeServiceDescriptorTable,eax
sub eax,0x40
mov ShadowTable,eax
popad
}
nSDTKerCallLen = _KeServiceDescriptorTable->ntoskrnl.NumberOfServices;
pSSDTKernel = (PULONG)ExAllocatePool( NonPagedPool, nSDTKerCallLen*sizeof(ULONG) );
if(!pSSDTKernel)
{
dprintf("AddMyServiceTable alloc fail\n");
return 0;
}
memset( (PVOID)pSSDTKernel, 0, nSDTKerCallLen*sizeof(ULONG));
//填充新的SSDT表
//
RtlCopyMemory( (PVOID)pSSDTKernel,(PVOID)_KeServiceDescriptorTable->ntoskrnl.ServiceTableBase,nSDTKerCallLen*sizeof(ULONG) );
RtlCopyMemory( (PVOID)&_KeServiceDescriptorTable->NotUse1,
(PVOID)&_KeServiceDescriptorTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE) );
RtlCopyMemory( (PVOID)&ShadowTable->NotUse1,(PVOID)&ShadowTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE)*2);
WPOFF();
RtlCopyMemory((PVOID)&_KeServiceDescriptorTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
RtlCopyMemory((PVOID)&ShadowTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
WPON();
return 1;
}
void RePlaceSSDT()
{
if (AddMyServiceTable())
{
HookSysCall();
}
}
void RestoreSSDT()
{
int i;
char *actual_function = (char *)(KiSystemService_hack_address);
KIRQL oldIrql;
WPOFF();
KeRaiseIrql( DISPATCH_LEVEL,&oldIrql );
for(i=0;i < 5;i++)
{
actual_function[i] = g_pFindOrigCode[i];
}
KeLowerIrql( oldIrql );
ExFreePool(pSSDTKernel);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
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;
RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\dnx_57987675368241");
if (pobj_name->Name.Buffer)
{
if (wcsstr(pobj_name->Name.Buffer,L"\\BaseNamedObjects\\dnx_57987675368241"))
{
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
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;
OBJECT_ATTRIBUTES tmpobjatus;
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;
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"))
{
dprintf("fack mutex!\n");
return STATUS_SUCCESS;
__try
{
RtlInitUnicodeString(&tmpunicodestring,L"Global\\MutexDragonNest");
RtlZeroMemory(wzCount,3*sizeof(WCHAR));
wzCount[0]=(WCHAR)(0x30+g_Dra_count);
g_Dra_count++;
if(g_Dra_count==20) g_Dra_count=0;
RtlInitUnicodeString(&uni_count,wzCount);
// dprintf("uni_count %wZ\n",&uni_count);
// p_mutex_name->MaximumLength=0x100;
RtlAppendUnicodeStringToString(&tmpunicodestring,&uni_count);
dprintf("tmpunicodestring %wZ\n",&tmpunicodestring);
InitializeObjectAttributes(&tmpobjatus,&tmpunicodestring,ObjectAttributes->Attributes,ObjectAttributes->RootDirectory,ObjectAttributes->SecurityDescriptor);
//dprintf("mutex %S\n",p_mutex_name->Buffer);
return OrgZwCreateMutant(MutantHandle,DesiredAccess,&tmpobjatus,InitialOwner);
}
__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();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////NtOpenProcess
ULONG OldNtProcessAdd;
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};
PEPROCESS tempeprocess;
if (!strcmp("DragonNest.exe",GetProcessNameFromEProc(0)) || !strcmp("dnlauncher.exe",GetProcessNameFromEProc(0)))
{
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();
}
}
return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
}
ULONG Pass_NtOpenProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
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) = 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;
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("DragonNest.exe",GetProcessNameFromEProc(0)))
{
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;
ULONG Address=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;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNtReadVirtualMemoryAdd; //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};
// WCHAR wzCount[3];
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 (!wcscmp(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");
// RtlZeroMemory(wzCount,3*sizeof(WCHAR));
// wzCount[0]=(WCHAR)(0x30+g_Sem_count);
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");
}
// 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;
ULONG Address=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;
ULONG Address=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;
ULONG Address=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;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 189 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OrgNtReleaseSemaphore; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*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 (!wcscmp(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;
ULONG Address=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;
ULONG Address=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&n
GPK也没有啥特别。龙之谷多开检测和别的不一样。
直接上代码。
代码:
#include "struct.h"
#include "FGPK.h"
//////////////////////////////////////////////////////////////////////////
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address=0;
PULONG pSSDTKernel;
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_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 InitSWSSDT();
//////////////////////////////////////////////////////////////////////////
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();
HookFindWindow();
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();
UnHookFindWindow();
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");
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;
}
//////////////////////////////////////////////////////////////////////////
void __declspec(naked) my_function_detour_KiFastCallEntry()
{
__asm
{
cmp ecx,10h
jne SSDT
mov edi,KeServiceDescriptorTable
sub edi,0x10
jmp [SSDTDW_reentry_address]
SSDT:
mov edi,KeServiceDescriptorTable
add edi,0x20
jmp [SSDT_reentry_address]
}
}
UCHAR findcode[]={0x83,0xf9,0x10,0x75};
VOID FindHackAddr()
{
ULONG uSysenter;
ULONG i=0;
PUCHAR strSysenter;
__asm{
mov ecx,0x176
rdmsr
mov uSysenter,eax //得到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;
}
unsigned long AddMyServiceTable()
{
ULONG nSDTKerCallLen;
__asm
{
pushad
mov eax,KeServiceDescriptorTable
mov _KeServiceDescriptorTable,eax
sub eax,0x40
mov ShadowTable,eax
popad
}
nSDTKerCallLen = _KeServiceDescriptorTable->ntoskrnl.NumberOfServices;
pSSDTKernel = (PULONG)ExAllocatePool( NonPagedPool, nSDTKerCallLen*sizeof(ULONG) );
if(!pSSDTKernel)
{
dprintf("AddMyServiceTable alloc fail\n");
return 0;
}
memset( (PVOID)pSSDTKernel, 0, nSDTKerCallLen*sizeof(ULONG));
//填充新的SSDT表
//
RtlCopyMemory( (PVOID)pSSDTKernel,(PVOID)_KeServiceDescriptorTable->ntoskrnl.ServiceTableBase,nSDTKerCallLen*sizeof(ULONG) );
RtlCopyMemory( (PVOID)&_KeServiceDescriptorTable->NotUse1,
(PVOID)&_KeServiceDescriptorTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE) );
RtlCopyMemory( (PVOID)&ShadowTable->NotUse1,(PVOID)&ShadowTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE)*2);
WPOFF();
RtlCopyMemory((PVOID)&_KeServiceDescriptorTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
RtlCopyMemory((PVOID)&ShadowTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
WPON();
return 1;
}
void RePlaceSSDT()
{
if (AddMyServiceTable())
{
HookSysCall();
}
}
void RestoreSSDT()
{
int i;
char *actual_function = (char *)(KiSystemService_hack_address);
KIRQL oldIrql;
WPOFF();
KeRaiseIrql( DISPATCH_LEVEL,&oldIrql );
for(i=0;i < 5;i++)
{
actual_function[i] = g_pFindOrigCode[i];
}
KeLowerIrql( oldIrql );
ExFreePool(pSSDTKernel);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
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;
RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\dnx_57987675368241");
if (pobj_name->Name.Buffer)
{
if (wcsstr(pobj_name->Name.Buffer,L"\\BaseNamedObjects\\dnx_57987675368241"))
{
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
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;
OBJECT_ATTRIBUTES tmpobjatus;
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;
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"))
{
dprintf("fack mutex!\n");
return STATUS_SUCCESS;
__try
{
RtlInitUnicodeString(&tmpunicodestring,L"Global\\MutexDragonNest");
RtlZeroMemory(wzCount,3*sizeof(WCHAR));
wzCount[0]=(WCHAR)(0x30+g_Dra_count);
g_Dra_count++;
if(g_Dra_count==20) g_Dra_count=0;
RtlInitUnicodeString(&uni_count,wzCount);
// dprintf("uni_count %wZ\n",&uni_count);
// p_mutex_name->MaximumLength=0x100;
RtlAppendUnicodeStringToString(&tmpunicodestring,&uni_count);
dprintf("tmpunicodestring %wZ\n",&tmpunicodestring);
InitializeObjectAttributes(&tmpobjatus,&tmpunicodestring,ObjectAttributes->Attributes,ObjectAttributes->RootDirectory,ObjectAttributes->SecurityDescriptor);
//dprintf("mutex %S\n",p_mutex_name->Buffer);
return OrgZwCreateMutant(MutantHandle,DesiredAccess,&tmpobjatus,InitialOwner);
}
__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();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////NtOpenProcess
ULONG OldNtProcessAdd;
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};
PEPROCESS tempeprocess;
if (!strcmp("DragonNest.exe",GetProcessNameFromEProc(0)) || !strcmp("dnlauncher.exe",GetProcessNameFromEProc(0)))
{
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();
}
}
return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
}
ULONG Pass_NtOpenProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
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) = 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;
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("DragonNest.exe",GetProcessNameFromEProc(0)))
{
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;
ULONG Address=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;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNtReadVirtualMemoryAdd; //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};
// WCHAR wzCount[3];
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 (!wcscmp(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");
// RtlZeroMemory(wzCount,3*sizeof(WCHAR));
// wzCount[0]=(WCHAR)(0x30+g_Sem_count);
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");
}
// 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;
ULONG Address=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;
ULONG Address=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;
ULONG Address=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;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 189 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OrgNtReleaseSemaphore; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*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 (!wcscmp(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;
ULONG Address=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;
ULONG Address=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&n
上一篇: C++:自制Lex 词法分析器生成器
下一篇: jsp中实现倒计时的代码教程