/* 本文就暂时命名为PsLookupProcessByProcessId.C吧! pid与进程名互换,很简单的问题,不削一顾,可到用的时候才知道重要。 网上很多,那是别人的。 还是自己的感觉好,完全懂,还一个修改。 made by correy made at 2013.01.18 QQ:112426112 Email:kouleguan at hotmail dot com Homepage:http://correy.webs.com If the call to PsLookupProcessByProcessId is successful, PsLookupProcessByProcessID increases the reference count on the object returned in the Process parameter. Consequently, when a driver has completed using the Process parameter, the driver must call ObDereferenceObject to dereference the Process parameter received from the PsLookupProcessByProcessID routine. */ #include <ntddk.h> #include <ntifs.h> extern UCHAR *PsGetProcessImageFileName(IN PEPROCESS Process); //c++ 才需要"C" DRIVER_UNLOAD Unload; VOID Unload(__in PDRIVER_OBJECT DriverObject) { } HANDLE GetPidFromProcessName(char * ProcessName) { PEPROCESS Process; int h; CHAR * pName; STRING s1,s2; for (h = 0; h < 10000; h += 4) //由于PEPROCESS结构不公开,不采用遍历的办法,反而更通用。 { if (PsLookupProcessByProcessId((HANDLE)h, & Process) != STATUS_INVALID_PARAMETER) { pName = (CHAR*)PsGetProcessImageFileName(Process);//未公开函数。也有替换的办法。 RtlInitString(&s1, pName); RtlInitString(&s2, ProcessName); if (RtlEqualString(&s1, &s2, 1)) { DbgPrint("pid == %08d\n",h); return (HANDLE)h; } } } return (HANDLE)-1; } char * GetProcessNameFromPid(HANDLE pid) { PEPROCESS Process; if (PsLookupProcessByProcessId(pid, & Process) == STATUS_INVALID_PARAMETER) { return "pid不存在"; } DbgPrint("ProcessName is %s\n",PsGetProcessImageFileName(Process)); return (CHAR*)PsGetProcessImageFileName(Process);//未公开函数。也有替换的办法。 } DRIVER_INITIALIZE DriverEntry; NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE h; char * ProcessName; //KdBreakPoint();//#define KdBreakPoint() DbgBreakPoint() DriverObject->DriverUnload = Unload; h = GetPidFromProcessName("explorer.exe"); ProcessName = GetProcessNameFromPid(h); return 0; } ////////////////////////////////////////////////////////////////////////////// //改进版,排除了死进程。有一些垃圾的东西。 /* 本文就暂时命名为PsLookupProcessByProcessId.C吧! pid与进程名互换,很简单的问题,不削一顾,可到用的时候才知道重要。 网上很多,那是别人的。 还是自己的感觉好,完全懂,还可以修改。 made by correy made at 2013.01.24 QQ:112426112 Email:kouleguan at hotmail dot com Homepage:http://correy.webs.com */ #include <ntddk.h> #include <ntifs.h> typedef struct _SYSTEM_THREAD_INFORMATION { LARGE_INTEGER KernelTime; LARGE_INTEGER UserTime; LARGE_INTEGER CreateTime; ULONG WaitTime; PVOID StartAddress; CLIENT_ID ClientId; KPRIORITY Priority; KPRIORITY BasePriority; ULONG ContextSwitchCount; LONG State; LONG WaitReason; } SYSTEM_THREAD_INFORMATION, * PSYSTEM_THREAD_INFORMATION; typedef struct _SYSTEM_PROCESS_INFORMATION { ULONG NextEntryDelta; ULONG ThreadCount; ULONG Reserved1[6]; LARGE_INTEGER CreateTime; LARGE_INTEGER UserTime; LARGE_INTEGER KernelTime; UNICODE_STRING ProcessName; KPRIORITY BasePriority; ULONG ProcessId; ULONG InheritedFromProcessId; ULONG HandleCount; ULONG Reserved2[2]; VM_COUNTERS VmCounters; IO_COUNTERS IoCounters; SYSTEM_THREAD_INFORMATION Threads[1]; } SYSTEM_PROCESS_INFORMATION, * PSYSTEM_PROCESS_INFORMATION; extern UCHAR *PsGetProcessImageFileName(IN PEPROCESS Process); //c++ 才需要"C" extern int PsGetProcessExitStatus(PEPROCESS Process); extern NTSTATUS ZwQuerySystemInformation( int SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength OPTIONAL); DRIVER_UNLOAD Unload; VOID Unload(__in PDRIVER_OBJECT DriverObject) { } //HANDLE GetPidFromProcessName(char * ProcessName) //int IsActiveProcess(int h) //{//枚举进程 // NTSTATUS ntStatus; // ULONG cbBuffer = 0x8000; // PVOID pBuffer = NULL; // PSYSTEM_PROCESS_INFORMATION pInfo; // UNICODE_STRING us1,us2; // // do { // pBuffer = ExAllocatePoolWithTag(NonPagedPool, cbBuffer,'tag'); // if (pBuffer == NULL) { // return 0; // } // // ntStatus = ZwQuerySystemInformation(5, pBuffer, cbBuffer, NULL); // if (ntStatus == STATUS_INFO_LENGTH_MISMATCH) { // ExFreePoolWithTag(pBuffer,'tag'); // cbBuffer *= 2; // } else if (!NT_SUCCESS(ntStatus)) { // ExFreePoolWithTag(pBuffer,'tag'); // return 0; // } // } while(ntStatus == STATUS_INFO_LENGTH_MISMATCH); // // pInfo = (PSYSTEM_PROCESS_INFORMATION)pBuffer; // while(TRUE) // { // /*LPWSTR pszProcessName = pInfo->ProcessName.Buffer; // if (pszProcessName == NULL) { // pszProcessName = L"NULL"; // }*/ // // DbgPrint("pid == %08d;pname:%wZ\n", pInfo->ProcessId,pInfo->ProcessName.Buffer); // // RtlInitUnicodeString(&us1, pInfo->ProcessName.Buffer); // RtlInitUnicodeString(&us2, L"explorer.exe"); ///wgclient.exe // // if (RtlEqualUnicodeString(&us1, &us2, 1)) { // ExFreePoolWithTag(pBuffer,'tag'); // return h; // } // // /*if (pInfo->ProcessId == h) { // ExFreePoolWithTag(pBuffer,'tag'); // return h; // }*/ // // if (pInfo->NextEntryDelta == 0) { // break; // } // pInfo = (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)+pInfo->NextEntryDelta); // } // // ExFreePoolWithTag(pBuffer,'tag'); //} //用ZwQueryInformationProcess ProcessBasicInformation->ExitStatus的办法没有能实现, //不用eprocess的exittime和判断ObjectTable是否为0 , //更不用ZwQuerySystemInformation的5号功能枚举。 //也没有使用peb的办法。 int IsActiveProcess(int h) { PEPROCESS Process; int ExitCode; if (PsLookupProcessByProcessId((HANDLE)h, & Process) != STATUS_INVALID_PARAMETER) { __try { ExitCode = PsGetProcessExitStatus(Process); if (ExitCode == 259) //这个观察所得。 { return 1; } else //等于1就是退出了。 { return 0; } } __except (1) { //这时候大多是Process是错误的。 } } return 0; } HANDLE GetPidFromProcessName(char * ProcessName) { PEPROCESS Process; int h; CHAR * pName; STRING s1,s2; KIRQL OldIrql; KeRaiseIrql(APC_LEVEL, &OldIrql); for (h = 0; h < 10000; h += 4) //由于PEPROCESS结构不公开,不采用遍历的办法,反而更通用。 { if (PsLookupProcessByProcessId((HANDLE)h, & Process) != STATUS_INVALID_PARAMETER) { pName = (CHAR*)PsGetProcessImageFileName(Process);//未公开函数。也有替换的办法。 //如果pName不可以访问,请退出,不然蓝屏。 解决办法是下面加异常处理 //KeRaiseIrql(APC_LEVEL, &OldIrql); __try { if (!MmIsAddressValid(pName)) { continue; } RtlInitString(&s1, pName); RtlInitString(&s2, ProcessName); } __except (1) { //KeLowerIrql(OldIrql); continue; } //KeLowerIrql(OldIrql); //ObDereferenceObject(Process);//加这一行蓝屏。 if (RtlEqualString(&s1, &s2, 1)) { DbgPrint("pid == %08d\n",h); //KeLowerIrql(OldIrql); //放置在这里会运行的快一点。放到上一个if语句,运行的很慢。 //排除已经退出的进程。 if (IsActiveProcess(h)) { KeLowerIrql(OldIrql); return (HANDLE)h; } } s1.MaximumLength = 0;//释放,避免以后还运行。 s2.MaximumLength = 0; } } KeLowerIrql(OldIrql); return (HANDLE)-1; } char * GetProcessNameFromPid1(HANDLE pid) { PEPROCESS Process; if (PsLookupProcessByProcessId(pid, & Process) == STATUS_INVALID_PARAMETER) { return "pid不存在"; } DbgPrint("ProcessName is %s\n",PsGetProcessImageFileName(Process)); return (CHAR*)PsGetProcessImageFileName(Process);//未公开函数。也有替换的办法。 } DRIVER_INITIALIZE DriverEntry; NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath) { NTSTATUS status = STATUS_UNSUCCESSFUL; HANDLE h; char * ProcessName; int b = 0; LARGE_INTEGER interval; KdBreakPoint();//#define KdBreakPoint() DbgBreakPoint() DriverObject->DriverUnload = Unload; for (;;) //主要是测试用的。 { if (b) { break; } h = GetPidFromProcessName("explorer.exe"); ProcessName = GetProcessNameFromPid1(h); interval.QuadPart = (1 * (((-10) * 1000) * 1000)); //暂停5秒钟。 KeDelayExecutionThread(KernelMode, FALSE, &interval);//这3行是新添加的. } return 0; } 还有一个种微软公开,但过时的办法:ZwQuerySystemInformation和ZwQueryInformationProcess
2013年1月18日星期五
PsLookupProcessByProcessId.C
订阅:
博文评论 (Atom)
没有评论:
发表评论