#include <ntddk.h>
#include <windef.h>
#include <stdlib.h>
typedef struct _ServiceDescriptorTable {
PVOID ServiceTableBase; //System Service Dispatch Table 的基地址
PVOID ServiceCounterTable; //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。
unsigned int NumberOfServices; //由 ServiceTableBase 描述的服务的数目。
PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表
}*PServiceDescriptorTable;
extern "C" PServiceDescriptorTable KeServiceDescriptorTable;
VOID UnHOOKNtOpenProcess();
ULONG Old_NtOpProAddress;
ULONG New_NtOpProAddress;
ULONG Address_KiFastCallEntry;
ULONG OldJmpKeFastCallEntry;
typedef NTSTATUS (*NTOPENPROCESS)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
);
VOID OutPut()
{
DbgPrint("Success\n");
}
VOID UnHookKiFastCallEntry()
{
// 2B E1 C1 E9 02
UCHAR HookKiFastMyAddress[5] = {0x2B,0xE1,0xC1,0xE9,0x02};
_asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
RtlCopyMemory((PVOID)(OldJmpKeFastCallEntry-5),HookKiFastMyAddress,5);
_asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
_declspec(naked)VOID MyKiFaseCallEntry()
{
_asm
{
pushad //一定要保存这个
pushfd
call OutPut
popfd
popad
sub esp,ecx
shr ecx,2
jmp OldJmpKeFastCallEntry
}
}
VOID HOOKMYKIFASTCALLENTRY(ULONG Address)
{
ULONG HOOKFUNTIONADDRESS = (ULONG)MyKiFaseCallEntry;
UCHAR HOOKADDRESS[5] = {0xe9,0,0,0,0};
ULONG NTHOOKADDRESS_KIFASTCALLENTRY = HOOKFUNTIONADDRESS - Address - 5;
*(ULONG*)&HOOKADDRESS[1] = NTHOOKADDRESS_KIFASTCALLENTRY;
OldJmpKeFastCallEntry = (Address+5);
_asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
RtlCopyMemory((PVOID)Address,HOOKADDRESS,5);
_asm
{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
ULONG HookKiFastCallEntry(ULONG KiFastCallEntryAddress)
{
KiFastCallEntryAddress-=50;
BYTE* P;
for (ULONG i=0;i<50;i++)
{
// 2B E1 C1 E9 02
P = (BYTE*)(KiFastCallEntryAddress+i);
if (*P==0x2b && *(P+1)== 0xe1 && *(P+2)==0xc1 && *(P+3)== 0xE9 && *(P+4)==0x02)
{
//============================================
DbgPrint("OldJmpKeFastCallEntry:%X\n",P);
UnHOOKNtOpenProcess();
//============================================
return (ULONG)P;
break;
}
}
return 0;
}
NTSTATUS MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
)
{
//获取调用 KiFastCallEntry 中代码的地址
_asm
{
pushfd
mov eax,[ebp+4]
mov Address_KiFastCallEntry,eax
popfd
}
ULONG Address = HookKiFastCallEntry(Address_KiFastCallEntry);
if (Address != 0)
{
HOOKMYKIFASTCALLENTRY(Address);
}
return ((NTOPENPROCESS)Old_NtOpProAddress)(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);
}
VOID HOOKNtOpenProcess()
{
_asm
{
push ebx
push eax
push ecx
mov ebx,122
mov eax,KeServiceDescriptorTable
mov eax,[eax]
mov ecx,[eax+ebx*4]
mov Old_NtOpProAddress,ecx
pop ecx
pop eax
pop ebx
}
New_NtOpProAddress = (ULONG)MyNtOpenProcess;
_asm //关闭保护
{
cli
mov eax,CR0
and eax,not 10000h
mov CR0,eax
}
_asm
{
push ebx
push eax
push ecx
mov ebx,122
mov eax,KeServiceDescriptorTable
mov eax,[eax]
mov ecx,MyNtOpenProcess
mov [eax+ebx*4],ecx
pop ecx
pop eax
pop ebx
}
_asm //开启保护
{
mov eax,CR0
or eax,10000h
mov CR0,eax
sti
}
}
VOID UnHOOKNtOpenProcess()
{
_asm //关闭保护
{
cli
mov eax,CR0
and eax,not 10000h
mov CR0,eax
}
_asm
{
push ebx
push eax
push ecx
mov ebx,122
mov eax,KeServiceDescriptorTable
mov eax,[eax]
mov ecx,Old_NtOpProAddress
mov [eax+ebx*4],ecx
pop ecx
pop eax
pop ebx
}
_asm //开启保护
{
mov eax,CR0
or eax,10000h
mov CR0,eax
sti
}
}
VOID DriverUnload(PDRIVER_OBJECT pDriverObj)
{
UnHookKiFastCallEntry();
DbgPrint("++++驱动卸载++++\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegistryString)
{
pDriverObj->DriverUnload = DriverUnload;
DbgPrint("++++驱动加载++++\n");
HOOKNtOpenProcess();
return STATUS_SUCCESS;
}