/************************************/
//简单实现隐藏SSDT HOOK By ZzAge
/************************************/
#include <ntddk.h>
#define BYTE unsigned char
#define MEM_TAG 'ZMEM'
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
VOID Unload(
IN PDRIVER_OBJECT DriverObject
)
typedef NTSTATUS (*NTOPENPROCESS)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
)
NTSTATUS PsLookupProcessByProcessId(
IN HANDLE ProcessId,
OUT PEPROCESS *Process
)
PUCHAR PsGetProcessImageFileName(
IN PEPROCESS Process
)
#ifdef ALLOC_PRAGMA
#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(PAGE, Unload)
#endif
NTOPENPROCESS OldNtOpenProcess
BYTE JmpCode[5]={0xE9,0x00,0x00,0x00,0x00}
BYTE OrgCode[5]={0x8B,0x3F,0x8B,0x1C,0x87}
BYTE PushRetCode[6]={0x68,0x00,0x00,0x00,0x00,0xc3}
ULONG uKiFastCallEntryAddr=0
ULONG HookAddr=0
ULONG JMPRet=0
ULONG PushRetMem=0
//NtOpenProcess代理函数
NTSTATUS MyNtOpenProcess(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMase,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId
)
{
PEPROCESS lpPEPROCESS
NTSTATUS status
char *ProcessName
//取要打开目标进程的PEPROCESS
status=PsLookupProcessByProcessId(ClientId->UniqueProcess,&lpPEPROCESS)
if (NT_SUCCESS(status))
{
if (KeGetCurrentIrql()==PASSIVE_LEVEL)
{
ProcessName=_strupr(PsGetProcessImageFileName(lpPEPROCESS))
if (strcmp(ProcessName,"NOTEPAD.EXE")==0) //判断打开的进程是否为NOTEPAD.EXE
{
return STATUS_ACCESS_DENIED
}
}
}
return OldNtOpenProcess(ProcessHandle,AccessMase,ObjectAttributes,ClientId)
}
//HOOK KiFastCallEntry过滤函数
__declspec(naked)void OverFuck()
{
_asm
{
pushfd
pushad
mov edi,dword ptr [edi]
mov ebx,dword ptr [edi+eax*4]
cmp OldNtOpenProcess,ebx
je Label1
popad
popfd
mov edi,dword ptr [edi]
mov ebx,dword ptr [edi+eax*4]
jmp [JMPRet]
Label1:
popad
popfd
mov ebx,MyNtOpenProcess //修改NtOpenProcess为我们的代理函数
jmp [JMPRet]
}
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_SUCCESS
KIRQL oldIrql
UNICODE_STRING ustrFunctionName
DbgPrint("[HideSSDT] DriverEntry!\n")
//卸载例程
DriverObject->DriverUnload = Unload
//获取NtOpenProcess地址
RtlInitUnicodeString(&ustrFunctionName, L"NtOpenProcess" )
OldNtOpenProcess=(NTOPENPROCESS)MmGetSystemRoutineAddress( &ustrFunctionName)
DbgPrint("NtOpenProcess=0x%08X",OldNtOpenProcess)
//系统调用管理器的地址保存在MSR寄存器里面,标识ID为0x176是SYSENTER_EIP_MSR寄存器,存放着KiFastCallEntry地址!所以在这里用rdmsr读取KiFastCallEntry地址;
__asm
{
pushfd
pushad
mov ecx,0x176
rdmsr
mov uKiFastCallEntryAddr,eax //获取KiFastCallEntry地址
xor ecx,ecx
Label1:
cmp ecx,0x100
je Label3
mov edx,DWORD ptr [eax]
cmp edx,0x1C8B3F8B //搜索特征码,获取要Hook的位置
je Label2
inc eax
inc ecx
jmp Label1
Label2:
mov HookAddr,eax
Label3:
popad
popfd
}
if (HookAddr==0)
{
return status
}
//申请分配二级跳转内存
PushRetMem=(ULONG)ExAllocatePoolWithTag(NonPagedPool,6,MEM_TAG)
if ((PVOID)PushRetMem==NULL)
{
return status
}
DbgPrint("PushRetMem=0x%08X",PushRetMem)
//一级跳转地址
*(ULONG*)&JmpCode[1]=(ULONG)(PushRetMem)-(HookAddr+5)
//二级跳转地址
*(ULONG*)&PushRetCode[1]=(ULONG)OverFuck
//HOOK返回地址
JMPRet=HookAddr+5
//提升中断请求级
oldIrql = KeRaiseIrqlToDpcLevel()
//关闭中断
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
//进行HOOK操作
RtlCopyMemory((PVOID)PushRetMem,PushRetCode,6)
RtlCopyMemory((PVOID)HookAddr,JmpCode,5)
//开启中断
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
//恢复先前中断请求级
KeLowerIrql(oldIrql)
DbgPrint("KiFastCallEntry=0x%08X",uKiFastCallEntryAddr)
DbgPrint("HookAddr=0x%08X",HookAddr)
//添加代码
return status
}
VOID Unload( IN PDRIVER_OBJECT DriverObject)
{
if (HookAddr!=0)
{
KIRQL oldIrql
//提升中断请求级
oldIrql = KeRaiseIrqlToDpcLevel()
//关闭中断
_asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
//进行还原HOOK操作
RtlCopyMemory((PVOID)HookAddr,OrgCode,5)
_asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
//恢复先前中断请求级
KeLowerIrql(oldIrql)
// 释放内存
ExFreePool((PVOID)PushRetMem)
}
DbgPrint("[HideSSDT] Unloaded\n")
}