1。先要声名一些函数(已经导出)
// 1. 声明要使函数
NTKERNELAPI NTSTATUS PsSuspendProcess(PEPROCESS pEProcess);
NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS pEProcess);
NTKERNELAPI NTSTATUS PsResumeProcess(PEPROCESS pEProcess);
NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(IN PEPROCESS pEProcess);
// 根据PID返回进程EPROCESS,失败返回NULL
PEPROCESS LookupProcess(HANDLE hPid)
{
PEPROCESS pEProcess = NULL;
if (NT_SUCCESS(PsLookupProcessByProcessId(
hPid, &pEProcess)))
return pEProcess;
return NULL;
}
//挂起进程
BOOLEAN KernelSuspendProcess(ULONG Id)
{
//1. 先根据ID得到EPORCESS
PEPROCESS pEProcess;
if ((pEProcess = LookupProcess((HANDLE)Id) )!= NULL)
{
//2. 暂停进程
if (NT_SUCCESS(PsSuspendProcess(pEProcess)))
return FALSE;
}
return TRUE;
}
//恢复进程
BOOLEAN KernelResumeProcess(ULONG Id)
{
//1. 先根据ID得到EPORCESS
PEPROCESS pEProcess;
if ((pEProcess = LookupProcess((HANDLE)Id)) != NULL)
{
//2. 暂停进程
if (NT_SUCCESS(PsResumeProcess(pEProcess)))
return FALSE;
}
return TRUE;
}
//结束进程
void KernelKillProcess() {
HANDLE hProcess = NULL;
CLIENT_ID ClientId = { 0 };
OBJECT_ATTRIBUTES objAttribut =
{ sizeof(OBJECT_ATTRIBUTES) };
ClientId.UniqueProcess = (HANDLE)1234; // PID
ClientId.UniqueThread = 0;
// 打开进程,如果句柄有效,则结束进程
ZwOpenProcess(
&hProcess, // 返回打开后的句柄
1, // 访问权限
&objAttribut, // 对象属性
&ClientId); // 进程ID结构
if (hProcess) {
ZwTerminateProcess(hProcess, 0);
ZwClose(hProcess);
};
}
//遍历进程
VOID EnumProcess() {
PEPROCESS pEProc = NULL;
// 循环遍历进程(假设线程的最大值不超过0x25600)
ULONG i = 0;
for (i = 4; i<0x25600; i = i + 4) {
// a.根据PID返回PEPROCESS
pEProc = LookupProcess((HANDLE)i);
if (!pEProc) continue;
// b. 打印进程信息
DbgPrint("EPROCESS=%p PID=%ld PPID=%ld Name=%s\n",
pEProc, (UINT32)PsGetProcessId(pEProc),
(UINT32)PsGetProcessInheritedFromUniqueProcessId(pEProc),
PsGetProcessImageFileName(pEProc));
// c. 将进程对象引用计数减1
ObDereferenceObject(pEProc);
DbgPrint("\n");
}
}
注意这里不是那种普通的通过链遍历得到的。因为有可能故意断链。这里通过暴力的遍历(同时进程id都是偶数)
原文地址:http://blog.51cto.com/haidragon/2131418
时间: 2024-11-02 23:10:06