近期学习了一下HOOK SSDT,通过HOOK ZwTerminateProcess来实现的编了一个小程序实现简单的禁止结束进程,主要代码如下:
NTSTATUS HookZwTerminateProcess(IN HANDLE ProcessHandle OPTIONAL,
IN NTSTATUS ExitStatus)
{
ULONG pid = 0;
NTSTATUS status = 0;
NTSTATUS rc = 0;
PEPROCESS EProcess;
LPTSTR lpCurProc;
if(ProcessHandle != NULL)
{
//调用ZwQueryInformationProcess得到PID
ULONG Rlen;
PVOID pBuffer;
PROCESS_BASIC_INFORMATION *pbi;
pBuffer = ExAllocatePoolWithTag(PagedPool, sizeof(PROCESS_BASIC_INFORMATION),0x123456);
status = ZwQueryInformationProcess(ProcessHandle,
ProcessBasicInformation,
pBuffer,
sizeof(PROCESS_BASIC_INFORMATION),
&Rlen);
if(!NT_SUCCESS(status))
{
ExFreePool(pBuffer);//释放分配的内存
DbgPrint("ZwQueryInformationProcess() wrong!/n");
//return -1;
rc = (NTSTATUS)(REALZwTerminateProcess)RealZwTerminateProcess(ProcessHandle,ExitStatus);
return rc;
}
pbi = (struct _PROCESS_BASIC_INFORMATION *)pBuffer;
DbgPrint("ProcessHandle代表进程%d!",pbi->UniqueProcessId);
pid = (ULONG)pbi->UniqueProcessId;
ExFreePool(pBuffer);//释放分配的内存
//调用PsLoopupProcessByProcessId得到进程名
status = PsLookupProcessByProcessId(pid,&EProcess);
if(!NT_SUCCESS(status))
{
DbgPrint("PsLookupProcessByProcessId() wrong/n");
//return -1;
rc = (NTSTATUS)(REALZwTerminateProcess)RealZwTerminateProcess(ProcessHandle,ExitStatus);
return rc;
}
lpCurProc = (LPTSTR)EProcess;
lpCurProc = lpCurProc + myoffset;//myoffset为偏移地址,指向进程的名称,最多16字节
DbgPrint("PROCESSNAME=%s",lpCurProc);
//做出判断,是否禁止结束进程,我以notepad.exe为例
if(memicmp((void *)protectpname,(void *)lpCurProc,11) == 0)
{
return STATUS_UNSUCCESSFUL;
}
}
rc = (NTSTATUS)(REALZwTerminateProcess)RealZwTerminateProcess(ProcessHandle,ExitStatus);
return rc;
}
遗留问题:
1、直接点击一个记事本文件的关闭按钮,会造成该notepad.exe进程占用很大的CPU时间,CPU使用率一直是100%。
2、仅适用于进程名少于16个字节的情况。