原理
Attach 到进程进行内存清零.这里提供了两种方法.原理是一样
KeAttachProcess方法 与 KeStackAttachProcess方法. 其中第一种属于旧方法了.根据MSDN所说API已经升级为了KeStackAttachProcess
#include <ntifs.h>
NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process); //未公开的进行导出即可
NTKERNELAPI VOID NTAPI KeAttachProcess(PEPROCESS Process);
NTKERNELAPI VOID NTAPI KeDetachProcess();
void DriverUnLoad(PDRIVER_OBJECT pDriverObj)
{
KdPrint(("驱动卸载成功"));
}
/*
1.枚举所有进程. 2^31方
*/
PEPROCESS GetEprocessByPid(HANDLE pid)
{
//根据PID 返回PEPROCESS
PEPROCESS pEpro = NULL;
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
ntStatus = PsLookupProcessByProcessId(pid, &pEpro);
if (NT_SUCCESS(ntStatus))
{
return pEpro;
}
return NULL;
}
//新方法
void MemKillProcess(HANDLE pid)
{
PEPROCESS proc = NULL;
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PKAPC_STATE pApcState = NULL;
PsLookupProcessByProcessId((HANDLE)pid,&proc);
if (proc == 0)
{
return;
}
//KeAttachProcess(proc);
//KeDetachProcess() 等都已经过时.所以使用新的
pApcState = (PKAPC_STATE)ExAllocatePoolWithTag(NonPagedPool, sizeof(PKAPC_STATE), '1111');
if (NULL == pApcState)
{
ObDereferenceObject(proc);
return;
}
__try{
KeStackAttachProcess(proc, pApcState);
//KeAttachProcess(proc);
for (int i = 0x10000; i < 0x20000000; i += PAGE_SIZE)
{
__try
{
memset((PVOID)i, 0, PAGE_SIZE);
}
__except (1)
{
; //内部处理异常
}
}
KeUnstackDetachProcess(pApcState);
//KeDetachProcess();
ObDereferenceObject(proc);
return;
}
__except (1)
{
DbgPrint("强杀出错\r\n");
KeUnstackDetachProcess(pApcState);
ObDereferenceObject(proc);
}
return;
}
HANDLE GetPidByProcessName(char *ProcessName)
{
PEPROCESS pCurrentEprocess = NULL;
HANDLE pid = 0;
DbgPrint("寻找名为%s的PID\r\n", ProcessName);
for (int i = 0; i < 2147483647; i += 4)
{
pCurrentEprocess = GetEprocessByPid((HANDLE)i);
if (pCurrentEprocess != NULL)
{
/*DbgPrint("进程名字为: %s 进程PID = %d 进程的父Pid = %d\r\n",
PsGetProcessImageFileName(pCurrentEprocess),
PsGetProcessId(pCurrentEprocess),
PsGetProcessInheritedFromUniqueProcessId(pCurrentEprocess));*/
pid = PsGetProcessId(pCurrentEprocess);
if (strstr(PsGetProcessImageFileName(pCurrentEprocess), ProcessName) != NULL)
{
ObDereferenceObject(pCurrentEprocess); //解引用
DbgPrint("找到了\r\n");
return pid;
}
ObDereferenceObject(pCurrentEprocess); //解引用
}
}
DbgPrint("未找到\r\n");
return (HANDLE)-1;
}
//旧方法
void OldMemKillProcess(HANDLE pid)
{
SIZE_T i = 0;
//依附进程
PEPROCESS proc = 0;
PsLookupProcessByProcessId(pid, &proc);
if (NULL == proc)
{
return;
}
KeAttachProcess((PEPROCESS)proc); //这里改为指定进程的 EPROCESS
for (i = 0x10000; i < 0x20000000; i += PAGE_SIZE)
{
__try
{
memset((PVOID)i, 0, PAGE_SIZE); //把进程内存全部置零
}
_except(1)
{
;
}
}
//退出依附进程
KeDetachProcess();
ObDereferenceObject(proc);
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
ULONG iCount = 0;
NTSTATUS ntStatus;
pDriverObj->DriverUnload = DriverUnLoad;
MemKillProcess(GetPidByProcessName("calc.exe")); //新方法
OldMemKillProcess(GetPidByProcessName("calc.exe"));//旧方法
return STATUS_SUCCESS;
}