#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)
没有评论:
发表评论