游戏保护大放送之HP
程序员文章站
2022-03-12 15:55:34
作 者: wtxpwh 本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系 做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无...
作 者: wtxpwh 本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系 做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无关!
征途2的保护多了objecthook。
上代码!
代码:
#include "struct.h"
#include "FGPK.h"
//////////////////////////////////////////////////////////////////////////
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address=0;
PULONG pSSDTKernel,pSSWDTKernel;
PSERVICE_DESCRIPTOR_TABLE_SHADOW _KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE_SHADOW ShadowTable;
unsigned long SSDT_reentry_address,SSDTDW_reentry_address;
ULONG g_Dra_count=0;
ULONG g_Sem_count=0;
//////////////////////////////////////////////////////////////////////////
void RePlaceSSDT();
void RestoreSSDT();
ULONG Pass_NtCreateMutant();
VOID UnDetour_NtCreateMutant();
ULONG Pass_NtQuerySystemInformation();
VOID UnDetour_NtQuerySystemInformation();
ULONG Pass_NtOpenProcess();
VOID UnDetour_NtOpenProcess();
NTSTATUS HookFindWindow();
NTSTATUS UnHookFindWindow();
ULONG Pass_NtReadVirtualMemory();
VOID UnDetour_NtReadVirtualMemory();
ULONG Pass_NtWriteVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
ULONG Pass_NtCreateSemaphore();
VOID UnDetour_NtCreateSemaphore();
ULONG Pass_NtReleaseSemaphore();
VOID UnDetour_NtReleaseSemaphore();
ULONG Pass_NtOpenSemaphore();
VOID UnDetour_NtOpenSemaphore();
ULONG Pass_NtQueryObject();
VOID UnDetour_NtQueryObject();
ULONG Pass_NtWaitForSingleObject();
VOID UnDetour_NtWaitForSingleObject();
NTSTATUS HookNtUserPostMessage();
NTSTATUS UnHookNtUserPostMessage();
NTSTATUS HookNtUserSendInput();
NTSTATUS UnHookNtUserSendInput();
NTSTATUS HookNtUserMessageCall();
NTSTATUS UnHookNtUserMessageCall();
NTSTATUS InitSWSSDT();
ULONG IsHooked=0;
ULONG HookSysCall();
NTSTATUS GetHookedFunAdd();
//////////////////////////////////////////////////////////////////////////
PEPROCESS crsEProc;
PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTableShadow;
__declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);
#define ObjectNameInformation 1
#define SystemHandleInformation 0x10
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} _SYSTEM_HANDLE_INFORMATION, *P_SYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_HANDLE_INformATION_EX {
ULONG NumberOfHandles;
_SYSTEM_HANDLE_INFORMATION Information[1];
} _SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
//////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
PDRIVER_OBJECT pDriverObj,
PUNICODE_STRING pRegistryString
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
dprintf("[FGPK] DriverEntry\n");
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj,
0,
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status)) {
dprintf("[FGPK] IoCreateDevice = 0x%x\n", status);
return status;
}
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status)) {
dprintf("[FGPK] IoCreateSymbolicLink = 0x%x\n", status);
IoDeleteDevice(pDevObj);
return status;
}
//
// 添加执行代码
//
RePlaceSSDT();
InitSWSSDT();
// Pass_NtQueryObject();
// Pass_NtCreateMutant();
// Pass_NtCreateSemaphore();
// Pass_NtReleaseSemaphore();
// Pass_NtOpenSemaphore();
// Pass_NtWaitForSingleObject();
// Pass_NtQuerySystemInformation();
Pass_NtOpenProcess();
// Pass_NtReadVirtualMemory();
// Pass_NtWriteVirtualMemory();
// HookFindWindow();
// HookNtUserMessageCall();
// HookNtUserSendInput();
// HookNtUserPostMessage();
return STATUS_SUCCESS;
}
VOID
DriverUnload(
PDRIVER_OBJECT pDriverObj
)
{
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
//
// 添加卸载代码
//
// UnDetour_NtOpenSemaphore();
// UnDetour_NtWaitForSingleObject();
// UnDetour_NtCreateSemaphore();
// UnDetour_NtReleaseSemaphore();
// UnDetour_NtCreateMutant();
// UnDetour_NtQueryObject();
// UnDetour_NtQuerySystemInformation();
UnDetour_NtOpenProcess();
// UnDetour_NtReadVirtualMemory();
// UnDetour_NtWriteVirtualMemory();
// UnHookFindWindow();
// UnHookNtUserPostMessage();
// UnHookNtUserSendInput();
// UnHookNtUserMessageCall();
RestoreSSDT();
// Sleep(5000);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
dprintf("[FGPK] Unloaded\n");
}
NTSTATUS
DispatchCreate(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[FGPK] IRP_MJ_CREATE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchClose(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[FGPK] IRP_MJ_CLOSE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchIoctl(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode) {
case IOCTL_HELLO: {
dprintf("[FGPK] Hello\n");
GetHookedFunAdd();
HookSysCall();
IsHooked=1;
status = STATUS_SUCCESS;
}
break;
//
// 添加执行代码
//
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
/////////////////////////////////////
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS IsGame()
{
if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
{
return 1;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
void __declspec(naked) my_function_detour_KiFastCallEntry()
{
__asm
{
cmp ecx,10h
jne SSDT
pushad
call IsGame
cmp eax,1
popad
je ZTGAME1
mov edi,KeServiceDescriptorTable
sub edi,0x10
ZTGAME1:
jmp [SSDTDW_reentry_address]
SSDT:
pushad
call IsGame
cmp eax,1
popad
je ZTGAME2
mov edi,KeServiceDescriptorTable
add edi,0x20
ZTGAME2:
jmp [SSDT_reentry_address]
}
}
UCHAR findcode[]={0x83,0xf9,0x10,0x75};
VOID FindHackAddr()
{
ULONG uSysenter;
ULONG i=0;
PUCHAR strSysenter;
__asm{
mov ecx,0x176
rdmsr
mov uSysenter,eax //得到KiFastCallEntry地址
}
strSysenter=(PUCHAR)uSysenter;
for (i=0;i<0x100;i++)
{
if (
findcode[0]==strSysenter[i] &&
findcode[1]==strSysenter[i+1] &&
findcode[2]==strSysenter[i+2] &&
findcode[3]==strSysenter[i+3] )
{
break;
}
}
KiSystemService_hack_address=uSysenter+i;
}
ULONG HookSysCall()
{
KIRQL oldIrql;
unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
char *actual_function;
int i = 0;
FindHackAddr();
if (KiSystemService_hack_address==0)
{
dprintf("find hack address error!\n");
return 0;
}
actual_function =(char*) KiSystemService_hack_address;
SSDT_reentry_address = KiSystemService_hack_address+0x20;
SSDTDW_reentry_address = KiSystemService_hack_address+0x5;
*( (unsigned long *)(&newcode[1]) ) = (ULONG)my_function_detour_KiFastCallEntry-KiSystemService_hack_address-5;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 5;i++)
{
g_pFindOrigCode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
PVOID GetInfoTable(ULONG ATableType)
{
ULONG mSize = 0x4000;
PVOID mPtr = NULL;
NTSTATUS St;
do
{
mPtr = ExAllocatePool(PagedPool, mSize);
memset(mPtr, 0, mSize);
if (mPtr)
{
St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL);
} else return NULL;
if (St == STATUS_INFO_LENGTH_MISMATCH)
{
ExFreePool(mPtr);
mSize = mSize * 2;
}
} while (St == STATUS_INFO_LENGTH_MISMATCH);
if (St == STATUS_SUCCESS) return mPtr;
ExFreePool(mPtr);
return NULL;
}
HANDLE GetCsrPid()
{
HANDLE Process, hObject;
HANDLE CsrId = (HANDLE)0;
OBJECT_ATTRIBUTES obj;
CLIENT_ID cid;
UCHAR Buff[0x100];
POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
PSYSTEM_HANDLE_INFORMATION_EX Handles;
ULONG r;
Handles = GetInfoTable(SystemHandleInformation);
if (!Handles) return CsrId;
for (r = 0; r < Handles->NumberOfHandles; r++)
{
if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
{
InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
cid.UniqueThread = 0;
if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
{
if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
{
if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
{
if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
{
CsrId = (HANDLE)Handles->Information[r].ProcessId;
}
}
ZwClose(hObject);
}
ZwClose(Process);
}
}
}
ExFreePool(Handles);
return CsrId;
}
unsigned long AddMyServiceTable()
{
ULONG nSDTKerCallLen,nSWDTKerCallLen;
NTSTATUS status;
PEPROCESS crsEProc;
__asm
{
pushad
mov eax,KeServiceDescriptorTable
mov _KeServiceDescriptorTable,eax
sub eax,0x40
mov ShadowTable,eax
popad
}
nSDTKerCallLen = _KeServiceDescriptorTable->ntoskrnl.NumberOfServices;
nSWDTKerCallLen = ShadowTable->win32k.NumberOfServices;
pSSDTKernel = (PULONG)ExAllocatePool( NonPagedPool, nSDTKerCallLen*sizeof(ULONG));
pSSWDTKernel= (PULONG)ExAllocatePool( NonPagedPool, nSWDTKerCallLen*sizeof(ULONG));
if(!pSSDTKernel || !pSSWDTKernel)
{
DbgPrint("AddMyServiceTable alloc fail\n");
return 0;
}
memset( (PVOID)pSSDTKernel, 0, nSDTKerCallLen*sizeof(ULONG));
memset( (PVOID)pSSWDTKernel, 0, nSWDTKerCallLen*sizeof(ULONG));
//填充新的SSDT表
//
RtlCopyMemory( (PVOID)pSSDTKernel,(PVOID)_KeServiceDescriptorTable->ntoskrnl.ServiceTableBase,nSDTKerCallLen*sizeof(ULONG) );
RtlCopyMemory( (PVOID)&_KeServiceDescriptorTable->NotUse1,(PVOID)&_KeServiceDescriptorTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE) );
//sswdt
status = PsLookupProcessByProcessId((HANDLE)GetCsrPid(), &crsEProc);
if (!NT_SUCCESS( status ))
{
DbgPrint("PsLookupProcessByProcessId() error\n");
return status;
}
KeAttachProcess(crsEProc);
__try
{
RtlCopyMemory( (PVOID)pSSWDTKernel,(PVOID)ShadowTable->win32k.ServiceTableBase,nSWDTKerCallLen*sizeof(ULONG) );
}
__finally
{
KeDetachProcess();
}
RtlCopyMemory( (PVOID)&ShadowTable->NotUse1,(PVOID)&ShadowTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE));
RtlCopyMemory( (PVOID)&ShadowTable->NotUse2,(PVOID)&ShadowTable->win32k,sizeof(SERVICE_DESCRIPTOR_TABLE));
WPOFF();
RtlCopyMemory((PVOID)&_KeServiceDescriptorTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
RtlCopyMemory((PVOID)&ShadowTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
RtlCopyMemory((PVOID)&ShadowTable->NotUse2.ServiceTableBase, &pSSWDTKernel, sizeof(ULONG));
WPON();
return 1;
}
void RePlaceSSDT()
{
if (AddMyServiceTable())
{
HookSysCall();
}
}
void RestoreSSDT()
{
int i;
char *actual_function = (char *)(KiSystemService_hack_address);
KIRQL oldIrql;
WPOFF();
KeRaiseIrql( DISPATCH_LEVEL,&oldIrql );
for(i=0;i < 5;i++)
{
actual_function[i] = g_pFindOrigCode[i];
}
KeLowerIrql( oldIrql );
ExFreePool(pSSDTKernel);
ExFreePool(pSSWDTKernel);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTQUERYOBJECT)
(
IN HANDLE ObjectHandle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG ObjectInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NTQUERYOBJECT OrgNtQueryObject;
//*****************************************************************************************************************
NTSYSAPI
NTSTATUS
NTAPI
ObQueryNameString(
__in PVOID Object,
__out_opt POBJECT_NAME_INFORMATION ObjectNameInfo,
__in ULONG Length,
__out PULONG ReturnLength
);
NTSTATUS GetObjectNameFromHandle(HANDLE Objecthandle,PUNICODE_STRING filename)
{
// PFILE_OBJECT pFileObject;
// OBJECT_HANDLE_INFORMATION HandleInformationObject;
NTSTATUS nTstatus;
POBJECT_NAME_INFORMATION pObjectInformation;
PVOID Object;
OBJECT_HANDLE_INFORMATION HandleInformation = {0};
ULONG TempReturnLength;
pObjectInformation=ExAllocatePool(PagedPool,0x100);
RtlZeroMemory(pObjectInformation,0x100);
__try
{
nTstatus = ObReferenceObjectByHandle( Objecthandle,
0,
NULL,
0,
&Object,
&HandleInformation );
if (NT_SUCCESS( nTstatus ))
{
nTstatus = ObQueryNameString( Object,
(POBJECT_NAME_INFORMATION)pObjectInformation,
0x100,
&TempReturnLength
);
RtlCopyUnicodeString(filename,(PUNICODE_STRING)&(pObjectInformation->Name));
return 0;
}
}
__except(1)
{
dprintf("GetObjectNameFromHandle error!\n");
}
return -1;
}
//********************************************************************************************************************
NTSTATUS __stdcall MyNtQueryObject(
HANDLE ObjectHandle,
OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength)
{
NTSTATUS nTstatus;
UNICODE_STRING Objectname;
UNICODE_STRING oldname;
__try
{
if(strcmp(GetProcessNameFromEProc(0),"DragonNest.exe")==0)
{
//DragonNest pid 3548 ObjectNameInformation MyNtQueryObject name \BaseNamedObjects\dnx_579876753682410 handle 00000614
nTstatus=OrgNtQueryObject(ObjectHandle,ObjectInformationClass,ObjectInformation,ObjectInformationLength,ReturnLength);
switch (ObjectInformationClass)
{
case ObjectNameInformation:
if(ObjectInformation!=NULL)
{
POBJECT_NAME_INFORMATION pobj_name=(POBJECT_NAME_INFORMATION)ObjectInformation;
if (pobj_name->Name.Buffer)
{
if (wcsstr(pobj_name->Name.Buffer,L"dnx_57987675368241"))
{
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\dnx_57987675368241");
RtlCopyUnicodeString(&(pobj_name->Name),&oldname);
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
}
else if (wcsstr(pobj_name->Name.Buffer,L"MutexDragonNest"))
{
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
// RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\MutexDragonNest");
// RtlCopyUnicodeString(&(pobj_name->Name),&oldname);
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
}
}
}
break;
case ObjectBasicInformation:
if(ObjectInformation!=NULL)
{
POBJECT_BASIC_INFORMATION pobj_basic=(POBJECT_BASIC_INFORMATION)ObjectInformation;
dprintf("DragonNest pid %d ObjectBasicInformation HandleCount %d handle %08x\n",PsGetCurrentProcessId(),pobj_basic->HandleCount,(ULONG)ObjectHandle);
}
break;
}
}
}
__except(1)
{
dprintf("MyNtQueryObject error!\n");
}
return nTstatus;
}
ULONG Pass_NtQueryObject()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 163 * 4;
(ULONG)OrgNtQueryObject = *(ULONG*)Address; //保存此地址
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtQueryObject; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//反补丁,用于最后恢复用
VOID UnDetour_NtQueryObject()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 163 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OrgNtQueryObject; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef NTSYSAPI NTSTATUS (__stdcall *ZWCREATEMUTANT)(
OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN BOOLEAN InitialOwner );
ZWCREATEMUTANT OrgZwCreateMutant;
ULONG g_mutex_count=0;
NTSTATUS __stdcall MyZwCreateMutant(
OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN BOOLEAN InitialOwner )
{
PUNICODE_STRING p_mutex_name;
UNICODE_STRING uni_count;
WCHAR wzCount[3];
UNICODE_STRING tmpunicodestring,tmpunicodestring1;
OBJECT_ATTRIBUTES tmpobjatus;
NTSTATUS nTstatus;
__try
{
if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
{
if(ObjectAttributes==NULL)
return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
p_mutex_name=ObjectAttributes->ObjectName;
if(p_mutex_name )
{
if (p_mutex_name->Buffer)
{
// dprintf("mutex %S\n",p_mutex_name->Buffer);
if (!wcscmp(p_mutex_name->Buffer,L"Global\\MutexDragonNest"))
{
// return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
dprintf("fack mutex!\n");
return STATUS_SUCCESS;
// DbgBreakPoint();
nTstatus=OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
while(1)
{
if (nTstatus==STATUS_OBJECT_NAME_EXISTS)
{
dprintf("STATUS_OBJECT_NAME_EXISTS\n");
g_mutex_count++;
if(g_mutex_count==20) g_mutex_count=0;
dprintf("g_mutex_count %d\n",g_mutex_count);
uni_count.Buffer=(PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
uni_count.MaximumLength=BUFFER_SIZE;
nTstatus=RtlIntegerToUnicodeString(g_mutex_count,10,&uni_count);
if (NT_SUCCESS(nTstatus))
{
dprintf("uni_count %wZ\n",uni_count);
RtlInitUnicodeString(&tmpunicodestring1,L"Global\\MutexDragonNest");
tmpunicodestring.Buffer=(PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
tmpunicodestring.MaximumLength=BUFFER_SIZE;
//wcscpy(tmpunicodestring.Buffer,L"Global\\MutexDragonNest");
RtlCopyUnicodeString(&tmpunicodestring,&tmpunicodestring1);
RtlAppendUnicodeStringToString(&tmpunicodestring,&uni_count);
DbgPrint("tmpunicodestring %wZ\n",&tmpunicodestring);
InitializeObjectAttributes(&tmpobjatus,&tmpunicodestring,ObjectAttributes->Attributes,
ObjectAttributes->RootDirectory,ObjectAttributes->SecurityDescriptor);
nTstatus=OrgZwCreateMutant(MutantHandle,DesiredAccess,&tmpobjatus,InitialOwner);
dprintf("name %wZ\n",tmpobjatus.ObjectName);
RtlFreeUnicodeString(&tmpunicodestring);
}
else
{
dprintf("RtlIntegerToUnicodeString error!\n");
}
RtlFreeUnicodeString(&uni_count);
// RtlInitUnicodeString(&uni_count,wzCount);
}
else
{
dprintf("CreateMutex sucess! Mutex name %S\n",p_mutex_name->Buffer);
return nTstatus;
}
}
}
}
}
}
}
__except(1)
{
dprintf("MyZwCreateMutant error\n");
}
return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
}
ULONG Pass_NtCreateMutant()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 43 * 4;
(ULONG)OrgZwCreateMutant = *(ULONG*)Address; //保存此地址
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyZwCreateMutant; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//反补丁,用于最后恢复用
VOID UnDetour_NtCreateMutant()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 43 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OrgZwCreateMutant; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTQUERYSYSTEMINFORMATION)
(
ULONG SystemInformationCLass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
NTQUERYSYSTEMINFORMATION OldNtQuerySystemInformation;
typedef struct _SYSTEM_BASIC_INFORMATION {
BYTE Reserved1[24];
PVOID Reserved2[4];
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION;
NTSTATUS NewNtQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS ntStatus;
UNICODE_STRING gamename;
UNICODE_STRING launchername;
ntStatus = OldNtQuerySystemInformation(
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength );
if (!_stricmp(GetProcessNameFromEProc(0),"DragonNest.exe") || !_stricmp(GetProcessNameFromEProc(0),"dnlauncher.exe"))
{
if( NT_SUCCESS(ntStatus))
{
if(SystemInformationClass == 5)
{
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
struct _SYSTEM_PROCESSES *prev = NULL;
while(curr)
{
if (curr->ProcessName.Buffer != NULL)
{
// dprintf("processid %d\n",curr->ProcessId);
RtlInitUnicodeString(&gamename,L"DragonNest.exe");
RtlInitUnicodeString(&launchername,L"dnlauncher.exe");
if((!RtlCompareUnicodeString(&(curr->ProcessName),&gamename,FALSE) && (ULONG)PsGetCurrentProcessId()!=curr->ProcessId) ||
!RtlCompareUnicodeString(&(curr->ProcessName),&launchername,FALSE))
{
// dprintf("FIND DNF PDI %d\n",curr->ProcessId);
if(prev)
{
if(curr->NextEntryDelta)
{
prev->NextEntryDelta += curr->NextEntryDelta;
}
else
{
prev->NextEntryDelta = 0;
}
}
else
{
if(curr->NextEntryDelta)
{
(char *)SystemInformation += curr->NextEntryDelta;
}
else
{
SystemInformation = NULL;
}
}
}
else
{
prev = curr;
}
}
if(curr->NextEntryDelta)
{
((char *)curr += curr->NextEntryDelta);
}
else
{
curr = NULL;
}
}
}
}
}
return ntStatus;
}
ULONG Pass_NtQuerySystemInformation()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 173 * 4;
(ULONG)OldNtQuerySystemInformation = *(ULONG*)Address; //保存此地址
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtQuerySystemInformation; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//反补丁,用于最后恢复用
VOID UnDetour_NtQuerySystemInformation()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 173 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNtQuerySystemInformation; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
/*
805c1148 8bff mov edi,edi
805c114a 55 push ebp
805c114b 8bec mov ebp,esp
805c114d 83ec10 sub esp,10h
*/
VOID UnHook()
{
KIRQL oldIrql;
unsigned char oldcode[]={0x8b,0xff,0x55,0x8b,0xec,0x83,0xec,0x10};
unsigned char* obcheckobjectaccessptr=(unsigned char*)GetFunctionAddr(L"ObCheckObjectAccess");
ULONG Address=(ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 257 * 4;
unsigned char* ntterminateprocessptr=(unsigned char*)(*(ULONG*)Address);
if (obcheckobjectaccessptr[0]==0x68)
{
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
RtlCopyMemory(obcheckobjectaccessptr,oldcode,8);
KeLowerIrql(oldIrql);
WPON();
}
if (ntterminateprocessptr[0]==0x68)
{
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
RtlCopyMemory(ntterminateprocessptr,oldcode,8);
KeLowerIrql(oldIrql);
WPON();
}
}
//////////////////////////////////////////////////////////////////////////NtOpenProcess
typedef NTSTATUS (*NTOPENPROCESS) (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
);
NTOPENPROCESS OldNtProcessAdd;
NTOPENPROCESS HookedNtOpenProcess;
extern POBJECT_TYPE PsProcessType;
NTSTATUS
NewNtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
HANDLE Handle;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PEPROCESS Process;
PETHREAD Thread;
CLIENT_ID CapturedCid={0};
BOOLEAN ObjectNamePresent;
BOOLEAN ClientIdPresent;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ULONG Attributes;
LUID SeDebugPrivilege = {0};
POBJECT_TYPE _PsProcessType;
PEPROCESS tempeprocess;
if (!strcmp("Open.exe",GetProcessNameFromEProc(0)))
{
DbgPrint("open.exe openprocess!\n");
}
if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
{
// return HookedNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
PsLookupProcessByProcessId(ClientId->UniqueProcess,&tempeprocess);
__try
{
if (
!strcmp("DML.exe",GetProcessNameFromEProc(tempeprocess)) ||
(!strcmp("DragonNest.exe",GetProcessNameFromEProc(tempeprocess)) && PsGetCurrentProcessId()!=ClientId->UniqueProcess)
/*!strcmp("DeRoX.exe",GetProcessNameFromEProc(tempeprocess))*/
)
{
return STATUS_ACCESS_DENIED;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
dprintf("GetExceptionCode %08x\n",GetExceptionCode());
return GetExceptionCode();
}
}
// UnHook();
(ULONG)_PsProcessType=*(ULONG*)PsProcessType;
PreviousMode = KeGetPreviousMode();
SeDebugPrivilege =RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
if (PreviousMode != KernelMode) {
__try {
ProbeForWriteHandle (ProcessHandle);
ProbeForReadSmallStructure (ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, UserMode);
if (ARGUMENT_PRESENT (ClientId)) {
ProbeForReadSmallStructure (ClientId, sizeof (CLIENT_ID), sizeof (ULONG));
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
} else {
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, KernelMode);
if (ARGUMENT_PRESENT (ClientId)) {
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
if (ObjectNamePresent && ClientIdPresent) {
return STATUS_INVALID_PARAMETER_MIX;
}
Status = SeCreateAccessState(
&AccessState,
&AuxData,
DesiredAccess,
&_PsProcessType->TypeInfo.GenericMapping
);
if ( !NT_SUCCESS(Status) ) {
return Status;
}
if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
} else {
AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
}
AccessState.RemainingDesiredAccess = 0;
}
if (ObjectNamePresent) {
Status = ObOpenObjectByName(
ObjectAttributes,
_PsProcessType,
PreviousMode,
&AccessState,
0,
NULL,
&Handle
);
SeDeleteAccessState( &AccessState );
if ( NT_SUCCESS(Status) ) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
if ( ClientIdPresent ) {
Thread = NULL;
if (CapturedCid.UniqueThread) {
Status = PsLookupProcessThreadByCid(
&CapturedCid,
&Process,
&Thread
);
if (!NT_SUCCESS(Status)) {
SeDeleteAccessState( &AccessState );
return Status;
}
} else {
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&Process
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
}
//
// OpenObjectByAddress
//
Status = ObOpenObjectByPointer(
Process,
Attributes,
&AccessState,
0,
_PsProcessType,
PreviousMode,
&Handle
);
SeDeleteAccessState( &AccessState );
if (Thread) {
ObDereferenceObject(Thread);
}
ObDereferenceObject(Process);
if (NT_SUCCESS (Status)) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
return STATUS_INVALID_PARAMETER_MIX;
}
ULONG Pass_NtOpenProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
(ULONG)OldNtProcessAdd = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtOpenProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtOpenProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) =(ULONG) OldNtProcessAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef
NTSTATUS
(*NTREADVIRTUALMEMORY)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL );
NTREADVIRTUALMEMORY OldNtReadVirtualMemoryAdd;
NTREADVIRTUALMEMORY HookedNtReadVirtualMemoryAdd;
NTSTATUS NewNtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID &
本人不保证此办法现在还生效!蓝屏死机于本人无关!
征途2的保护多了objecthook。
上代码!
代码:
#include "struct.h"
#include "FGPK.h"
//////////////////////////////////////////////////////////////////////////
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address=0;
PULONG pSSDTKernel,pSSWDTKernel;
PSERVICE_DESCRIPTOR_TABLE_SHADOW _KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE_SHADOW ShadowTable;
unsigned long SSDT_reentry_address,SSDTDW_reentry_address;
ULONG g_Dra_count=0;
ULONG g_Sem_count=0;
//////////////////////////////////////////////////////////////////////////
void RePlaceSSDT();
void RestoreSSDT();
ULONG Pass_NtCreateMutant();
VOID UnDetour_NtCreateMutant();
ULONG Pass_NtQuerySystemInformation();
VOID UnDetour_NtQuerySystemInformation();
ULONG Pass_NtOpenProcess();
VOID UnDetour_NtOpenProcess();
NTSTATUS HookFindWindow();
NTSTATUS UnHookFindWindow();
ULONG Pass_NtReadVirtualMemory();
VOID UnDetour_NtReadVirtualMemory();
ULONG Pass_NtWriteVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
ULONG Pass_NtCreateSemaphore();
VOID UnDetour_NtCreateSemaphore();
ULONG Pass_NtReleaseSemaphore();
VOID UnDetour_NtReleaseSemaphore();
ULONG Pass_NtOpenSemaphore();
VOID UnDetour_NtOpenSemaphore();
ULONG Pass_NtQueryObject();
VOID UnDetour_NtQueryObject();
ULONG Pass_NtWaitForSingleObject();
VOID UnDetour_NtWaitForSingleObject();
NTSTATUS HookNtUserPostMessage();
NTSTATUS UnHookNtUserPostMessage();
NTSTATUS HookNtUserSendInput();
NTSTATUS UnHookNtUserSendInput();
NTSTATUS HookNtUserMessageCall();
NTSTATUS UnHookNtUserMessageCall();
NTSTATUS InitSWSSDT();
ULONG IsHooked=0;
ULONG HookSysCall();
NTSTATUS GetHookedFunAdd();
//////////////////////////////////////////////////////////////////////////
PEPROCESS crsEProc;
PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTableShadow;
__declspec(dllimport) _stdcall KeAddSystemServiceTable(PVOID, PVOID, PVOID, PVOID, PVOID);
#define ObjectNameInformation 1
#define SystemHandleInformation 0x10
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} _SYSTEM_HANDLE_INFORMATION, *P_SYSTEM_HANDLE_INFORMATION;
typedef struct _SYSTEM_HANDLE_INformATION_EX {
ULONG NumberOfHandles;
_SYSTEM_HANDLE_INFORMATION Information[1];
} _SYSTEM_HANDLE_INFORMATION_EX, *PSYSTEM_HANDLE_INFORMATION_EX;
//////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
PDRIVER_OBJECT pDriverObj,
PUNICODE_STRING pRegistryString
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
dprintf("[FGPK] DriverEntry\n");
pDriverObj->MajorFunction[IRP_MJ_CREATE] = DispatchCreate;
pDriverObj->MajorFunction[IRP_MJ_CLOSE] = DispatchClose;
pDriverObj->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
pDriverObj->DriverUnload = DriverUnload;
RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
status = IoCreateDevice(pDriverObj,
0,
&ustrDevName,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDevObj);
if(!NT_SUCCESS(status)) {
dprintf("[FGPK] IoCreateDevice = 0x%x\n", status);
return status;
}
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status)) {
dprintf("[FGPK] IoCreateSymbolicLink = 0x%x\n", status);
IoDeleteDevice(pDevObj);
return status;
}
//
// 添加执行代码
//
RePlaceSSDT();
InitSWSSDT();
// Pass_NtQueryObject();
// Pass_NtCreateMutant();
// Pass_NtCreateSemaphore();
// Pass_NtReleaseSemaphore();
// Pass_NtOpenSemaphore();
// Pass_NtWaitForSingleObject();
// Pass_NtQuerySystemInformation();
Pass_NtOpenProcess();
// Pass_NtReadVirtualMemory();
// Pass_NtWriteVirtualMemory();
// HookFindWindow();
// HookNtUserMessageCall();
// HookNtUserSendInput();
// HookNtUserPostMessage();
return STATUS_SUCCESS;
}
VOID
DriverUnload(
PDRIVER_OBJECT pDriverObj
)
{
UNICODE_STRING strLink;
RtlInitUnicodeString(&strLink, LINK_NAME);
//
// 添加卸载代码
//
// UnDetour_NtOpenSemaphore();
// UnDetour_NtWaitForSingleObject();
// UnDetour_NtCreateSemaphore();
// UnDetour_NtReleaseSemaphore();
// UnDetour_NtCreateMutant();
// UnDetour_NtQueryObject();
// UnDetour_NtQuerySystemInformation();
UnDetour_NtOpenProcess();
// UnDetour_NtReadVirtualMemory();
// UnDetour_NtWriteVirtualMemory();
// UnHookFindWindow();
// UnHookNtUserPostMessage();
// UnHookNtUserSendInput();
// UnHookNtUserMessageCall();
RestoreSSDT();
// Sleep(5000);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
dprintf("[FGPK] Unloaded\n");
}
NTSTATUS
DispatchCreate(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[FGPK] IRP_MJ_CREATE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchClose(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[FGPK] IRP_MJ_CLOSE\n");
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS
DispatchIoctl(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
NTSTATUS status = STATUS_INVALID_DEVICE_REQUEST;
PIO_STACK_LOCATION pIrpStack;
ULONG uIoControlCode;
PVOID pIoBuffer;
ULONG uInSize;
ULONG uOutSize;
pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;
pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
uInSize = pIrpStack->Parameters.DeviceIoControl.InputBufferLength;
uOutSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
switch(uIoControlCode) {
case IOCTL_HELLO: {
dprintf("[FGPK] Hello\n");
GetHookedFunAdd();
HookSysCall();
IsHooked=1;
status = STATUS_SUCCESS;
}
break;
//
// 添加执行代码
//
}
if(status == STATUS_SUCCESS)
pIrp->IoStatus.Information = uOutSize;
else
pIrp->IoStatus.Information = 0;
/////////////////////////////////////
pIrp->IoStatus.Status = status;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return status;
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS IsGame()
{
if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
{
return 1;
}
return 0;
}
//////////////////////////////////////////////////////////////////////////
void __declspec(naked) my_function_detour_KiFastCallEntry()
{
__asm
{
cmp ecx,10h
jne SSDT
pushad
call IsGame
cmp eax,1
popad
je ZTGAME1
mov edi,KeServiceDescriptorTable
sub edi,0x10
ZTGAME1:
jmp [SSDTDW_reentry_address]
SSDT:
pushad
call IsGame
cmp eax,1
popad
je ZTGAME2
mov edi,KeServiceDescriptorTable
add edi,0x20
ZTGAME2:
jmp [SSDT_reentry_address]
}
}
UCHAR findcode[]={0x83,0xf9,0x10,0x75};
VOID FindHackAddr()
{
ULONG uSysenter;
ULONG i=0;
PUCHAR strSysenter;
__asm{
mov ecx,0x176
rdmsr
mov uSysenter,eax //得到KiFastCallEntry地址
}
strSysenter=(PUCHAR)uSysenter;
for (i=0;i<0x100;i++)
{
if (
findcode[0]==strSysenter[i] &&
findcode[1]==strSysenter[i+1] &&
findcode[2]==strSysenter[i+2] &&
findcode[3]==strSysenter[i+3] )
{
break;
}
}
KiSystemService_hack_address=uSysenter+i;
}
ULONG HookSysCall()
{
KIRQL oldIrql;
unsigned char newcode[] = { 0xE9, 0x44, 0x33, 0x22, 0x11};
char *actual_function;
int i = 0;
FindHackAddr();
if (KiSystemService_hack_address==0)
{
dprintf("find hack address error!\n");
return 0;
}
actual_function =(char*) KiSystemService_hack_address;
SSDT_reentry_address = KiSystemService_hack_address+0x20;
SSDTDW_reentry_address = KiSystemService_hack_address+0x5;
*( (unsigned long *)(&newcode[1]) ) = (ULONG)my_function_detour_KiFastCallEntry-KiSystemService_hack_address-5;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 5;i++)
{
g_pFindOrigCode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
PVOID GetInfoTable(ULONG ATableType)
{
ULONG mSize = 0x4000;
PVOID mPtr = NULL;
NTSTATUS St;
do
{
mPtr = ExAllocatePool(PagedPool, mSize);
memset(mPtr, 0, mSize);
if (mPtr)
{
St = ZwQuerySystemInformation(ATableType, mPtr, mSize, NULL);
} else return NULL;
if (St == STATUS_INFO_LENGTH_MISMATCH)
{
ExFreePool(mPtr);
mSize = mSize * 2;
}
} while (St == STATUS_INFO_LENGTH_MISMATCH);
if (St == STATUS_SUCCESS) return mPtr;
ExFreePool(mPtr);
return NULL;
}
HANDLE GetCsrPid()
{
HANDLE Process, hObject;
HANDLE CsrId = (HANDLE)0;
OBJECT_ATTRIBUTES obj;
CLIENT_ID cid;
UCHAR Buff[0x100];
POBJECT_NAME_INFORMATION ObjName = (PVOID)&Buff;
PSYSTEM_HANDLE_INFORMATION_EX Handles;
ULONG r;
Handles = GetInfoTable(SystemHandleInformation);
if (!Handles) return CsrId;
for (r = 0; r < Handles->NumberOfHandles; r++)
{
if (Handles->Information[r].ObjectTypeNumber == 21) //Port object
{
InitializeObjectAttributes(&obj, NULL, OBJ_KERNEL_HANDLE, NULL, NULL);
cid.UniqueProcess = (HANDLE)Handles->Information[r].ProcessId;
cid.UniqueThread = 0;
if (NT_SUCCESS(NtOpenProcess(&Process, PROCESS_DUP_HANDLE, &obj, &cid)))
{
if (NT_SUCCESS(ZwDuplicateObject(Process, (HANDLE)Handles->Information[r].Handle,NtCurrentProcess(), &hObject, 0, 0, DUPLICATE_SAME_ACCESS)))
{
if (NT_SUCCESS(ZwQueryObject(hObject, ObjectNameInformation, ObjName, 0x100, NULL)))
{
if (ObjName->Name.Buffer && !wcsncmp(L"\\Windows\\ApiPort", ObjName->Name.Buffer, 20))
{
CsrId = (HANDLE)Handles->Information[r].ProcessId;
}
}
ZwClose(hObject);
}
ZwClose(Process);
}
}
}
ExFreePool(Handles);
return CsrId;
}
unsigned long AddMyServiceTable()
{
ULONG nSDTKerCallLen,nSWDTKerCallLen;
NTSTATUS status;
PEPROCESS crsEProc;
__asm
{
pushad
mov eax,KeServiceDescriptorTable
mov _KeServiceDescriptorTable,eax
sub eax,0x40
mov ShadowTable,eax
popad
}
nSDTKerCallLen = _KeServiceDescriptorTable->ntoskrnl.NumberOfServices;
nSWDTKerCallLen = ShadowTable->win32k.NumberOfServices;
pSSDTKernel = (PULONG)ExAllocatePool( NonPagedPool, nSDTKerCallLen*sizeof(ULONG));
pSSWDTKernel= (PULONG)ExAllocatePool( NonPagedPool, nSWDTKerCallLen*sizeof(ULONG));
if(!pSSDTKernel || !pSSWDTKernel)
{
DbgPrint("AddMyServiceTable alloc fail\n");
return 0;
}
memset( (PVOID)pSSDTKernel, 0, nSDTKerCallLen*sizeof(ULONG));
memset( (PVOID)pSSWDTKernel, 0, nSWDTKerCallLen*sizeof(ULONG));
//填充新的SSDT表
//
RtlCopyMemory( (PVOID)pSSDTKernel,(PVOID)_KeServiceDescriptorTable->ntoskrnl.ServiceTableBase,nSDTKerCallLen*sizeof(ULONG) );
RtlCopyMemory( (PVOID)&_KeServiceDescriptorTable->NotUse1,(PVOID)&_KeServiceDescriptorTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE) );
//sswdt
status = PsLookupProcessByProcessId((HANDLE)GetCsrPid(), &crsEProc);
if (!NT_SUCCESS( status ))
{
DbgPrint("PsLookupProcessByProcessId() error\n");
return status;
}
KeAttachProcess(crsEProc);
__try
{
RtlCopyMemory( (PVOID)pSSWDTKernel,(PVOID)ShadowTable->win32k.ServiceTableBase,nSWDTKerCallLen*sizeof(ULONG) );
}
__finally
{
KeDetachProcess();
}
RtlCopyMemory( (PVOID)&ShadowTable->NotUse1,(PVOID)&ShadowTable->ntoskrnl,sizeof(SERVICE_DESCRIPTOR_TABLE));
RtlCopyMemory( (PVOID)&ShadowTable->NotUse2,(PVOID)&ShadowTable->win32k,sizeof(SERVICE_DESCRIPTOR_TABLE));
WPOFF();
RtlCopyMemory((PVOID)&_KeServiceDescriptorTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
RtlCopyMemory((PVOID)&ShadowTable->NotUse1.ServiceTableBase, &pSSDTKernel, sizeof(ULONG));
RtlCopyMemory((PVOID)&ShadowTable->NotUse2.ServiceTableBase, &pSSWDTKernel, sizeof(ULONG));
WPON();
return 1;
}
void RePlaceSSDT()
{
if (AddMyServiceTable())
{
HookSysCall();
}
}
void RestoreSSDT()
{
int i;
char *actual_function = (char *)(KiSystemService_hack_address);
KIRQL oldIrql;
WPOFF();
KeRaiseIrql( DISPATCH_LEVEL,&oldIrql );
for(i=0;i < 5;i++)
{
actual_function[i] = g_pFindOrigCode[i];
}
KeLowerIrql( oldIrql );
ExFreePool(pSSDTKernel);
ExFreePool(pSSWDTKernel);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTQUERYOBJECT)
(
IN HANDLE ObjectHandle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
OUT PVOID ObjectInformation,
IN ULONG ObjectInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
NTQUERYOBJECT OrgNtQueryObject;
//*****************************************************************************************************************
NTSYSAPI
NTSTATUS
NTAPI
ObQueryNameString(
__in PVOID Object,
__out_opt POBJECT_NAME_INFORMATION ObjectNameInfo,
__in ULONG Length,
__out PULONG ReturnLength
);
NTSTATUS GetObjectNameFromHandle(HANDLE Objecthandle,PUNICODE_STRING filename)
{
// PFILE_OBJECT pFileObject;
// OBJECT_HANDLE_INFORMATION HandleInformationObject;
NTSTATUS nTstatus;
POBJECT_NAME_INFORMATION pObjectInformation;
PVOID Object;
OBJECT_HANDLE_INFORMATION HandleInformation = {0};
ULONG TempReturnLength;
pObjectInformation=ExAllocatePool(PagedPool,0x100);
RtlZeroMemory(pObjectInformation,0x100);
__try
{
nTstatus = ObReferenceObjectByHandle( Objecthandle,
0,
NULL,
0,
&Object,
&HandleInformation );
if (NT_SUCCESS( nTstatus ))
{
nTstatus = ObQueryNameString( Object,
(POBJECT_NAME_INFORMATION)pObjectInformation,
0x100,
&TempReturnLength
);
RtlCopyUnicodeString(filename,(PUNICODE_STRING)&(pObjectInformation->Name));
return 0;
}
}
__except(1)
{
dprintf("GetObjectNameFromHandle error!\n");
}
return -1;
}
//********************************************************************************************************************
NTSTATUS __stdcall MyNtQueryObject(
HANDLE ObjectHandle,
OBJECT_INFORMATION_CLASS ObjectInformationClass,
PVOID ObjectInformation,
ULONG ObjectInformationLength,
PULONG ReturnLength)
{
NTSTATUS nTstatus;
UNICODE_STRING Objectname;
UNICODE_STRING oldname;
__try
{
if(strcmp(GetProcessNameFromEProc(0),"DragonNest.exe")==0)
{
//DragonNest pid 3548 ObjectNameInformation MyNtQueryObject name \BaseNamedObjects\dnx_579876753682410 handle 00000614
nTstatus=OrgNtQueryObject(ObjectHandle,ObjectInformationClass,ObjectInformation,ObjectInformationLength,ReturnLength);
switch (ObjectInformationClass)
{
case ObjectNameInformation:
if(ObjectInformation!=NULL)
{
POBJECT_NAME_INFORMATION pobj_name=(POBJECT_NAME_INFORMATION)ObjectInformation;
if (pobj_name->Name.Buffer)
{
if (wcsstr(pobj_name->Name.Buffer,L"dnx_57987675368241"))
{
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\dnx_57987675368241");
RtlCopyUnicodeString(&(pobj_name->Name),&oldname);
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
}
else if (wcsstr(pobj_name->Name.Buffer,L"MutexDragonNest"))
{
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
// RtlInitUnicodeString(&oldname,L"\\BaseNamedObjects\\MutexDragonNest");
// RtlCopyUnicodeString(&(pobj_name->Name),&oldname);
dprintf("DragonNest pid %d ObjectNameInformation MyNtQueryObject name %wZ handle %08x\n",PsGetCurrentProcessId(),&(pobj_name->Name),(ULONG)ObjectHandle);
}
}
}
break;
case ObjectBasicInformation:
if(ObjectInformation!=NULL)
{
POBJECT_BASIC_INFORMATION pobj_basic=(POBJECT_BASIC_INFORMATION)ObjectInformation;
dprintf("DragonNest pid %d ObjectBasicInformation HandleCount %d handle %08x\n",PsGetCurrentProcessId(),pobj_basic->HandleCount,(ULONG)ObjectHandle);
}
break;
}
}
}
__except(1)
{
dprintf("MyNtQueryObject error!\n");
}
return nTstatus;
}
ULONG Pass_NtQueryObject()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 163 * 4;
(ULONG)OrgNtQueryObject = *(ULONG*)Address; //保存此地址
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtQueryObject; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//反补丁,用于最后恢复用
VOID UnDetour_NtQueryObject()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 163 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OrgNtQueryObject; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef NTSYSAPI NTSTATUS (__stdcall *ZWCREATEMUTANT)(
OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN BOOLEAN InitialOwner );
ZWCREATEMUTANT OrgZwCreateMutant;
ULONG g_mutex_count=0;
NTSTATUS __stdcall MyZwCreateMutant(
OUT PHANDLE MutantHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN BOOLEAN InitialOwner )
{
PUNICODE_STRING p_mutex_name;
UNICODE_STRING uni_count;
WCHAR wzCount[3];
UNICODE_STRING tmpunicodestring,tmpunicodestring1;
OBJECT_ATTRIBUTES tmpobjatus;
NTSTATUS nTstatus;
__try
{
if (!strcmp(GetProcessNameFromEProc(0),"DragonNest.exe"))
{
if(ObjectAttributes==NULL)
return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
p_mutex_name=ObjectAttributes->ObjectName;
if(p_mutex_name )
{
if (p_mutex_name->Buffer)
{
// dprintf("mutex %S\n",p_mutex_name->Buffer);
if (!wcscmp(p_mutex_name->Buffer,L"Global\\MutexDragonNest"))
{
// return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
dprintf("fack mutex!\n");
return STATUS_SUCCESS;
// DbgBreakPoint();
nTstatus=OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
while(1)
{
if (nTstatus==STATUS_OBJECT_NAME_EXISTS)
{
dprintf("STATUS_OBJECT_NAME_EXISTS\n");
g_mutex_count++;
if(g_mutex_count==20) g_mutex_count=0;
dprintf("g_mutex_count %d\n",g_mutex_count);
uni_count.Buffer=(PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
uni_count.MaximumLength=BUFFER_SIZE;
nTstatus=RtlIntegerToUnicodeString(g_mutex_count,10,&uni_count);
if (NT_SUCCESS(nTstatus))
{
dprintf("uni_count %wZ\n",uni_count);
RtlInitUnicodeString(&tmpunicodestring1,L"Global\\MutexDragonNest");
tmpunicodestring.Buffer=(PWSTR)ExAllocatePool(PagedPool,BUFFER_SIZE);
tmpunicodestring.MaximumLength=BUFFER_SIZE;
//wcscpy(tmpunicodestring.Buffer,L"Global\\MutexDragonNest");
RtlCopyUnicodeString(&tmpunicodestring,&tmpunicodestring1);
RtlAppendUnicodeStringToString(&tmpunicodestring,&uni_count);
DbgPrint("tmpunicodestring %wZ\n",&tmpunicodestring);
InitializeObjectAttributes(&tmpobjatus,&tmpunicodestring,ObjectAttributes->Attributes,
ObjectAttributes->RootDirectory,ObjectAttributes->SecurityDescriptor);
nTstatus=OrgZwCreateMutant(MutantHandle,DesiredAccess,&tmpobjatus,InitialOwner);
dprintf("name %wZ\n",tmpobjatus.ObjectName);
RtlFreeUnicodeString(&tmpunicodestring);
}
else
{
dprintf("RtlIntegerToUnicodeString error!\n");
}
RtlFreeUnicodeString(&uni_count);
// RtlInitUnicodeString(&uni_count,wzCount);
}
else
{
dprintf("CreateMutex sucess! Mutex name %S\n",p_mutex_name->Buffer);
return nTstatus;
}
}
}
}
}
}
}
__except(1)
{
dprintf("MyZwCreateMutant error\n");
}
return OrgZwCreateMutant(MutantHandle,DesiredAccess,ObjectAttributes,InitialOwner);
}
ULONG Pass_NtCreateMutant()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 43 * 4;
(ULONG)OrgZwCreateMutant = *(ULONG*)Address; //保存此地址
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyZwCreateMutant; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//反补丁,用于最后恢复用
VOID UnDetour_NtCreateMutant()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 43 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OrgZwCreateMutant; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTQUERYSYSTEMINFORMATION)
(
ULONG SystemInformationCLass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength
);
NTQUERYSYSTEMINFORMATION OldNtQuerySystemInformation;
typedef struct _SYSTEM_BASIC_INFORMATION {
BYTE Reserved1[24];
PVOID Reserved2[4];
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION;
NTSTATUS NewNtQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS ntStatus;
UNICODE_STRING gamename;
UNICODE_STRING launchername;
ntStatus = OldNtQuerySystemInformation(
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength );
if (!_stricmp(GetProcessNameFromEProc(0),"DragonNest.exe") || !_stricmp(GetProcessNameFromEProc(0),"dnlauncher.exe"))
{
if( NT_SUCCESS(ntStatus))
{
if(SystemInformationClass == 5)
{
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES *)SystemInformation;
struct _SYSTEM_PROCESSES *prev = NULL;
while(curr)
{
if (curr->ProcessName.Buffer != NULL)
{
// dprintf("processid %d\n",curr->ProcessId);
RtlInitUnicodeString(&gamename,L"DragonNest.exe");
RtlInitUnicodeString(&launchername,L"dnlauncher.exe");
if((!RtlCompareUnicodeString(&(curr->ProcessName),&gamename,FALSE) && (ULONG)PsGetCurrentProcessId()!=curr->ProcessId) ||
!RtlCompareUnicodeString(&(curr->ProcessName),&launchername,FALSE))
{
// dprintf("FIND DNF PDI %d\n",curr->ProcessId);
if(prev)
{
if(curr->NextEntryDelta)
{
prev->NextEntryDelta += curr->NextEntryDelta;
}
else
{
prev->NextEntryDelta = 0;
}
}
else
{
if(curr->NextEntryDelta)
{
(char *)SystemInformation += curr->NextEntryDelta;
}
else
{
SystemInformation = NULL;
}
}
}
else
{
prev = curr;
}
}
if(curr->NextEntryDelta)
{
((char *)curr += curr->NextEntryDelta);
}
else
{
curr = NULL;
}
}
}
}
}
return ntStatus;
}
ULONG Pass_NtQuerySystemInformation()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 173 * 4;
(ULONG)OldNtQuerySystemInformation = *(ULONG*)Address; //保存此地址
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtQuerySystemInformation; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
//反补丁,用于最后恢复用
VOID UnDetour_NtQuerySystemInformation()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 173 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNtQuerySystemInformation; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
/*
805c1148 8bff mov edi,edi
805c114a 55 push ebp
805c114b 8bec mov ebp,esp
805c114d 83ec10 sub esp,10h
*/
VOID UnHook()
{
KIRQL oldIrql;
unsigned char oldcode[]={0x8b,0xff,0x55,0x8b,0xec,0x83,0xec,0x10};
unsigned char* obcheckobjectaccessptr=(unsigned char*)GetFunctionAddr(L"ObCheckObjectAccess");
ULONG Address=(ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 257 * 4;
unsigned char* ntterminateprocessptr=(unsigned char*)(*(ULONG*)Address);
if (obcheckobjectaccessptr[0]==0x68)
{
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
RtlCopyMemory(obcheckobjectaccessptr,oldcode,8);
KeLowerIrql(oldIrql);
WPON();
}
if (ntterminateprocessptr[0]==0x68)
{
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
RtlCopyMemory(ntterminateprocessptr,oldcode,8);
KeLowerIrql(oldIrql);
WPON();
}
}
//////////////////////////////////////////////////////////////////////////NtOpenProcess
typedef NTSTATUS (*NTOPENPROCESS) (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
);
NTOPENPROCESS OldNtProcessAdd;
NTOPENPROCESS HookedNtOpenProcess;
extern POBJECT_TYPE PsProcessType;
NTSTATUS
NewNtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
HANDLE Handle;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PEPROCESS Process;
PETHREAD Thread;
CLIENT_ID CapturedCid={0};
BOOLEAN ObjectNamePresent;
BOOLEAN ClientIdPresent;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ULONG Attributes;
LUID SeDebugPrivilege = {0};
POBJECT_TYPE _PsProcessType;
PEPROCESS tempeprocess;
if (!strcmp("Open.exe",GetProcessNameFromEProc(0)))
{
DbgPrint("open.exe openprocess!\n");
}
if (!strcmp("HProtect.exe",GetProcessNameFromEProc(0)) || !strcmp("zhengtu2.dat",GetProcessNameFromEProc(0)))
{
// return HookedNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
PsLookupProcessByProcessId(ClientId->UniqueProcess,&tempeprocess);
__try
{
if (
!strcmp("DML.exe",GetProcessNameFromEProc(tempeprocess)) ||
(!strcmp("DragonNest.exe",GetProcessNameFromEProc(tempeprocess)) && PsGetCurrentProcessId()!=ClientId->UniqueProcess)
/*!strcmp("DeRoX.exe",GetProcessNameFromEProc(tempeprocess))*/
)
{
return STATUS_ACCESS_DENIED;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
dprintf("GetExceptionCode %08x\n",GetExceptionCode());
return GetExceptionCode();
}
}
// UnHook();
(ULONG)_PsProcessType=*(ULONG*)PsProcessType;
PreviousMode = KeGetPreviousMode();
SeDebugPrivilege =RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
if (PreviousMode != KernelMode) {
__try {
ProbeForWriteHandle (ProcessHandle);
ProbeForReadSmallStructure (ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, UserMode);
if (ARGUMENT_PRESENT (ClientId)) {
ProbeForReadSmallStructure (ClientId, sizeof (CLIENT_ID), sizeof (ULONG));
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
} else {
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, KernelMode);
if (ARGUMENT_PRESENT (ClientId)) {
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
if (ObjectNamePresent && ClientIdPresent) {
return STATUS_INVALID_PARAMETER_MIX;
}
Status = SeCreateAccessState(
&AccessState,
&AuxData,
DesiredAccess,
&_PsProcessType->TypeInfo.GenericMapping
);
if ( !NT_SUCCESS(Status) ) {
return Status;
}
if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
} else {
AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
}
AccessState.RemainingDesiredAccess = 0;
}
if (ObjectNamePresent) {
Status = ObOpenObjectByName(
ObjectAttributes,
_PsProcessType,
PreviousMode,
&AccessState,
0,
NULL,
&Handle
);
SeDeleteAccessState( &AccessState );
if ( NT_SUCCESS(Status) ) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
if ( ClientIdPresent ) {
Thread = NULL;
if (CapturedCid.UniqueThread) {
Status = PsLookupProcessThreadByCid(
&CapturedCid,
&Process,
&Thread
);
if (!NT_SUCCESS(Status)) {
SeDeleteAccessState( &AccessState );
return Status;
}
} else {
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&Process
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
}
//
// OpenObjectByAddress
//
Status = ObOpenObjectByPointer(
Process,
Attributes,
&AccessState,
0,
_PsProcessType,
PreviousMode,
&Handle
);
SeDeleteAccessState( &AccessState );
if (Thread) {
ObDereferenceObject(Thread);
}
ObDereferenceObject(Process);
if (NT_SUCCESS (Status)) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
return STATUS_INVALID_PARAMETER_MIX;
}
ULONG Pass_NtOpenProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
(ULONG)OldNtProcessAdd = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtOpenProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtOpenProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) =(ULONG) OldNtProcessAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
typedef
NTSTATUS
(*NTREADVIRTUALMEMORY)(
IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesReaded OPTIONAL );
NTREADVIRTUALMEMORY OldNtReadVirtualMemoryAdd;
NTREADVIRTUALMEMORY HookedNtReadVirtualMemoryAdd;
NTSTATUS NewNtReadVirtualMemory(
IN HANDLE ProcessHandle,
IN PVOID &
上一篇: “程序员帮我修个电脑吧”“不会 滚”
下一篇: 几种常用的网络协议