工具:WDK 7+VS2015 测试平台:虚拟机 WINDOWS XP
包含的头文件#include
声明的API函数NTKERNELAPI HANDLE PsGetProcessInheritedFromUniqueProcessId(IN PEPROCESS Process);NTKERNELAPI PPEB_EX PsGetProcessPeb(PEPROCESS Process);NTKERNELAPI NTSTATUS PsLookupProcessByProcessId(HANDLE Id, PEPROCESS *Process);NTKERNELAPI NTSTATUS PsLookupThreadByThreadId(HANDLE Id, PETHREAD *Thread);NTKERNELAPI PEPROCESS IoThreadToProcess(PETHREAD Thread);//NTKERNELAPI VOID NTAPI KeAttachProcess(PEPROCESS Process);//NTKERNELAPI VOID NTAPI KeDetachProcess();//NTKERNELAPI VOID NTAPI KeStackAttachProcess(PEPROCESS Process, PKAPC_STATE ApcState);//NTKERNELAPI VOID NTAPI KeUnstackDetachProcess(PKAPC_STATE ApcState);
因为要通过PEPROCESS 来获取进程和模块,所以还要用到几个结构体要,在WinDbg 可看到。这里新建一个头文件,包含了PEB等信息#include 'peb.h'如下:#pragma once#include
用于遍历进程函数void EnumProcess(PEPROCESS eprocess){ KAPC_STATE ks; if (!MmIsAddressValid(eprocess)) return; //获取 PEB信息 PPEB_EX peb = PsGetProcessPeb(eprocess); if (!peb) return; //依附进程!!!!!!!!!!!!!! KeStackAttachProcess(eprocess, &ks); __try { if (PsGetProcessId(eprocess)!=0) { //获取 进程参数 PRTL_USER_PROCESS_PARAMETERS rtl_user_process_param = (PRTL_USER_PROCESS_PARAMETERS)peb->ProcessParameters; DbgPrint('CommandLine:%wZ\n', &rtl_user_process_param->CommandLine); DbgPrint('ImagePath=%wZ\n', &rtl_user_process_param->ImagePathName); //DbgPrint('Window Title=%wZ\n', &rtl_user_process_param->WindowTitle); DbgPrint('——————————————————————————————'); } } __except (EXCEPTION_EXECUTE_HANDLER) { //DbgPrint('Can not Process...'); } //取消依附进程 KeUnstackDetachProcess(&ks);}
//遍历模块,大体上和遍历进程一样,但也要注意void EnumModules(PEPROCESS eprocess){ KAPC_STATE ks; if (!MmIsAddressValid(eprocess)) return; //获取 PEB信息 PPEB_EX peb = PsGetProcessPeb(eprocess); if (!peb) return; //依附进程!!!!!!!!!!!!!! KeStackAttachProcess(eprocess, &ks); __try { PPEB_LDR_DATA_EX peb_LDR_data = (PPEB_LDR_DATA_EX)peb->Ldr; PLIST_ENTRY list_entry = &peb_LDR_data->InLoadOrderModuleList; //先获取第一个 PLIST_ENTRY currentList = list_entry->Flink; while (currentList!=list_entry) { PLDR_DATA_TABLE_ENTRY_EX ldr_data_table_entry = (PLDR_DATA_TABLE_ENTRY_EX)currentList; DbgPrint('Module Base=%p DllPath=%wZ\n', ldr_data_table_entry->DllBase, &ldr_data_table_entry->FullDllName); //指向下一个 currentList = currentList->Flink; } } __except (EXCEPTION_EXECUTE_HANDLER) { //DbgPrint('Can not Modules...'); } //取消依附进程 KeUnstackDetachProcess(&ks);}
//这个函数把上面两个函数整合在一起了VOID EnumProcessModuleInformations(){ //第一个进程环境块 PEPROCESS eprocess=PsGetCurrentProcess(); PEPROCESS eprocess_first = eprocess; while (1) {//获取进程 EnumProcess(eprocess); //下一个进程,我获取的是WinXP的 EPROCESS ! eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88); if (eprocess == eprocess_first) { break; } } eprocess= eprocess_first; while (1) {//获取模块 EnumModules(eprocess); //下一个进程 eprocess = (PEPROCESS)(*(ULONG*)((ULONG)eprocess + 0x88) - 0x88); if (eprocess == eprocess_first) { break; } } }
//卸载函数很简单VOID unload(PDRIVER_OBJECT p){ DbgPrint('UnloadDriver...');}
//驱动入口函数 NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver_Obj, PUNICODE_STRING pRegisterPath){ DbgPrint('DriverEntry...'); pDriver_Obj->DriverUnload = unload; DbgPrint('DriverName:%wZ RegisterPath:%wZ \n ', &pDriver_Obj->DriverName, pRegisterPath);//这里调用 EnumProcessModuleInformations(); return STATUS_SUCCESS;}
最后,基本上OK了,附上一张测试图: