运行效果

先简单说一下SSDT HOOK。应用程序的API在使用的时候要调用系统的低层的API
那么系统如何找到对应的API呢?在系统里有一张表。
System Services Descriptor Table,系统服务描述符表。
在这个表里就有各种系统API的地址,我们只要把这些地址改成我们自己函数的地址。
那么结果大家可想而知了,系统就会调用我们的API了。道理就是这么简单。当然实现
起来也很简单。
说一下步骤
首先我们要定义一个SSDT的结构代码如下
typedef struct ServiceDescriptorEntry
{
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} SSDTEntry;
__declspec(dllimport) SSDTEntry KeServiceDescriptorTable;
然后我们要定义一个自己的API函数,这个函数根据你要HOOK的API来
NTKERNELAPI NTSTATUS ZwTerminateProcess(IN HANDLE ProcessHandle OPTIONAL, IN NTSTATUS
ExitStatus);
当然还要一个结构来保存要HOOK的API。为什么要保存,当然是为了恢复。:)他的结构如下
typedef NTSTATUS(*_ZwTerminateProcess)(IN HANDLE ProcessHandle OPTIONAL,IN NTSTATUS
ExitStatus);
_ZwTerminateProcess Old_ZwTerminateProcess;
好了,下面我们要开始把SSDT里的API替换成我们的了。替换之前先把原先的API保存下。代码如下
//找出旧函数地址并保存
Old_ZwTerminateProcess =(_ZwTerminateProcess)(GetSystemFunc(ZwTerminateProcess));
#define GetSystemFunc(FuncName) KeServiceDescriptorTable.ServiceTableBase[*(PULONG)
((PUCHAR)FuncName+1)]
然后我们要改写了。当然系统不会那么随便就让我们来改写这个地址。它是受保护的只能读不能写。
那么我们怎么办呢?创建一个MDL来解决。代码如下
//设置内存为可写
MDSystemCall = MmCreateMdl(NULL, KeServiceDescriptorTable.ServiceTableBase,
KeServiceDescriptorTable.NumberOfServices*4);
if(!MDSystemCall)
return STATUS_UNSUCCESSFUL;
MmBuildMdlForNonPagedPool(MDSystemCall);
MDSystemCall->MdlFlags = MDSystemCall->MdlFlags | MDL_MAPPED_TO_SYSTEM_VA;
MappedSCT = MmMapLockedPages(MDSystemCall, KernelMode);
已经可以修改了那么我们要修改了。代码如下
HookOn( ZwTerminateProcess, NewZwTerminateProcess);
#define HookOn(_Old, _New) \
(PVOID) InterlockedExchange( (PLONG) &MappedSCT[GetIndex(_Old)], (LONG) _New)
这样就把地址修改成我们的了,下面怎么处理自己看着办好了。我这里是仿止结束。
//通过ProcessHandle来获得当前要结束的进程的EPROCESS
if (ObReferenceObjectByHandle
(ProcessHandle,GENERIC_READ,NULL,KernelMode,&SJMPROCESS,0) == STATUS_SUCCESS)
{
//如果要结束的是我们需要保护的进程,这里分两种情况
if (ZHUPROCESS== SJMPROCESS)
{
if (ZHUPROCESS != PsGetCurrentProcess())
{//情况一:当前进程不是我们所保护的进程
//换句话说也就是其他进程试图结束我们所保护的进程,当然不能
让他结束
nStatus = STATUS_ACCESS_DENIED;
}
}
}
用完了当然要把它恢复,恢复代码如下
//卸载Hook
UnHook( ZwTerminateProcess, Old_ZwTerminateProcess);
#define UnHook(_Old, _New) \
InterlockedExchange( (PLONG) &MappedSCT[GetIndex(_Old)], (LONG) _New)
差点忘了 MDL也要恢复 呵呵 恢复代码如下
//解锁、释放MDL
if(MDSystemCall)
{
MmUnmapLockedPages(MappedSCT, MDSystemCall);
IoFreeMdl(MDSystemCall);
}
至此大致过程已经完了。