#include <ntifs.h>
/*
功能:获取进程的全路径。
优点:进程的名字没有15-16个字符的限制。
此办法早就知道,一直没有实验成功。
今天用DBGVIEW.EXE观察成功,但是没有用WINDBG.EXE调试。
尽管MSDN上这样说:
ZwQueryInformationProcess may be altered or unavailable in future versions of Windows.
Applications should use the alternate functions listed in this topic.
可是ProcessImageFileName的功能也没有说没有替代的函数。
made by correy
made at 2014.05.06
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/
#define tag 'tset' //test
//2008版本的MSDN,非WDK。
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms687420(v=vs.85).aspx
//上面的一些标注在低版本上的WDK出错。
NTSTATUS /* WINAPI */ ZwQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
void print_ProcessImageFileName(IN HANDLE PId)
{
NTSTATUS status = 0;
PVOID us_ProcessImageFileName = 0;//UNICODE_STRING
ULONG ProcessInformationLength = 0;
ULONG ReturnLength = 0;
PEPROCESS EProcess = 0;
HANDLE Handle = 0;
/*
必须转换一下,不然是无效的句柄。
大概是句柄的类型转换为内核的。
*/
status = PsLookupProcessByProcessId(PId, &EProcess);
if (!NT_SUCCESS( status ))
{
KdPrint(("PsLookupProcessByProcessId fail with 0x%x in line %d\n",status, __LINE__));
return;
}
ObDereferenceObject(EProcess); //微软建议加上。
status = ObOpenObjectByPointer(EProcess, OBJ_KERNEL_HANDLE, NULL, GENERIC_READ, *PsProcessType, KernelMode, &Handle);//注意要关闭句柄。
if (!NT_SUCCESS( status ))
{
KdPrint(("ObOpenObjectByPointer fail with 0x%x in line %d\n",status, __LINE__));
return;
}
//获取需要的内存。
status = ZwQueryInformationProcess(Handle, ProcessImageFileName,us_ProcessImageFileName, ProcessInformationLength, &ReturnLength);
if( !NT_SUCCESS( status ) && status != STATUS_INFO_LENGTH_MISMATCH)
{
KdPrint(("ZwQueryInformationProcess fail with 0x%x in line %d\n",status, __LINE__));
ZwClose(Handle);
return;
}
ProcessInformationLength = ReturnLength;
us_ProcessImageFileName = ExAllocatePoolWithTag( NonPagedPool, ReturnLength, tag);
if (us_ProcessImageFileName == NULL) {
KdPrint(("ExAllocatePoolWithTag fail with 0x%x\n",status));
status = STATUS_INSUFFICIENT_RESOURCES;
ZwClose(Handle);
return;
}
RtlZeroMemory(us_ProcessImageFileName, ReturnLength);
status = ZwQueryInformationProcess(Handle, ProcessImageFileName,us_ProcessImageFileName, ProcessInformationLength, &ReturnLength);
if( !NT_SUCCESS( status ) )
{
KdPrint(("ZwQueryInformationProcess fail with 0x%x in line %d\n",status, __LINE__));
ExFreePoolWithTag( us_ProcessImageFileName, tag );
ZwClose(Handle);
return;
}
KdPrint(("ProcessImageFileName:%wZ\n",us_ProcessImageFileName));//注意:中间有汉字是不会显示的。
//形如:ProcessImageFileName:\Device\HarddiskVolume1\aa\Dbgvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvview.exe
ExFreePoolWithTag( us_ProcessImageFileName, tag );
ZwClose(Handle);
}
VOID ProcessCreateMon ( IN HANDLE hParentId, IN HANDLE PId,IN BOOLEAN bCreate )
{
if ( bCreate )
{
print_ProcessImageFileName(PId);
}
else
{
DbgPrint( "TERMINATED == PROCESS ID: %d\n", PId);
}
}
DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, TRUE);
if (!NT_SUCCESS( status ))
{
DbgPrint( "PsSetCreateProcessNotifyRoutine fail %d\n", status);
return;
}
}
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
BOOLEAN b = 0;
KdBreakPoint();//#define KdBreakPoint() DbgBreakPoint()
DriverObject->DriverUnload = Unload;
status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, FALSE);
if (!NT_SUCCESS( status ))
{
DbgPrint( "PsSetCreateProcessNotifyRoutine fail %d\n", status);
return status;
}
return 0;//STATUS_SUCCESS
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
#include <ntifs.h>
#include <windef.h>
/*
写作目的:
工作中的一次试验:拦截test.exe的某个操作。可死活拦截不了,郁闷了几天,在同事的探讨中发现了这个问题。
1.eprocees 中:ImageFileName : [15] ""
2.运行PsGetProcessImageFileName后,发现:
kd> db rax
fffffa80`1aed78b0 74 65 73 74 2e 65 78 65-70 70 6c 69 63 61 00 02 test.exepplica..
3.其实还有个限制就是不能超过15-16个字符。
这些问题百年不遇,以前用的好好的,今天突然出现这些问题,而且概率性还挺高的。
所以选用别的办法,放弃此函数。
以此纪念。
made by correy
made at 2014.06.17
email:kouleguan at hotmail dot com
homepage:http://correy.webs.com
*/
#define tag 'tset' //test
//2008版本的MSDN,非WDK。
//http://msdn.microsoft.com/en-us/library/windows/desktop/ms687420(v=vs.85).aspx
//上面的一些标注在低版本上的WDK出错。
NTSTATUS /* WINAPI */ ZwQueryInformationProcess(
__in HANDLE ProcessHandle,
__in PROCESSINFOCLASS ProcessInformationClass,
__out PVOID ProcessInformation,
__in ULONG ProcessInformationLength,
__out_opt PULONG ReturnLength
);
BOOL GetProcessImageFileName(IN HANDLE PId, OUT UNICODE_STRING * file_name )
{
NTSTATUS status = 0;
PVOID us_ProcessImageFileName = 0;//UNICODE_STRING
ULONG ProcessInformationLength = 0;
ULONG ReturnLength = 0;
PEPROCESS EProcess = 0;
HANDLE Handle = 0;
UNICODE_STRING * p = {0};
UNICODE_STRING temp = {0};
USHORT i = 0;
/*
必须转换一下,不然是无效的句柄。
大概是句柄的类型转换为内核的。
*/
status = PsLookupProcessByProcessId(PId, &EProcess);
if (!NT_SUCCESS( status ))
{
KdPrint(("PsLookupProcessByProcessId fail with 0x%x in line %d\n",status, __LINE__));
return FALSE ;
}
ObDereferenceObject(EProcess); //微软建议加上。
status = ObOpenObjectByPointer(EProcess, OBJ_KERNEL_HANDLE, NULL, GENERIC_READ, *PsProcessType, KernelMode, &Handle);//注意要关闭句柄。
if (!NT_SUCCESS( status ))
{
KdPrint(("ObOpenObjectByPointer fail with 0x%x in line %d\n",status, __LINE__));
return FALSE;
}
//获取需要的内存。
status = ZwQueryInformationProcess(Handle, ProcessImageFileName,us_ProcessImageFileName, ProcessInformationLength, &ReturnLength);
if( !NT_SUCCESS( status ) && status != STATUS_INFO_LENGTH_MISMATCH)
{
KdPrint(("ZwQueryInformationProcess fail with 0x%x in line %d\n",status, __LINE__));
ZwClose(Handle);
return FALSE ;
}
ProcessInformationLength = ReturnLength;
us_ProcessImageFileName = ExAllocatePoolWithTag( NonPagedPool, ReturnLength, tag);
if (us_ProcessImageFileName == NULL) {
KdPrint(("ExAllocatePoolWithTag fail with 0x%x\n",status));
status = STATUS_INSUFFICIENT_RESOURCES;
ZwClose(Handle);
return FALSE ;
}
RtlZeroMemory(us_ProcessImageFileName, ReturnLength);
status = ZwQueryInformationProcess(Handle, ProcessImageFileName,us_ProcessImageFileName, ProcessInformationLength, &ReturnLength);
if( !NT_SUCCESS( status ) )
{
KdPrint(("ZwQueryInformationProcess fail with 0x%x in line %d\n",status, __LINE__));
ExFreePoolWithTag( us_ProcessImageFileName, tag );
ZwClose(Handle);
return FALSE ;
}
//KdPrint(("ProcessImageFileName:%wZ\n",us_ProcessImageFileName));//注意:中间有汉字是不会显示的。
//形如:ProcessImageFileName:\Device\HarddiskVolume1\aa\Dbgvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvview.exe
p = (UNICODE_STRING *)us_ProcessImageFileName;
//从末尾开始搜索斜杠。
for (i = p->Length/2 - 1 ; ;i-- )
{
if (p->Buffer[i] == L'\\')
{
break;
}
}
i++;//跳过斜杠。
//构造文件名结构,复制用的。
temp.Length = p->Length - i * 2;
temp.MaximumLength = p->MaximumLength - i * 2;
temp.Buffer = &p->Buffer[i];
//这个内存由调用者释放。
file_name->Buffer = ExAllocatePoolWithTag(NonPagedPool, MAX_PATH, tag);
if (file_name->Buffer == NULL) {
DbgPrint("发生错误的文件为:%s, 代码行为:%d\n", __FILE__, __LINE__);
ExFreePoolWithTag( us_ProcessImageFileName, tag );
ZwClose(Handle);
return FALSE ;
}
RtlZeroMemory(file_name->Buffer, MAX_PATH);
RtlInitEmptyUnicodeString(file_name, file_name->Buffer,MAX_PATH);
RtlCopyUnicodeString(file_name, &temp);
KdPrint(("ProcessImageFileName:%wZ\n",file_name));
ExFreePoolWithTag( us_ProcessImageFileName, tag );
ZwClose(Handle);
return TRUE ;
}
VOID ProcessCreateMon ( IN HANDLE hParentId, IN HANDLE PId,IN BOOLEAN bCreate )
{
UNICODE_STRING file_name;
BOOL B = FALSE ;
if ( bCreate )
{
B = GetProcessImageFileName(PId, &file_name );
if (!B)
{
DbgPrint( "GetProcessImageFileName fail!\n");
}
RtlFreeUnicodeString(&file_name);
}
else
{
DbgPrint( "TERMINATED == PROCESS ID: %d\n", PId);
}
}
DRIVER_UNLOAD Unload;
VOID Unload(__in PDRIVER_OBJECT DriverObject)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, TRUE);
if (!NT_SUCCESS( status ))
{
DbgPrint( "PsSetCreateProcessNotifyRoutine fail %d\n", status);
return;
}
}
DRIVER_INITIALIZE DriverEntry;
NTSTATUS DriverEntry( __in struct _DRIVER_OBJECT * DriverObject, __in PUNICODE_STRING RegistryPath)
{
NTSTATUS status = STATUS_UNSUCCESSFUL;
BOOLEAN b = 0;
KdBreakPoint();
DriverObject->DriverUnload = Unload;
status = PsSetCreateProcessNotifyRoutine(ProcessCreateMon, FALSE);
if (!NT_SUCCESS( status ))
{
DbgPrint( "PsSetCreateProcessNotifyRoutine fail %d\n", status);
return status;
}
return 0;//STATUS_SUCCESS
}
2014年5月7日星期三
在驱动中获取进程的全路径
订阅:
博文评论 (Atom)
没有评论:
发表评论