传说修改cr0寄存器后再写SSDT在多核CPU不稳定,因此提供一个更加稳定的写SSDT表的方式,代码如下
//
// 挂钩函数
//
BOOL HookSSDT()
...{
PMDL pMdlSystemCall = NULL;
DWORD * MappedSystemCallTable = 0;
pMdlSystemCall = IoAllocateMdl(
KeServiceDescriptorTable->ntoskrnl.ServiceTable,
KeServiceDescriptorTable->ntoskrnl.CounterTable*4,
0,
0,
NULL
);
if(!pMdlSystemCall)
return FALSE;
MmBuildMdlForNonPagedPool(pMdlSystemCall);
MappedSystemCallTable=(DWORD *)MmMapLockedPages(pMdlSystemCall, KernelMode);
// HOOK NtRestoreKey 的例子
HOOK_SYSCALL(
ZwRestoreKey,
HookedNtRestoreKey,
RealNtRestoreKey,
NT_RESTORE_KEY,
MappedSystemCallTable
);
IoFreeMdl(pMdlSystemCall);
return TRUE;
}
//
// 卸载挂钩函数
//
BOOL UnhookSSDT()
...{
PMDL pMdlSystemCall = NULL;
DWORD * MappedSystemCallTable = NULL;
pMdlSystemCall = IoAllocateMdl(
KeServiceDescriptorTable->ntoskrnl.ServiceTable,
KeServiceDescriptorTable->ntoskrnl.CounterTable*4,
0,
0,
NULL
);
if(!pMdlSystemCall)
return FALSE;
MmBuildMdlForNonPagedPool(pMdlSystemCall);
MappedSystemCallTable = (DWORD *)MmMapLockedPages(pMdlSystemCall, KernelMode);
// UnHOOK NtRestoreKey 的例子
UNHOOK_SYSCALL(
ZwRestoreKey,
RealNtRestoreKey,
MappedSystemCallTable
);
IoFreeMdl(pMdlSystemCall);
return TRUE;
}
//
// HOOK NtRestoreKey 的例子
//
NTSTATUS
HookedNtRestoreKey(
IN HANDLE KeyHandle,
IN HANDLE FileHandle,
IN ULONG RestoreOption
)
...{
return RealNtRestoreKey(
KeyHandle,
FileHandle,
RestoreOption
);
}
// 挂钩函数
//
BOOL HookSSDT()
...{
PMDL pMdlSystemCall = NULL;
DWORD * MappedSystemCallTable = 0;
pMdlSystemCall = IoAllocateMdl(
KeServiceDescriptorTable->ntoskrnl.ServiceTable,
KeServiceDescriptorTable->ntoskrnl.CounterTable*4,
0,
0,
NULL
);
if(!pMdlSystemCall)
return FALSE;
MmBuildMdlForNonPagedPool(pMdlSystemCall);
MappedSystemCallTable=(DWORD *)MmMapLockedPages(pMdlSystemCall, KernelMode);
// HOOK NtRestoreKey 的例子
HOOK_SYSCALL(
ZwRestoreKey,
HookedNtRestoreKey,
RealNtRestoreKey,
NT_RESTORE_KEY,
MappedSystemCallTable
);
IoFreeMdl(pMdlSystemCall);
return TRUE;
}
//
// 卸载挂钩函数
//
BOOL UnhookSSDT()
...{
PMDL pMdlSystemCall = NULL;
DWORD * MappedSystemCallTable = NULL;
pMdlSystemCall = IoAllocateMdl(
KeServiceDescriptorTable->ntoskrnl.ServiceTable,
KeServiceDescriptorTable->ntoskrnl.CounterTable*4,
0,
0,
NULL
);
if(!pMdlSystemCall)
return FALSE;
MmBuildMdlForNonPagedPool(pMdlSystemCall);
MappedSystemCallTable = (DWORD *)MmMapLockedPages(pMdlSystemCall, KernelMode);
// UnHOOK NtRestoreKey 的例子
UNHOOK_SYSCALL(
ZwRestoreKey,
RealNtRestoreKey,
MappedSystemCallTable
);
IoFreeMdl(pMdlSystemCall);
return TRUE;
}
//
// HOOK NtRestoreKey 的例子
//
NTSTATUS
HookedNtRestoreKey(
IN HANDLE KeyHandle,
IN HANDLE FileHandle,
IN ULONG RestoreOption
)
...{
return RealNtRestoreKey(
KeyHandle,
FileHandle,
RestoreOption
);
}
其中HOOK_SYSCALL UNHOOK_SYSCALL SYSCALL_INDEX的定义:
//
// 获得被hook的函数在ssdt中的索引值
// _Function为该函数的Zw*形式
//
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
//
// 实现hook的宏
// _Function : Zw*形式的函数
// _Hook : 自己构造的函数的地址
// _Orig : 原始的函数地址
// _OrigType : 原始函数的类型
// _MappedSystemCallTable : SSDT的地址
//
#define HOOK_SYSCALL(_Function, _Hook, _Orig, _OrigType, _MappedSystemCallTable)
_Orig = (_OrigType) InterlockedExchange( (PLONG) &_MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Hook)
//
// 实现unhook的宏
// _Function : Zw*形式的函数
// _Orig : 原始的函数地址
// _MappedSystemCallTable : SSDT的地址
//
#define UNHOOK_SYSCALL(_Function, _Orig, _MappedSystemCallTable)
InterlockedExchange( (PLONG) &_MappedSystemCallTable[SYSCALL_INDEX(_Function)], (LONG) _Orig)