游戏保护大放送之HS
程序员文章站
2022-07-05 23:29:27
作 者: wtxpwh
本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系
做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无关
&...
作 者: wtxpwh
本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系
做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无关
安博士hook和tp差不多都是那些关键敏感的函数。至于是哪些被hook请自己动手用工具查看一下。
直接上代码!
代码:
#include "struct.h"
#include "4BOD.h"
//////////////////////////////////////////////////////////////////////////
ULONG Pass_NtProcess();
VOID UnDetour_NtProcess();
ULONG Pass_NtWriteVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
ULONG Pass_NtReadVirtualMemory();
VOID UnDetour_NtReadVirtualMemory();
ULONG Pass_KiAttachProcess();
VOID UnDetour_KiAttachProcess();
ULONG Pass_NtQueryInformationProcess();
VOID UnDetour_NtQueryInformationProcess();
ULONG Pass_PsSuspendThread();
VOID UnDetour_PsSuspendThread();
ULONG Pass_NtSetContextThread();
VOID UnDetour_NtSetContextThread();
ULONG Pass_NtGetContextThread();
VOID UnDetour_NtGetContextThread();
void Init_fun();
ULONG SearchMutex();
ULONG Pass_debugport();
ULONG FindProcess();
//////////////////////////////////////////////////////////////////////////
ULONG KeStackAttachProcess_Addr;
ULONG __stdcall IsNPCalled(HANDLE ProcessHandle);
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address;
PULONG pSSDTKernel;
PSERVICE_DESCRIPTOR_TABLE_SHADOW _KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE_SHADOW ShadowTable;
unsigned long SSDT_reentry_address,SSDTDW_reentry_address;
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 // www.2cto.com 得到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;
ULONG uSysenter;
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;
}
/*
__asm{
mov ecx,0x176
rdmsr
mov uSysenter,eax //得到KiFastCallEntry地址
}
KiSystemService_hack_address=uSysenter+0xaf;
*/
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;
}
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();
}
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)
{
DbgPrint("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();
}
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
PDRIVER_OBJECT pDriverObj,
PUNICODE_STRING pRegistryString
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
dprintf("[4BOD] 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("[4BOD] IoCreateDevice = 0x%x\n", status);
return status;
}
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status)) {
dprintf("[4BOD] IoCreateSymbolicLink = 0x%x\n", status);
IoDeleteDevice(pDevObj);
return status;
}
Init_fun();
RePlaceSSDT();
// FindProcess();
// SearchMutex();
// Pass_debugport();
Pass_NtProcess();
Pass_KiAttachProcess();
Pass_NtReadVirtualMemory();
Pass_NtWriteVirtualMemory();
Pass_NtQueryInformationProcess();
Pass_PsSuspendThread();
Pass_NtSetContextThread();
Pass_NtGetContextThread();
return STATUS_SUCCESS;
}
VOID
DriverUnload(
PDRIVER_OBJECT pDriverObj
)
{
UNICODE_STRING strLink;
LARGE_INTEGER Delay;
RtlInitUnicodeString(&strLink, LINK_NAME);
UnDetour_NtGetContextThread();
UnDetour_NtSetContextThread();
UnDetour_PsSuspendThread();
UnDetour_NtQueryInformationProcess();
UnDetour_NtWriteVirtualMemory();
UnDetour_NtReadVirtualMemory();
UnDetour_KiAttachProcess();
UnDetour_NtProcess();
RestoreSSDT();
Delay.QuadPart = -5000000;
KeDelayExecutionThread(KernelMode, TRUE, &Delay);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
dprintf("[4BOD] Unloaded\n");
}
NTSTATUS
DispatchCreate(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[4BOD] 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("[4BOD] 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("[4BOD] 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;
}
//////////////////////////////////////////////////////////////////////////
//返回-1:拒绝访问
//返回0 :走NP HOOK
//返回1 :绕过NP HOOK
//
////////////////////////////////////////////////////////////////////////////
ULONG __stdcall IsNPCalled(HANDLE ProcessHandle)
{
NTSTATUS status;
PEPROCESS pEProcess=0;
char* proname=0;
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
if (!ProcessHandle)
{
return 0;
}
status = ObReferenceObjectByHandle(ProcessHandle,PROCESS_ALL_ACCESS,NULL,0,&pEProcess,NULL);
if(!NT_SUCCESS(status))
{
DbgPrint("ObReferenceObjectByHandle fail! %08x \n",status);
return 0;
}
ObDereferenceObject(pEProcess);
proname=GetProcessNameFromEProc(pEProcess);
if (!_stricmp("OllyDBG.EXE",proname))
{
DbgPrint("ollydbg!!!!!!!!! \n");
return -1;
}
if (!_stricmp("Shadow.exe",proname))
{
return -1;
}
if (!_stricmp("taskmgr.exe",proname))
{
return -1;
}
return 0;
}
else if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("Shadow.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else
{
return 0;
}
}
//////////////////////////////////////////////////////////////////////////
ULONG __stdcall IsNPCalled_EP(PEPROCESS EProcess)
{
NTSTATUS status;
PEPROCESS pEProcess=0;
char* proname=0;
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
if (!EProcess)
{
return 0;
}
proname=GetProcessNameFromEProc(EProcess);
if (!_stricmp("OllyDBG.EXE",proname))
{
DbgPrint("ollydbg!!!!!!!!! epepepepep\n");
return -1;
}
if (!_stricmp("Shadow.exe",proname))
{
return -1;
}
if (!_stricmp("taskmgr.exe",proname))
{
return -1;
}
return 0;
}
else if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("Shadow.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else
{
return 0;
}
}
//////////////////////////////////////////////////////////////////////////
ULONG old_KiMoveApcState;
ULONG Init_KiMoveApcState()
{
old_KiMoveApcState=KeStackAttachProcess_Addr-0x6b2;
return 1;
}
VOID __declspec(naked) _KiMoveApcState (
__in PKAPC_STATE Source,
__out PKAPC_STATE Destination
)
{
__asm
{
jmp [old_KiMoveApcState]
}
}
//////////////////////////////////////////////////////////////////////////
ULONG __stdcall fack(PEPROCESS Pep)
{
__try
{
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
if (!_stricmp("ollydbg.exe",GetProcessNameFromEProc(Pep)))
{
DbgPrint("dnf kiattachprocess ollydbg!!!\n");
return 1;
}
}
}
__except(1)
{
DbgPrint("fack error!!\n");
}
return 0;
}
unsigned long KiAttachProcess_reentry_address;
void __declspec(naked) my_function_detour_KiAttachProcess()
{
__asm
{
inc word ptr [edi+0x60]
lea ebx,[esi+0x34]
push ebx
call _KiMoveApcState
jmp [KiAttachProcess_reentry_address]
}
}
//////////////////////////////////////////////////////////////////////////
char KiAttachProcess_g_oricode[8];
ULONG Pass_KiAttachProcess()
{
char *actual_function;
KIRQL oldIrql;
int i = 0;
unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
actual_function = (char *)(KeStackAttachProcess_Addr-0x219);
KiAttachProcess_reentry_address = (KeStackAttachProcess_Addr-0x20c);
*( (unsigned long *)(&newcode[1]) ) = (unsigned long)my_function_detour_KiAttachProcess;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
KiAttachProcess_g_oricode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_KiAttachProcess()
{
char *actual_function = (char *)(KeStackAttachProcess_Addr-0x219);
KIRQL oldIrql;
int i = 0;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = KiAttachProcess_g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
ULONG OldNtReadVirtualMemoryAdd;
ULONG reentryadd_NtReadVirtualMemory;
__declspec(naked) NTSTATUS NewNtReadVirtualMemory()
{
__asm
{
push [esp+4]
call IsNPCalled
cmp eax,1
jnz NtReadVirtualMemory_ENT1
push 0x1c
push 0x804daef0
mov eax, 0x8053cbe0
call eax
jmp [reentryadd_NtReadVirtualMemory]
NtReadVirtualMemory_ENT1:
cmp eax,0
jnz NtReadVirtualMemory_ENT2
jmp [OldNtReadVirtualMemoryAdd]
NtReadVirtualMemory_ENT2:
mov eax,0
ret 0x14
}
}
//////////////////////////////////////////////////////////////////////////NtReadVirtualMemory
ULONG Pass_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4; //得到NtReadVirtualMemory的服务地址
(ULONG)OldNtReadVirtualMemoryAdd = *(ULONG*)Address; //保存此地址
reentryadd_NtReadVirtualMemory=OldNtReadVirtualMemoryAdd+0xc;
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();
}
ULONG reentryadd_NtWriteVirtualMemory;
ULONG OldNtWriteVirtualMemoryAdd;
__declspec(naked) NTSTATUS NewNtWriteVirtualMemory()
{
__asm
{
push [esp+4]
call IsNPCalled
cmp eax,1
jnz NtWriteVirtualMemory_ENT1
push 0x1c
push 0x804daf08
mov eax, 0x8053cbe0
call eax
jmp [reentryadd_NtWriteVirtualMemory]
NtWriteVirtualMemory_ENT1:
cmp eax,0
jnz NtWriteVirtualMemory_ENT2
jmp [OldNtWriteVirtualMemoryAdd]
NtWriteVirtualMemory_ENT2:
mov eax,0
ret 0x14
}
}
//////////////////////////////////////////////////////////////////////////
ULONG Pass_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x115 * 4;
(ULONG)OldNtWriteVirtualMemoryAdd = *(ULONG*)Address;
reentryadd_NtWriteVirtualMemory=OldNtWriteVirtualMemoryAdd+0xc;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtWriteVirtualMemory; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x115 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNtWriteVirtualMemoryAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////NtOpenProcess
ULONG OldNtProcessAdd;
ULONG reentryadd_NtWriteVirtualMemory;
NTSTATUS
_NtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
HANDLE Handle;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PEPROCESS Process;
PETHREAD Thread;
CLIENT_ID CapturedCid={0};
BOOLEAN ObjectNamePresent;
BOOLEAN ClientIdPresent;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ULONG Attributes;
LUID SeDebugPrivilege = {0};
POBJECT_TYPE _PsProcessType;
PEPROCESS tempeprocess;
PsLookupProcessByProcessId(ClientId->UniqueProcess,&tempeprocess);
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
// ERROR_INVALID_PARAMETER
__try
{
// DbgPrint("dnf threadid %d KTHREAD %08x want openprocess %s\n",
// PsGetCurrentThreadId(),PsGetCurrentThread(),GetProcessNameFromEProc(tempeprocess));
if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(tempeprocess)) )
{
return STATUS_INVALID_PARAMETER;
}
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(tempeprocess)) )
{
// return STATUS_INVALID_PARAMETER;
}
if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(tempeprocess)) )
{
return STATUS_INVALID_PARAMETER;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("GetExceptionCode %08x",GetExceptionCode());
// return GetExceptionCode();
}
return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
}
// DbgPrint("%s want openprocess %s\n",GetProcessNameFromEProc(0),GetProcessNameFromEProc(tempeprocess));
(ULONG)_PsProcessType=*(ULONG*)PsProcessType;
PreviousMode = KeGetPreviousMode();
SeDebugPrivilege =RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
if (PreviousMode != KernelMode) {
__try {
ProbeForWriteHandle (ProcessHandle);
ProbeForReadSmallStructure (ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, UserMode);
if (ARGUMENT_PRESENT (ClientId)) {
ProbeForReadSmallStructure (ClientId, sizeof (CLIENT_ID), sizeof (ULONG));
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
} else {
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, KernelMode);
if (ARGUMENT_PRESENT (ClientId)) {
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
if (ObjectNamePresent && ClientIdPresent) {
return STATUS_INVALID_PARAMETER_MIX;
}
Status = SeCreateAccessState(
&AccessState,
&AuxData,
DesiredAccess,
&_PsProcessType->TypeInfo.GenericMapping
);
if ( !NT_SUCCESS(Status) ) {
return Status;
}
if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
} else {
AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
}
AccessState.RemainingDesiredAccess = 0;
}
if (ObjectNamePresent) {
Status = ObOpenObjectByName(
ObjectAttributes,
_PsProcessType,
PreviousMode,
&AccessState,
0,
NULL,
&Handle
);
SeDeleteAccessState( &AccessState );
if ( NT_SUCCESS(Status) ) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
if ( ClientIdPresent ) {
Thread = NULL;
if (CapturedCid.UniqueThread) {
Status = PsLookupProcessThreadByCid(
&CapturedCid,
&Process,
&Thread
);
if (!NT_SUCCESS(Status)) {
SeDeleteAccessState( &AccessState );
return Status;
}
} else {
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&Process
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
}
//
// OpenObjectByAddress
//
Status = ObOpenObjectByPointer(
Process,
Attributes,
&AccessState,
0,
_PsProcessType,
PreviousMode,
&Handle
);
SeDeleteAccessState( &AccessState );
if (Thread) {
ObDereferenceObject(Thread);
}
ObDereferenceObject(Process);
if (NT_SUCCESS (Status)) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
return STATUS_INVALID_PARAMETER_MIX;
}
ULONG Pass_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
OldNtProcessAdd = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)_NtOpenProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtProcessAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
void Init_fun()
{
KeStackAttachProcess_Addr=GetFunctionAddr(L"KeStackAttachProcess");
Init_KiMoveApcState();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
#define SYSTEMSERVICE(Index) *(PULONG)((ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase+ Index*4);
ULONG DbgkForwardExceptionAddr = 0;
ULONG KiDispatchExceptionAddr = 0;
ULONG DbgkpQueueMessageAddr = 0;
ULONG SearchMutex()
{
ULONG NtResumeThreadAddr = 0;
ULONG NtRaiseExceptionAddr = 0;
ULONG KiRaiseExceptionAddr = 0;
ULONG DbgkpSendApiMessageAddr = 0;
ULONG DbgkpProcessDebugPortMutex =0;
ULONG PsResumeThreadAddr =0;
DWORD dwKey;
ULONG i;
NtResumeThreadAddr = SYSTEMSERVICE(206);
DbgPrint("NtResumeThreadAddr : %X\n", NtResumeThreadAddr);
for(i = NtResumeThreadAddr; i < NtResumeThreadAddr + 0x7C; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8E475FF)
{
dwKey = i + 4;
PsResumeThreadAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("PsResumeThreadAddr : %X\n", PsResumeThreadAddr);
NtRaiseExceptionAddr = SYSTEMSERVICE(181);
DbgPrint("NtRaiseExceptionAddr : %X\n", NtRaiseExceptionAddr);
for(i = NtRaiseExceptionAddr; i < NtRaiseExceptionAddr + 0x30; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8505100)
{
dwKey = i + 4;
KiRaiseExceptionAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("KiRaiseExceptionAddr : %X\n", KiRaiseExceptionAddr);
if (KiRaiseExceptionAddr > 0x80000000)
{
for(i = KiRaiseExceptionAddr; i < KiRaiseExceptionAddr + 0x197; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE853FFFF)
{
dwKey = i + 4;
KiDispatchExceptionAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("KiDispatchExceptionAddr : %X\n", KiDispatchExceptionAddr);
}
if (KiDispatchExceptionAddr > 0x80000000)
{
for(i = KiDispatchExceptionAddr; i < KiDispatchExceptionAddr + 0x397; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8565701)
{
dwKey = i + 4;
DbgkForwardExceptionAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("DbgkForwardExceptionAddr : %X\n", DbgkForwardExceptionAddr);
}
if (DbgkForwardExceptionAddr > 0x80000000)
{
for(i = DbgkForwardExceptionAddr; i < DbgkForwardExceptionAddr + 0x8A; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8508845)
{
dwKey = i + 4;
DbgkpSendApiMessageAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("DbgkpSendApiMessageAddr : %X\n", DbgkpSendApiMessageAddr);
}
if (DbgkpSendApiMessageAddr > 0x80000000)
{
for(i = DbgkpSendApiMessageAddr; i < DbgkpSendApiMessageAddr + 0x55; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8515052)
{
dwKey = i + 4;
DbgkpQueueMessageAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("DbgkpQueueMessageAddr : %X\n", DbgkpQueueMessageAddr);
}
if (DbgkpQueueMessageAddr > 0x80000000)
{
for(i = DbgkpQueueMessageAddr; i < DbgkpQueueMessageAddr + 0x16F; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xB93075FC)
{
dwKey = i + 4;
DbgkpProcessDebugPortMutex = *(ULONG*)dwKey;
}
}
}
DbgPrint("DbgkpProcessDebugPortMutex : %X\n", DbgkpProcessDebugPortMutex);
}
return DbgkpProcessDebugPortMutex;
}
//////////////////////////////////////////////////////////////////////////
ULONG Pass_debugport()
{
KIRQL oldIrql;
char timestr[]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
char* g_KiDispatchException=(char*)(KiDispatchExceptionAddr+0x187);
char* g_PspCreateProcess=(char*)(KiDispatchExceptionAddr+0xD2599);
char* g_DbgkForwardException=(char*)(DbgkForwardExceptionAddr+0x3e);
char* g_DbgkpQueueMessage=(char*)(DbgkpQueueMessageAddr+0x7B);
char* g_DbgkCreateThread=(char*)(KiDispatchExceptionAddr+0x14515F);
char* g_DbgkExitThread=(char*)(KiDispatchExceptionAddr+0x1453F8);
char* g_DbgkMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x14550B);
char* g_DbgkExitProcess=(char*)(KiDispatchExceptionAddr+0x145472);
char* g_DbgkUnMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x1455D1);
char* g_PspExitThread=(char*)(KiDispatchExceptionAddr+0xD3E84);
char* g_DbgkpMarkProcessPeb=(char*)(KiDispatchExceptionAddr+0x1438EA);
char* g_MmCreatePeb=(char*)(KiDispatchExceptionAddr+0xB1907);
char* g_DbgkpSetProcessDebugObject=(char*)(KiDispatchExceptionAddr+0x144934);
char* g_DbgkpSetProcessDebugObject1=(char*)(KiDispatchExceptionAddr+0x144942);
char* g_DbgkpSetProcessDebugObject2=(char*)(KiDispatchExceptionAddr+0x14495C);
char* g_DbgkpSetProcessDebugObject3=(char*)(KiDispatchExceptionAddr+0x1449A6);
char* g_DbgkpSetProcessDebugObject4=(char*)(KiDispatchExceptionAddr+0x1449E8);
//nop
char* anti_DbgkExitThread=(char*)(KiDispatchExceptionAddr+0x1453F6);
char* anti_DbgkExitProcess=(char*)(KiDispatchExceptionAddr+0x145470);
char* anti_DbgkUnMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x1455CF);
//jmp
char* anti_DbgkMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x145505);
char* anti_DbgkForwardException=(char*)(DbgkForwardExceptionAddr+0x38);
//nop create time
char* g_PspCreateProcess_time=(char*)(KiDispatchExceptionAddr+0xD2B15);
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
memcpy(g_PspCreateProcess_time,timestr,9);
*(ULONG*)(&g_KiDispatchException[2])=0x70;
*(ULONG*)(&g_PspCreateProcess[2])=0x70;
*(ULONG*)(&g_DbgkForwardException[2])=0x70;
*(ULONG*)(&g_DbgkpQueueMessage[2])=0x70;
*(ULONG*)(&g_DbgkCreateThread[2])=0x70;
*(ULONG*)(&g_DbgkExitThread[2])=0x70;
*(ULONG*)(&g_DbgkMapViewOfSection[2])=0x70;
*(ULONG*)(&g_DbgkExitProcess[2])=0x70;
*(ULONG*)(&g_DbgkUnMapViewOfSection[2])=0x70;
*(ULONG*)(&g_PspExitThread[2])=0x70;
*(ULONG*)(&g_DbgkpMarkProcessPeb[2])=0x70;
*(ULONG*)(&g_MmCreatePeb[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject1[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject2[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject3[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject4[2])=0x70;
//
// anti_DbgkExitThread[0]=0x90;
// anti_DbgkExitThread[1]=0x90;
// anti_DbgkExitProcess[0]=0x90;
// anti_DbgkExitProcess[1]=0x90;
// anti_DbgkUnMapViewOfSection[0]=0x90;
// anti_DbgkUnMapViewOfSection[1]=0x90;
//
// anti_DbgkMapViewOfSection[0]=0xeb;
// anti_DbgkForwardException[0]=0xeb;
KeLowerIrql(oldIrql);
WPON();
return STATUS_SUCCESS;
}
const int process_list_offset=0x88;
const int createtime_list_offset=0x70;
ULONG FindProcess()
{
ULONG cproc=0x00000000;
ULONG i=0;
ULONG TPID;
PEPROCESS tmpeprocess;
PLIST_ENTRY plist_active_procs;
LARGE_INTEGER temptime;
temptime.QuadPart=0;
PsLookupProcessByProcessId((HANDLE)4,&tmpeprocess);
cproc=(ULONG)tmpeprocess;
while (1)
{
if ((i>=1) && ((ULONG)tmpeprocess==cproc))
{
break;
return 0x00000000;
}
else
{
plist_active_procs=(LIST_ENTRY*)(cproc+process_list_offset);
cproc=(ULONG)plist_active_procs->Flink;
cproc=cproc-process_list_offset;
*(LARGE_INTEGER*)(cproc+createtime_list_offset)=temptime;
i++;
}
}
return 1;
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTQUERYINFORMATIONPROCESS)(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
NTQUERYINFORMATIONPROCESS OldNQueryInformationProcessAddr;
typedef struct _PROCESS_DEBUG_PORT_INFO
{
HANDLE DebugPort;
} PROCESS_DEBUG_PORT_INFO;
//enum SYSTEM_INFORMATION_CLASS { SystemKernelDebuggerInformation = 35 };
//enum THREAD_INFO_CLASS { ThreadHideFromDebugger = 17 };
//enum PROCESS_INFO_CLASS { ProcessDebugPort = 7 };
NTSTATUS NewNtQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out PROCESS_DEBUG_PORT_INFO* ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
)
{
// PROCESS_DEBUG_PORT_INFO* tempPi;
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)) ||
!_stricmp("AION.bin",GetProcessNameFromEProc(0)) ||
!_stricmp("GameMon.des",GetProcessNameFromEProc(0)))
{
if (ProcessInformationClass==7)
{
DbgPrint("%s NtQueryInformationProcess debugport!\n",GetProcessNameFromEProc(0));
ProcessInformation->DebugPort=0;
return 0;
}
}
// DbgPrint("%s NtQueryInformationProcess !\n",GetProcessNameFromEProc(0));
return OldNQueryInformationProcessAddr(ProcessHandle,ProcessInformationClass,ProcessInformation,ProcessInformationLength,ReturnLength);
}
ULONG Pass_NtQueryInformationProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 154 * 4;
(ULONG)OldNQueryInformationProcessAddr = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtQueryInformationProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtQueryInformationProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 154 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNQueryInformationProcessAddr; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
// NTSTATUS __declspec(naked) _PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
// {
//
// }
//////////////////////////////////////////////////////////////////////////
//unsigned long PsSuspendThread_reentry_address;
ULONG pssuspendthreadaddr;
NTSTATUS __declspec(naked) _PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
{
__asm
{
push 0x18
push 0x804db9e8
mov esi,0x8053cbe0
call esi
mov esi,pssuspendthreadaddr
add esi,0xc
jmp esi
}
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS
_NtSuspendThread(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
)
{
PETHREAD Thread;
NTSTATUS st;
ULONG LocalPreviousSuspendCount;
KPROCESSOR_MODE Mode;
POBJECT_TYPE TempType;
// PAGED_CODE();
Mode = KeGetPreviousMode ();
try {
if (Mode != KernelMode) {
if (ARGUMENT_PRESENT (PreviousSuspendCount)) {
ProbeForWriteUlong (PreviousSuspendCount);
}
}
} except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
(ULONG)TempType=*(ULONG*)PsThreadType;
st = ObReferenceObjectByHandle (ThreadHandle,
THREAD_SUSPEND_RESUME,
TempType,
Mode,
&Thread,
NULL);
if (!NT_SUCCESS (st)) {
return st;
}
st = _PsSuspendThread (Thread, &LocalPreviousSuspendCount);
ObDereferenceObject (Thread);
try {
if (ARGUMENT_PRESENT (PreviousSuspendCount)) {
*PreviousSuspendCount = LocalPreviousSuspendCount;
}
} except (EXCEPTION_EXECUTE_HANDLER) {
st = GetExceptionCode ();
}
return st;
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS(*NTSUSPENDTHREAD)(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
);
NTSUSPENDTHREAD OldSuspendThreadAddr;
NTSTATUS MyNtSuspendThread(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
)
{
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
return OldSuspendThreadAddr(ThreadHandle,PreviousSuspendCount);
}
return _NtSuspendThread(ThreadHandle,PreviousSuspendCount);
}
ULONG Pass_PsSuspendThread()
{
KIRQL oldIrql;
ULONG Address=0;
LONG temp=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 254 * 4;
(ULONG)OldSuspendThreadAddr = *(ULONG*)Address;
temp=*(LONG*)((LONG)OldSuspendThreadAddr+0x65);
pssuspendthreadaddr=(LONG)OldSuspendThreadAddr+0x64+temp+5;
DbgPrint("pssuspendthreadaddr %08x\n",pssuspendthreadaddr);
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtSuspendThread; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_PsSuspendThread()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 254 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldSuspendThreadAddr; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS
MyNtGetContextThread(
__in HANDLE ThreadHandle,
__inout PCONTEXT ThreadContext
)
{
KPROCESSOR_MODE Mode;
NTSTATUS Status;
PETHREAD Thread;
PKTHREAD CurrentThread;
POBJECT_TYPE TempType;
// PAGED_CODE();
//
// Get previous mode and reference specified thread.
//
CurrentThread = KeGetCurrentThread();
Mode = *(CCHAR*)((ULONG)CurrentThread+0x140);
(ULONG)TempType=*(ULONG*)PsThreadType;
Status = ObReferenceObjectByHandle (ThreadHandle,
THREAD_GET_CONTEXT,
TempType,
Mode,
&Thread,
NULL);
//
// If the reference was successful, the check if the specified thread
// is a system thread.
//
if (NT_SUCCESS (Status)) {
//
// If t
本人寻求游戏安全方面的工作,Email:wtxpwh@163.com联系
做挂者请绕道!
本人不保证此办法现在还生效!蓝屏死机于本人无关
安博士hook和tp差不多都是那些关键敏感的函数。至于是哪些被hook请自己动手用工具查看一下。
直接上代码!
代码:
#include "struct.h"
#include "4BOD.h"
//////////////////////////////////////////////////////////////////////////
ULONG Pass_NtProcess();
VOID UnDetour_NtProcess();
ULONG Pass_NtWriteVirtualMemory();
VOID UnDetour_NtWriteVirtualMemory();
ULONG Pass_NtReadVirtualMemory();
VOID UnDetour_NtReadVirtualMemory();
ULONG Pass_KiAttachProcess();
VOID UnDetour_KiAttachProcess();
ULONG Pass_NtQueryInformationProcess();
VOID UnDetour_NtQueryInformationProcess();
ULONG Pass_PsSuspendThread();
VOID UnDetour_PsSuspendThread();
ULONG Pass_NtSetContextThread();
VOID UnDetour_NtSetContextThread();
ULONG Pass_NtGetContextThread();
VOID UnDetour_NtGetContextThread();
void Init_fun();
ULONG SearchMutex();
ULONG Pass_debugport();
ULONG FindProcess();
//////////////////////////////////////////////////////////////////////////
ULONG KeStackAttachProcess_Addr;
ULONG __stdcall IsNPCalled(HANDLE ProcessHandle);
char g_pFindOrigCode[8];
ULONG KiSystemService_hack_address;
PULONG pSSDTKernel;
PSERVICE_DESCRIPTOR_TABLE_SHADOW _KeServiceDescriptorTable;
PSERVICE_DESCRIPTOR_TABLE_SHADOW ShadowTable;
unsigned long SSDT_reentry_address,SSDTDW_reentry_address;
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 // www.2cto.com 得到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;
ULONG uSysenter;
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;
}
/*
__asm{
mov ecx,0x176
rdmsr
mov uSysenter,eax //得到KiFastCallEntry地址
}
KiSystemService_hack_address=uSysenter+0xaf;
*/
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;
}
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();
}
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)
{
DbgPrint("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();
}
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS
DriverEntry(
PDRIVER_OBJECT pDriverObj,
PUNICODE_STRING pRegistryString
)
{
NTSTATUS status = STATUS_SUCCESS;
UNICODE_STRING ustrLinkName;
UNICODE_STRING ustrDevName;
PDEVICE_OBJECT pDevObj;
dprintf("[4BOD] 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("[4BOD] IoCreateDevice = 0x%x\n", status);
return status;
}
RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);
if(!NT_SUCCESS(status)) {
dprintf("[4BOD] IoCreateSymbolicLink = 0x%x\n", status);
IoDeleteDevice(pDevObj);
return status;
}
Init_fun();
RePlaceSSDT();
// FindProcess();
// SearchMutex();
// Pass_debugport();
Pass_NtProcess();
Pass_KiAttachProcess();
Pass_NtReadVirtualMemory();
Pass_NtWriteVirtualMemory();
Pass_NtQueryInformationProcess();
Pass_PsSuspendThread();
Pass_NtSetContextThread();
Pass_NtGetContextThread();
return STATUS_SUCCESS;
}
VOID
DriverUnload(
PDRIVER_OBJECT pDriverObj
)
{
UNICODE_STRING strLink;
LARGE_INTEGER Delay;
RtlInitUnicodeString(&strLink, LINK_NAME);
UnDetour_NtGetContextThread();
UnDetour_NtSetContextThread();
UnDetour_PsSuspendThread();
UnDetour_NtQueryInformationProcess();
UnDetour_NtWriteVirtualMemory();
UnDetour_NtReadVirtualMemory();
UnDetour_KiAttachProcess();
UnDetour_NtProcess();
RestoreSSDT();
Delay.QuadPart = -5000000;
KeDelayExecutionThread(KernelMode, TRUE, &Delay);
IoDeleteSymbolicLink(&strLink);
IoDeleteDevice(pDriverObj->DeviceObject);
dprintf("[4BOD] Unloaded\n");
}
NTSTATUS
DispatchCreate(
PDEVICE_OBJECT pDevObj,
PIRP pIrp
)
{
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
dprintf("[4BOD] 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("[4BOD] 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("[4BOD] 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;
}
//////////////////////////////////////////////////////////////////////////
//返回-1:拒绝访问
//返回0 :走NP HOOK
//返回1 :绕过NP HOOK
//
////////////////////////////////////////////////////////////////////////////
ULONG __stdcall IsNPCalled(HANDLE ProcessHandle)
{
NTSTATUS status;
PEPROCESS pEProcess=0;
char* proname=0;
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
if (!ProcessHandle)
{
return 0;
}
status = ObReferenceObjectByHandle(ProcessHandle,PROCESS_ALL_ACCESS,NULL,0,&pEProcess,NULL);
if(!NT_SUCCESS(status))
{
DbgPrint("ObReferenceObjectByHandle fail! %08x \n",status);
return 0;
}
ObDereferenceObject(pEProcess);
proname=GetProcessNameFromEProc(pEProcess);
if (!_stricmp("OllyDBG.EXE",proname))
{
DbgPrint("ollydbg!!!!!!!!! \n");
return -1;
}
if (!_stricmp("Shadow.exe",proname))
{
return -1;
}
if (!_stricmp("taskmgr.exe",proname))
{
return -1;
}
return 0;
}
else if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("Shadow.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else
{
return 0;
}
}
//////////////////////////////////////////////////////////////////////////
ULONG __stdcall IsNPCalled_EP(PEPROCESS EProcess)
{
NTSTATUS status;
PEPROCESS pEProcess=0;
char* proname=0;
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
if (!EProcess)
{
return 0;
}
proname=GetProcessNameFromEProc(EProcess);
if (!_stricmp("OllyDBG.EXE",proname))
{
DbgPrint("ollydbg!!!!!!!!! epepepepep\n");
return -1;
}
if (!_stricmp("Shadow.exe",proname))
{
return -1;
}
if (!_stricmp("taskmgr.exe",proname))
{
return -1;
}
return 0;
}
else if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("Shadow.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(0)))
{
return 1;
}
else
{
return 0;
}
}
//////////////////////////////////////////////////////////////////////////
ULONG old_KiMoveApcState;
ULONG Init_KiMoveApcState()
{
old_KiMoveApcState=KeStackAttachProcess_Addr-0x6b2;
return 1;
}
VOID __declspec(naked) _KiMoveApcState (
__in PKAPC_STATE Source,
__out PKAPC_STATE Destination
)
{
__asm
{
jmp [old_KiMoveApcState]
}
}
//////////////////////////////////////////////////////////////////////////
ULONG __stdcall fack(PEPROCESS Pep)
{
__try
{
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
if (!_stricmp("ollydbg.exe",GetProcessNameFromEProc(Pep)))
{
DbgPrint("dnf kiattachprocess ollydbg!!!\n");
return 1;
}
}
}
__except(1)
{
DbgPrint("fack error!!\n");
}
return 0;
}
unsigned long KiAttachProcess_reentry_address;
void __declspec(naked) my_function_detour_KiAttachProcess()
{
__asm
{
inc word ptr [edi+0x60]
lea ebx,[esi+0x34]
push ebx
call _KiMoveApcState
jmp [KiAttachProcess_reentry_address]
}
}
//////////////////////////////////////////////////////////////////////////
char KiAttachProcess_g_oricode[8];
ULONG Pass_KiAttachProcess()
{
char *actual_function;
KIRQL oldIrql;
int i = 0;
unsigned char newcode[] = { 0xEA, 0x44, 0x33, 0x22, 0x11, 0x08,0x00};
actual_function = (char *)(KeStackAttachProcess_Addr-0x219);
KiAttachProcess_reentry_address = (KeStackAttachProcess_Addr-0x20c);
*( (unsigned long *)(&newcode[1]) ) = (unsigned long)my_function_detour_KiAttachProcess;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
KiAttachProcess_g_oricode[i] = actual_function[i];
actual_function[i] = newcode[i];
}
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_KiAttachProcess()
{
char *actual_function = (char *)(KeStackAttachProcess_Addr-0x219);
KIRQL oldIrql;
int i = 0;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
for(i=0;i < 7;i++)
{
actual_function[i] = KiAttachProcess_g_oricode[i];
}
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
ULONG OldNtReadVirtualMemoryAdd;
ULONG reentryadd_NtReadVirtualMemory;
__declspec(naked) NTSTATUS NewNtReadVirtualMemory()
{
__asm
{
push [esp+4]
call IsNPCalled
cmp eax,1
jnz NtReadVirtualMemory_ENT1
push 0x1c
push 0x804daef0
mov eax, 0x8053cbe0
call eax
jmp [reentryadd_NtReadVirtualMemory]
NtReadVirtualMemory_ENT1:
cmp eax,0
jnz NtReadVirtualMemory_ENT2
jmp [OldNtReadVirtualMemoryAdd]
NtReadVirtualMemory_ENT2:
mov eax,0
ret 0x14
}
}
//////////////////////////////////////////////////////////////////////////NtReadVirtualMemory
ULONG Pass_NtReadVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0xBA * 4; //得到NtReadVirtualMemory的服务地址
(ULONG)OldNtReadVirtualMemoryAdd = *(ULONG*)Address; //保存此地址
reentryadd_NtReadVirtualMemory=OldNtReadVirtualMemoryAdd+0xc;
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();
}
ULONG reentryadd_NtWriteVirtualMemory;
ULONG OldNtWriteVirtualMemoryAdd;
__declspec(naked) NTSTATUS NewNtWriteVirtualMemory()
{
__asm
{
push [esp+4]
call IsNPCalled
cmp eax,1
jnz NtWriteVirtualMemory_ENT1
push 0x1c
push 0x804daf08
mov eax, 0x8053cbe0
call eax
jmp [reentryadd_NtWriteVirtualMemory]
NtWriteVirtualMemory_ENT1:
cmp eax,0
jnz NtWriteVirtualMemory_ENT2
jmp [OldNtWriteVirtualMemoryAdd]
NtWriteVirtualMemory_ENT2:
mov eax,0
ret 0x14
}
}
//////////////////////////////////////////////////////////////////////////
ULONG Pass_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x115 * 4;
(ULONG)OldNtWriteVirtualMemoryAdd = *(ULONG*)Address;
reentryadd_NtWriteVirtualMemory=OldNtWriteVirtualMemoryAdd+0xc;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtWriteVirtualMemory; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtWriteVirtualMemory()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x115 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNtWriteVirtualMemoryAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////NtOpenProcess
ULONG OldNtProcessAdd;
ULONG reentryadd_NtWriteVirtualMemory;
NTSTATUS
_NtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
{
HANDLE Handle;
KPROCESSOR_MODE PreviousMode;
NTSTATUS Status;
PEPROCESS Process;
PETHREAD Thread;
CLIENT_ID CapturedCid={0};
BOOLEAN ObjectNamePresent;
BOOLEAN ClientIdPresent;
ACCESS_STATE AccessState;
AUX_ACCESS_DATA AuxData;
ULONG Attributes;
LUID SeDebugPrivilege = {0};
POBJECT_TYPE _PsProcessType;
PEPROCESS tempeprocess;
PsLookupProcessByProcessId(ClientId->UniqueProcess,&tempeprocess);
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
// ERROR_INVALID_PARAMETER
__try
{
// DbgPrint("dnf threadid %d KTHREAD %08x want openprocess %s\n",
// PsGetCurrentThreadId(),PsGetCurrentThread(),GetProcessNameFromEProc(tempeprocess));
if (!_stricmp("OllyDBG.EXE",GetProcessNameFromEProc(tempeprocess)) )
{
return STATUS_INVALID_PARAMETER;
}
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(tempeprocess)) )
{
// return STATUS_INVALID_PARAMETER;
}
if (!_stricmp("taskmgr.exe",GetProcessNameFromEProc(tempeprocess)) )
{
return STATUS_INVALID_PARAMETER;
}
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("GetExceptionCode %08x",GetExceptionCode());
// return GetExceptionCode();
}
return NtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes, ClientId);
}
// DbgPrint("%s want openprocess %s\n",GetProcessNameFromEProc(0),GetProcessNameFromEProc(tempeprocess));
(ULONG)_PsProcessType=*(ULONG*)PsProcessType;
PreviousMode = KeGetPreviousMode();
SeDebugPrivilege =RtlConvertLongToLuid(SE_DEBUG_PRIVILEGE);
if (PreviousMode != KernelMode) {
__try {
ProbeForWriteHandle (ProcessHandle);
ProbeForReadSmallStructure (ObjectAttributes,
sizeof(OBJECT_ATTRIBUTES),
sizeof(ULONG));
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, UserMode);
if (ARGUMENT_PRESENT (ClientId)) {
ProbeForReadSmallStructure (ClientId, sizeof (CLIENT_ID), sizeof (ULONG));
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
} else {
ObjectNamePresent = (BOOLEAN)ARGUMENT_PRESENT (ObjectAttributes->ObjectName);
Attributes = ObSanitizeHandleAttributes (ObjectAttributes->Attributes, KernelMode);
if (ARGUMENT_PRESENT (ClientId)) {
CapturedCid = *ClientId;
ClientIdPresent = TRUE;
} else {
ClientIdPresent = FALSE;
}
}
if (ObjectNamePresent && ClientIdPresent) {
return STATUS_INVALID_PARAMETER_MIX;
}
Status = SeCreateAccessState(
&AccessState,
&AuxData,
DesiredAccess,
&_PsProcessType->TypeInfo.GenericMapping
);
if ( !NT_SUCCESS(Status) ) {
return Status;
}
if (SeSinglePrivilegeCheck( SeDebugPrivilege, PreviousMode )) {
if ( AccessState.RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
AccessState.PreviouslyGrantedAccess |= PROCESS_ALL_ACCESS;
} else {
AccessState.PreviouslyGrantedAccess |= ( AccessState.RemainingDesiredAccess );
}
AccessState.RemainingDesiredAccess = 0;
}
if (ObjectNamePresent) {
Status = ObOpenObjectByName(
ObjectAttributes,
_PsProcessType,
PreviousMode,
&AccessState,
0,
NULL,
&Handle
);
SeDeleteAccessState( &AccessState );
if ( NT_SUCCESS(Status) ) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
if ( ClientIdPresent ) {
Thread = NULL;
if (CapturedCid.UniqueThread) {
Status = PsLookupProcessThreadByCid(
&CapturedCid,
&Process,
&Thread
);
if (!NT_SUCCESS(Status)) {
SeDeleteAccessState( &AccessState );
return Status;
}
} else {
Status = PsLookupProcessByProcessId(
CapturedCid.UniqueProcess,
&Process
);
if ( !NT_SUCCESS(Status) ) {
SeDeleteAccessState( &AccessState );
return Status;
}
}
//
// OpenObjectByAddress
//
Status = ObOpenObjectByPointer(
Process,
Attributes,
&AccessState,
0,
_PsProcessType,
PreviousMode,
&Handle
);
SeDeleteAccessState( &AccessState );
if (Thread) {
ObDereferenceObject(Thread);
}
ObDereferenceObject(Process);
if (NT_SUCCESS (Status)) {
__try {
*ProcessHandle = Handle;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode ();
}
}
return Status;
}
return STATUS_INVALID_PARAMETER_MIX;
}
ULONG Pass_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
OldNtProcessAdd = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)_NtOpenProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 0x7A * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = OldNtProcessAdd; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
void Init_fun()
{
KeStackAttachProcess_Addr=GetFunctionAddr(L"KeStackAttachProcess");
Init_KiMoveApcState();
}
//////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////
#define SYSTEMSERVICE(Index) *(PULONG)((ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase+ Index*4);
ULONG DbgkForwardExceptionAddr = 0;
ULONG KiDispatchExceptionAddr = 0;
ULONG DbgkpQueueMessageAddr = 0;
ULONG SearchMutex()
{
ULONG NtResumeThreadAddr = 0;
ULONG NtRaiseExceptionAddr = 0;
ULONG KiRaiseExceptionAddr = 0;
ULONG DbgkpSendApiMessageAddr = 0;
ULONG DbgkpProcessDebugPortMutex =0;
ULONG PsResumeThreadAddr =0;
DWORD dwKey;
ULONG i;
NtResumeThreadAddr = SYSTEMSERVICE(206);
DbgPrint("NtResumeThreadAddr : %X\n", NtResumeThreadAddr);
for(i = NtResumeThreadAddr; i < NtResumeThreadAddr + 0x7C; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8E475FF)
{
dwKey = i + 4;
PsResumeThreadAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("PsResumeThreadAddr : %X\n", PsResumeThreadAddr);
NtRaiseExceptionAddr = SYSTEMSERVICE(181);
DbgPrint("NtRaiseExceptionAddr : %X\n", NtRaiseExceptionAddr);
for(i = NtRaiseExceptionAddr; i < NtRaiseExceptionAddr + 0x30; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8505100)
{
dwKey = i + 4;
KiRaiseExceptionAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("KiRaiseExceptionAddr : %X\n", KiRaiseExceptionAddr);
if (KiRaiseExceptionAddr > 0x80000000)
{
for(i = KiRaiseExceptionAddr; i < KiRaiseExceptionAddr + 0x197; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE853FFFF)
{
dwKey = i + 4;
KiDispatchExceptionAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("KiDispatchExceptionAddr : %X\n", KiDispatchExceptionAddr);
}
if (KiDispatchExceptionAddr > 0x80000000)
{
for(i = KiDispatchExceptionAddr; i < KiDispatchExceptionAddr + 0x397; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8565701)
{
dwKey = i + 4;
DbgkForwardExceptionAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("DbgkForwardExceptionAddr : %X\n", DbgkForwardExceptionAddr);
}
if (DbgkForwardExceptionAddr > 0x80000000)
{
for(i = DbgkForwardExceptionAddr; i < DbgkForwardExceptionAddr + 0x8A; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8508845)
{
dwKey = i + 4;
DbgkpSendApiMessageAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("DbgkpSendApiMessageAddr : %X\n", DbgkpSendApiMessageAddr);
}
if (DbgkpSendApiMessageAddr > 0x80000000)
{
for(i = DbgkpSendApiMessageAddr; i < DbgkpSendApiMessageAddr + 0x55; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xE8515052)
{
dwKey = i + 4;
DbgkpQueueMessageAddr = i + *(ULONG*)dwKey + 8;
}
}
}
DbgPrint("DbgkpQueueMessageAddr : %X\n", DbgkpQueueMessageAddr);
}
if (DbgkpQueueMessageAddr > 0x80000000)
{
for(i = DbgkpQueueMessageAddr; i < DbgkpQueueMessageAddr + 0x16F; i++)
{
dwKey = *(PDWORD)i;
if (MmIsAddressValid(&dwKey))
{
if (dwKey == 0xB93075FC)
{
dwKey = i + 4;
DbgkpProcessDebugPortMutex = *(ULONG*)dwKey;
}
}
}
DbgPrint("DbgkpProcessDebugPortMutex : %X\n", DbgkpProcessDebugPortMutex);
}
return DbgkpProcessDebugPortMutex;
}
//////////////////////////////////////////////////////////////////////////
ULONG Pass_debugport()
{
KIRQL oldIrql;
char timestr[]={0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90};
char* g_KiDispatchException=(char*)(KiDispatchExceptionAddr+0x187);
char* g_PspCreateProcess=(char*)(KiDispatchExceptionAddr+0xD2599);
char* g_DbgkForwardException=(char*)(DbgkForwardExceptionAddr+0x3e);
char* g_DbgkpQueueMessage=(char*)(DbgkpQueueMessageAddr+0x7B);
char* g_DbgkCreateThread=(char*)(KiDispatchExceptionAddr+0x14515F);
char* g_DbgkExitThread=(char*)(KiDispatchExceptionAddr+0x1453F8);
char* g_DbgkMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x14550B);
char* g_DbgkExitProcess=(char*)(KiDispatchExceptionAddr+0x145472);
char* g_DbgkUnMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x1455D1);
char* g_PspExitThread=(char*)(KiDispatchExceptionAddr+0xD3E84);
char* g_DbgkpMarkProcessPeb=(char*)(KiDispatchExceptionAddr+0x1438EA);
char* g_MmCreatePeb=(char*)(KiDispatchExceptionAddr+0xB1907);
char* g_DbgkpSetProcessDebugObject=(char*)(KiDispatchExceptionAddr+0x144934);
char* g_DbgkpSetProcessDebugObject1=(char*)(KiDispatchExceptionAddr+0x144942);
char* g_DbgkpSetProcessDebugObject2=(char*)(KiDispatchExceptionAddr+0x14495C);
char* g_DbgkpSetProcessDebugObject3=(char*)(KiDispatchExceptionAddr+0x1449A6);
char* g_DbgkpSetProcessDebugObject4=(char*)(KiDispatchExceptionAddr+0x1449E8);
//nop
char* anti_DbgkExitThread=(char*)(KiDispatchExceptionAddr+0x1453F6);
char* anti_DbgkExitProcess=(char*)(KiDispatchExceptionAddr+0x145470);
char* anti_DbgkUnMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x1455CF);
//jmp
char* anti_DbgkMapViewOfSection=(char*)(KiDispatchExceptionAddr+0x145505);
char* anti_DbgkForwardException=(char*)(DbgkForwardExceptionAddr+0x38);
//nop create time
char* g_PspCreateProcess_time=(char*)(KiDispatchExceptionAddr+0xD2B15);
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
memcpy(g_PspCreateProcess_time,timestr,9);
*(ULONG*)(&g_KiDispatchException[2])=0x70;
*(ULONG*)(&g_PspCreateProcess[2])=0x70;
*(ULONG*)(&g_DbgkForwardException[2])=0x70;
*(ULONG*)(&g_DbgkpQueueMessage[2])=0x70;
*(ULONG*)(&g_DbgkCreateThread[2])=0x70;
*(ULONG*)(&g_DbgkExitThread[2])=0x70;
*(ULONG*)(&g_DbgkMapViewOfSection[2])=0x70;
*(ULONG*)(&g_DbgkExitProcess[2])=0x70;
*(ULONG*)(&g_DbgkUnMapViewOfSection[2])=0x70;
*(ULONG*)(&g_PspExitThread[2])=0x70;
*(ULONG*)(&g_DbgkpMarkProcessPeb[2])=0x70;
*(ULONG*)(&g_MmCreatePeb[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject1[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject2[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject3[2])=0x70;
*(ULONG*)(&g_DbgkpSetProcessDebugObject4[2])=0x70;
//
// anti_DbgkExitThread[0]=0x90;
// anti_DbgkExitThread[1]=0x90;
// anti_DbgkExitProcess[0]=0x90;
// anti_DbgkExitProcess[1]=0x90;
// anti_DbgkUnMapViewOfSection[0]=0x90;
// anti_DbgkUnMapViewOfSection[1]=0x90;
//
// anti_DbgkMapViewOfSection[0]=0xeb;
// anti_DbgkForwardException[0]=0xeb;
KeLowerIrql(oldIrql);
WPON();
return STATUS_SUCCESS;
}
const int process_list_offset=0x88;
const int createtime_list_offset=0x70;
ULONG FindProcess()
{
ULONG cproc=0x00000000;
ULONG i=0;
ULONG TPID;
PEPROCESS tmpeprocess;
PLIST_ENTRY plist_active_procs;
LARGE_INTEGER temptime;
temptime.QuadPart=0;
PsLookupProcessByProcessId((HANDLE)4,&tmpeprocess);
cproc=(ULONG)tmpeprocess;
while (1)
{
if ((i>=1) && ((ULONG)tmpeprocess==cproc))
{
break;
return 0x00000000;
}
else
{
plist_active_procs=(LIST_ENTRY*)(cproc+process_list_offset);
cproc=(ULONG)plist_active_procs->Flink;
cproc=cproc-process_list_offset;
*(LARGE_INTEGER*)(cproc+createtime_list_offset)=temptime;
i++;
}
}
return 1;
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS (*NTQUERYINFORMATIONPROCESS)(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
NTQUERYINFORMATIONPROCESS OldNQueryInformationProcessAddr;
typedef struct _PROCESS_DEBUG_PORT_INFO
{
HANDLE DebugPort;
} PROCESS_DEBUG_PORT_INFO;
//enum SYSTEM_INFORMATION_CLASS { SystemKernelDebuggerInformation = 35 };
//enum THREAD_INFO_CLASS { ThreadHideFromDebugger = 17 };
//enum PROCESS_INFO_CLASS { ProcessDebugPort = 7 };
NTSTATUS NewNtQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out PROCESS_DEBUG_PORT_INFO* ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
)
{
// PROCESS_DEBUG_PORT_INFO* tempPi;
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)) ||
!_stricmp("AION.bin",GetProcessNameFromEProc(0)) ||
!_stricmp("GameMon.des",GetProcessNameFromEProc(0)))
{
if (ProcessInformationClass==7)
{
DbgPrint("%s NtQueryInformationProcess debugport!\n",GetProcessNameFromEProc(0));
ProcessInformation->DebugPort=0;
return 0;
}
}
// DbgPrint("%s NtQueryInformationProcess !\n",GetProcessNameFromEProc(0));
return OldNQueryInformationProcessAddr(ProcessHandle,ProcessInformationClass,ProcessInformation,ProcessInformationLength,ReturnLength);
}
ULONG Pass_NtQueryInformationProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 154 * 4;
(ULONG)OldNQueryInformationProcessAddr = *(ULONG*)Address;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)NewNtQueryInformationProcess; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_NtQueryInformationProcess()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 154 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldNQueryInformationProcessAddr; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
// NTSTATUS __declspec(naked) _PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
// {
//
// }
//////////////////////////////////////////////////////////////////////////
//unsigned long PsSuspendThread_reentry_address;
ULONG pssuspendthreadaddr;
NTSTATUS __declspec(naked) _PsSuspendThread(PETHREAD Thread, PULONG PreviousSuspendCount)
{
__asm
{
push 0x18
push 0x804db9e8
mov esi,0x8053cbe0
call esi
mov esi,pssuspendthreadaddr
add esi,0xc
jmp esi
}
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS
_NtSuspendThread(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
)
{
PETHREAD Thread;
NTSTATUS st;
ULONG LocalPreviousSuspendCount;
KPROCESSOR_MODE Mode;
POBJECT_TYPE TempType;
// PAGED_CODE();
Mode = KeGetPreviousMode ();
try {
if (Mode != KernelMode) {
if (ARGUMENT_PRESENT (PreviousSuspendCount)) {
ProbeForWriteUlong (PreviousSuspendCount);
}
}
} except (EXCEPTION_EXECUTE_HANDLER) {
return GetExceptionCode();
}
(ULONG)TempType=*(ULONG*)PsThreadType;
st = ObReferenceObjectByHandle (ThreadHandle,
THREAD_SUSPEND_RESUME,
TempType,
Mode,
&Thread,
NULL);
if (!NT_SUCCESS (st)) {
return st;
}
st = _PsSuspendThread (Thread, &LocalPreviousSuspendCount);
ObDereferenceObject (Thread);
try {
if (ARGUMENT_PRESENT (PreviousSuspendCount)) {
*PreviousSuspendCount = LocalPreviousSuspendCount;
}
} except (EXCEPTION_EXECUTE_HANDLER) {
st = GetExceptionCode ();
}
return st;
}
//////////////////////////////////////////////////////////////////////////
typedef NTSTATUS(*NTSUSPENDTHREAD)(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
);
NTSUSPENDTHREAD OldSuspendThreadAddr;
NTSTATUS MyNtSuspendThread(
__in HANDLE ThreadHandle,
__out_opt PULONG PreviousSuspendCount
)
{
if (!_stricmp("DNF.exe",GetProcessNameFromEProc(0)))
{
return OldSuspendThreadAddr(ThreadHandle,PreviousSuspendCount);
}
return _NtSuspendThread(ThreadHandle,PreviousSuspendCount);
}
ULONG Pass_PsSuspendThread()
{
KIRQL oldIrql;
ULONG Address=0;
LONG temp=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 254 * 4;
(ULONG)OldSuspendThreadAddr = *(ULONG*)Address;
temp=*(LONG*)((LONG)OldSuspendThreadAddr+0x65);
pssuspendthreadaddr=(LONG)OldSuspendThreadAddr+0x64+temp+5;
DbgPrint("pssuspendthreadaddr %08x\n",pssuspendthreadaddr);
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)MyNtSuspendThread; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
return 1;
}
VOID UnDetour_PsSuspendThread()
{
KIRQL oldIrql;
ULONG Address=0;
Address = (ULONG)_KeServiceDescriptorTable->NotUse1.ServiceTableBase + 254 * 4;
WPOFF();
oldIrql = KeRaiseIrqlToDpcLevel();
*((ULONG*)Address) = (ULONG)OldSuspendThreadAddr; //HOOK SSDT
KeLowerIrql(oldIrql);
WPON();
}
//////////////////////////////////////////////////////////////////////////
NTSTATUS
MyNtGetContextThread(
__in HANDLE ThreadHandle,
__inout PCONTEXT ThreadContext
)
{
KPROCESSOR_MODE Mode;
NTSTATUS Status;
PETHREAD Thread;
PKTHREAD CurrentThread;
POBJECT_TYPE TempType;
// PAGED_CODE();
//
// Get previous mode and reference specified thread.
//
CurrentThread = KeGetCurrentThread();
Mode = *(CCHAR*)((ULONG)CurrentThread+0x140);
(ULONG)TempType=*(ULONG*)PsThreadType;
Status = ObReferenceObjectByHandle (ThreadHandle,
THREAD_GET_CONTEXT,
TempType,
Mode,
&Thread,
NULL);
//
// If the reference was successful, the check if the specified thread
// is a system thread.
//
if (NT_SUCCESS (Status)) {
//
// If t
上一篇: BloomFilter过滤器过滤算法的简单实现(学习笔记)
下一篇: 网络层——IP报文头介绍