/*
本文就暂时命名为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)
没有评论:
发表评论