驱动枚举所有进程所有模块,删除指定进程。
环境: VS2008中配置WDK7600驱动开发环境
包含文件 #include <ntifs.h> #include <WinDef.h>
需要在 #include <ntddk.h> 之前那么就不会出错
程序大体流程:
PsGetCurrentProcess() 得到本进程EPROCESS
通过EPROCESS +0x174 得到进程名
通过EPROCESS +0x84得到进程ID
PsLookupProcessByProcessId 通过进程ID 得到 这个ID的 EPROCESS
MmGetSystemRoutineAddress得到 PsGetProcessPeb的函数地址
PsGetProcessPeb 通过进程的 EPROCESS得到 进程的PEB 然后再得到PEB的LDR
保存APC状态(Asynchronous procedure call,异步程序调用)KeStackAttachProcess(EPROCESS , &KAPC);
通过ldr 得到 内存加载链表InMemoryOrderModuleList 通过它循环遍历模块
pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink
pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
pLdrDataEntry 包含有模块的全路径 然后循环得到
detach进程 KeUnstackDetachProcess
另外就是 PsLookupProcessByProcessId得到 EPROCESS会增加引用计数 这里减少即可
ObDereferenceObject(EPROCESS),EPROCESS=null;
通过EPROCESS +0x88得到下一个EPROCESS的ActiveProcessLinks
通过上面这个结构 - 0x88 就得到这个EPROCESS指针
然后循环进行遍历进程
typedef PPEB (__stdcall *PFNPsGetProcessPeb)(PEPROCESS pEProcess);
typedef ULONG PPS_POST_PROCESS_INIT_ROUTINE; <div>
typedef struct _PEB_LDR_DATA {
BYTE Reserved1;
PVOID Reserved2;
LIST_ENTRY InMemoryOrderModuleList;
} PEB_LDR_DATA, *PPEB_LDR_DATA; </div><div>
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1;
PVOID Reserved2;
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BYTE Reserved1;
BYTE BeingDebugged;
BYTE Reserved2;
PVOID Reserved3;
PPEB_LDR_DATA Ldr;
PRTL_USER_PROCESS_PARAMETERSProcessParameters;
BYTE Reserved4;
PVOID Reserved5;
PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine;
BYTE Reserved6;
PVOID Reserved7;
ULONG SessionId;
} PEB, *PPEB;
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
DWORD SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
DWORD Flags;
WORD LoadCount;
WORD TlsIndex;
LIST_ENTRY HashLinks;
PVOID SectionPointer;
DWORD CheckSum;
DWORD TimeDateStamp;
PVOID LoadedImports;
PVOID EntryPointActivationContext;
PVOID PatchInformation;
}LDR_DATA_TABLE_ENTRY,*PLDR_DATA_TABLE_ENTRY; </div>
主要功能代码:
NTSTATUS ScanModulebypid(ULONG ulProcessId)
{
//获取进程的EPROCESS结构指针
NTSTATUS nStatus;
PEPROCESSpEProcess = NULL;
nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess);
if (!NT_SUCCESS(nStatus))
{
return STATUS_UNSUCCESSFUL;
}
//查找函数地址
UNICODE_STRING uniFunctionName;
RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb");
//函数指针
PFNPsGetProcessPebPsGetProcessPeb = NULL;
PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName);
if (PsGetProcessPeb == NULL)
{
KdPrint(("Get PsGetProcessPeb Failed~!\n"));
return STATUS_UNSUCCESSFUL;
}
//获取PEB指针
PPEB pPEB = NULL;
pPEB = PsGetProcessPeb(pEProcess);
if (pPEB == NULL)
{
KdPrint(("Get pPEB Failed~!\n"));
return STATUS_UNSUCCESSFUL;
}
//保存APC状态APC,即Asynchronous procedure call,异步程序调用
KAPC_STATE KAPC ={0};
//附加到进程
KeStackAttachProcess(pEProcess, &KAPC);
//是否已经附加到进程
BOOLEAN bIsAttached = FALSE;
bIsAttached = TRUE;
//指向LDR
//LDR数据结构
PPEB_LDR_DATA pPebLdrData = NULL;
pPebLdrData = pPEB->Ldr;
//链表头节点、尾节点
PLIST_ENTRY pListEntryStart = NULL;
PLIST_ENTRY pListEntryEnd = NULL;
//头节点、尾节点
pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;
//开始遍历_LDR_DATA_TABLE_ENTRY
//LDR链表入口
PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;
do
{
//通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构
pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
//输出DLL全路径
KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));
pListEntryStart = pListEntryStart->Flink;
}while(pListEntryStart != pListEntryEnd);
KdPrint(("\n\n"));
//Detach进程
if (bIsAttached != FALSE)
{
KeUnstackDetachProcess(&KAPC);
}
//减少引用计数
if (pEProcess != NULL)
{
ObDereferenceObject(pEProcess);
pEProcess = NULL;
}
return STATUS_SUCCESS;
}
NTSTATUS ScanProcessModule()
{
PEPROCESS eprocess,Firsteprocess;
ULONG ulProcessName;
ULONG ulProcessID;
KdPrint(("start ScanProcessModile\n"));
//__asm int 3;
eprocess = PsGetCurrentProcess();
Firsteprocess = eprocess;
if (eprocess == 0)
{
KdPrint(("PsGetCurrentProcess error"));
return STATUS_SUCCESS;
}
while (eprocess != NULL)
{
ulProcessName = (ULONG)eprocess + 0x174; // +0x174 ImageFileName : UChar
ulProcessID = *(ULONG*)((ULONG)eprocess + 0x84);// +0x084 UniqueProcessId: Ptr32 Void
KdPrint(("processname = %s,processid = %d \r \n",ulProcessName,ulProcessID));
//if (!strcmp( (char*)(ULONG*)ulProcessName ,"notepad.exe"))
//{
ScanModulebypid(ulProcessID);
//}
// +0x088 ActiveProcessLinks : _LIST_ENTRY
eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88);//-0x88是得到 eprocess结构
if (eprocess == Firsteprocess || (*(LONG*)( (LONG)eprocess + 0x84) ) <0)//如果链表搜索完毕或者进程PID小于0则结束
{
break;
}
}
return STATUS_SUCCESS;
}
删除指定进程:
方法1 卸载掉指定进程的NTDLL.dll 模块 (这里以 notepad.exe 为例子)
extern "C"
NTSTATUS
MmUnmapViewOfSection(
IN PEPROCESS Process,
IN ULONG BaseAddress
);
NTSTATUS ScanProcessModule()
{
PEPROCESS eprocess,Firsteprocess;
ULONG ulProcessName;
ULONG ulProcessID;
KdPrint(("start ScanProcessModile\n"));
//__asm int 3;
eprocess = PsGetCurrentProcess();
Firsteprocess = eprocess;
if (eprocess == 0)
{
KdPrint(("PsGetCurrentProcess error"));
return STATUS_SUCCESS;
}
PEPROCESS eprocess2;
while (eprocess != NULL)
{
ulProcessName = (ULONG)eprocess + 0x174; // +0x174 ImageFileName : UChar
ulProcessID = *(ULONG*)((ULONG)eprocess + 0x84);// +0x084 UniqueProcessId: Ptr32 Void
KdPrint(("processname = %s,processid = %d \r \n",ulProcessName,ulProcessID));
if (!strcmp( (char*)(ULONG*)ulProcessName ,"notepad.exe"))
{
PsLookupProcessByProcessId((HANDLE)ulProcessID,&eprocess2);
UNICODE_STRING uniPsGetProcessPeb;
RtlInitUnicodeString(&uniPsGetProcessPeb,L"PsGetProcessPeb");
PFNPsGetProcessPeb PsGetProcessPebAddr = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniPsGetProcessPeb);
if (PsGetProcessPebAddr == NULL)
{
KdPrint(("Get PsGetProcessPeb Failed~!\n"));
return STATUS_UNSUCCESSFUL;
}
PPEB pPEB = NULL;
pPEB = PsGetProcessPebAddr(eprocess2);
if (pPEB == NULL)
{
KdPrint(("Get pPEB Failed~!\n"));
return STATUS_UNSUCCESSFUL;
}
//保存APC状态APC,即Asynchronous procedure call,异步程序调用
KAPC_STATE KAPC ={0};
//附加到进程
KeStackAttachProcess(eprocess2, &KAPC);
//是否已经附加到进程
BOOLEAN bIsAttached = FALSE;
bIsAttached = TRUE;
//指向LDR
//LDR数据结构
PPEB_LDR_DATA pPebLdrData = NULL;
pPebLdrData = pPEB->Ldr;
//链表头节点、尾节点
PLIST_ENTRY pListEntryStart = NULL;
PLIST_ENTRY pListEntryEnd = NULL;
//头节点、尾节点
pListEntryStart = pListEntryEnd = pPebLdrData->InMemoryOrderModuleList.Flink;
//开始遍历_LDR_DATA_TABLE_ENTRY
//LDR链表入口
PLDR_DATA_TABLE_ENTRY pLdrDataEntry = NULL;
do
{
//通过_LIST_ENTRY的Flink成员获取_LDR_DATA_TABLE_ENTRY结构
pLdrDataEntry = (PLDR_DATA_TABLE_ENTRY)CONTAINING_RECORD(pListEntryStart,LDR_DATA_TABLE_ENTRY, InMemoryOrderLinks);
//输出DLL全路径
KdPrint(("%wZ \n", &pLdrDataEntry->FullDllName));
UNICODE_STRING uniNtdll;
RtlInitUnicodeString(&uniNtdll,L"ntdll.dll");
if (RtlEqualUnicodeString(&pLdrDataEntry->BaseDllName,&uniNtdll,TRUE))
{
MmUnmapViewOfSection(eprocess2,(ULONG)(pLdrDataEntry->DllBase));
KdPrint(("卸载 ntdll.dll 完成"));
}
pListEntryStart = pListEntryStart->Flink;
}while(pListEntryStart != pListEntryEnd);
//Detach进程
if (bIsAttached != FALSE)
{
KeUnstackDetachProcess(&KAPC);
}
//减少引用计数
if (eprocess2 != NULL)
{
ObDereferenceObject(eprocess2);
eprocess2 = NULL;
}
}
// +0x088 ActiveProcessLinks : _LIST_ENTRY
eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88);//-0x88是得到 eprocess结构
if (eprocess == Firsteprocess || (*(LONG*)( (LONG)eprocess + 0x84) ) <0)//如果链表搜索完毕或者进程PID小于0则结束
{
break;
}
}
return STATUS_SUCCESS;
}
页:
[1]