阅读:3804回复:7
driver如何根据进程ID得到其对应的程序文件名?
driver用PsGetCurrentProcessId( )可以得到当前的进程ID,如何把这个PID转换成对应的程序文件名?
把这个PID传给ring 3的应用程序,由应用程序在用户态转换成文件名之后再传给driver似乎可行,但在这个来回的时间段内,那个PID对应的进程有可能退出了,而且这样在内核态和用户态之间切换也有效率问题。 我看了sysinternals.com上的FileMon的代码,它似乎是通过搜索内存来找到进程的文件名的,但无法得到该文件的全路径名。 谢谢! |
|
沙发#
发布于:2002-04-02 11:31
思路,供参考:
用PsGetCurrentProcess或IoGetCurrentProcess 得到进程的EPROCESS的指针 然后访问EPROCESS内部的域ImageFileName 对于EPROCESS内部数据结构在《Inside Win2000》中有描述 在本站有个帖子也有描述:http://www.driverdevelop.com/forum/viewthread.php?tid=5725 问题是访问这些域好象不太容易 |
|
|
板凳#
发布于:2002-04-02 18:48
ImageFileName好象不是全路径名,是个短名,只有16个unicode字符长。
[编辑 - 4/2/02 作者: Netguy] |
|
地板#
发布于:2002-04-02 22:48
not so difficult.
but what you think is not correct. commonly , not all IRP is dealed in orginal context.(when you use systemthread or workitem), if you currect irql is not passive, you can not get it now. assume you use workthread, you pass orignal irp by someway. then do this way if ( Irp ) { pEthread = Irp->Tail.Overlay.Thread; }else { pEthread = PsGetCurrentThread(); } if (!pEthread)... //error pREProcess = pEthread->ThreadsProcess; if (!pREProcess ).... //error dwRProcessId = pREProcess->UniqueProcessId; InitializeObjectAttributes( &RObjectAttributes, 0, 0, 0, 0 ); RClientId.UniqueProcess = (HANDLE)dwRProcessId; RClientId.UniqueThread = 0; ntRStatus = ZwOpenProcess( &hRProcess, PROCESS_ALL_ACCESS,&RObjectAttributes, &RClientId ); if( !NT_SUCCESS(ntRStatus) ) .. //error ntRStatus = ZwReadVirtualMemory( hRProcess, pREProcess->Peb,&Peb, sizeof(Peb), &dwRReturnedBytes ); if( !NT_SUCCESS(ntRStatus) ) .. //error if(! Peb.ProcessParameters )... //error ntRStatus = ZwReadVirtualMemory( hRProcess, Peb.ProcessParameters, &PebParams, sizeof(PebParams), &dwRReturnedBytes ); if( !NT_SUCCESS(ntRStatus) ) .. //error pRCommandLine = PebParams.ApplicationName.Buffer; nRSize = PebParams.ApplicationName.Length; if( pRCommandLine && nRSize > 0 && nRSize < 2048 ) { pLocalCommandLine = ExAllocatePool( NonPagedPool, nRSize +2); RtlZeroMemory(pLocalCommandLine , nRSize +2); ntRStatus = ZwReadVirtualMemory( hRProcess, pRCommandLine, pLocalCommandLine, nRSize, &dwRReturnedBytes ); if( !NT_SUCCESS(ntRStatus)) ..//error RtlInitUnicodeString(&UCmdLine,pLocalCommandLine); AnsiStr.Buffer = NULL; RtlUnicodeStringToAnsiString (&AnsiStr, &UCmdLine, TRUE); strncpy(ProcessName, AnsiStr.Buffer, min (AnsiStr.Length, PROCNAMELEN -1)); RtlFreeAnsiString(&AnsiStr); ..... now , ProcessName is full process image name include formal path informatin. remember , you can not get system process image path. remember , irpl is always must be checked. you should not use it in passive level. if not, use workitem or system thread. if you want to get command parameters, use PebParams.CommandLine to replace PebParams.ApplicationName and .... you can not use it as a real ifs filter. because when ifs initialize, it can not depend on ntdll.dll. if you must use zwreadvirtualmemory for a ifs driver or filter. realize zwreadvirtualmemory yourself. mov eax, 0xa4 lea edx, [esp+0x4] int 0x2e ret |
|
地下室#
发布于:2002-04-02 22:51
sorry, write miss.
remember , irpl is always must be checked. you should not use it in passive level. if not, use workitem or system thread. should be remember , irpl is always must be checked. you should use it in passive level. if not, use workitem or system thread. |
|
5楼#
发布于:2002-04-03 23:22
多谢啦!!!
下面的几个结构的具体内容好象在ntddk.h/wdm.h中没有定义? typedef struct _KTHREAD *PKTHREAD; typedef struct _ETHREAD *PETHREAD; typedef struct _EPROCESS *PEPROCESS; 我昨天看到一个驱动程序大概用的另外一种方法得到全文件名: 1、用PsSetCreateProcessNotifyRoutine挂一个钩子,通过它可以得到加载的每个进程的ID和短文件名; 2、用PsSetLoadImageNotifyRoutine挂一个钩子,通过它可以得到加载的每个模块的全文件名和进程ID; 将1和2的结果进行匹配就可以建立进程ID和全文件名的对应关系。不过这种方法有个缺陷,就是要求驱动必须在所有进程创建之前北加载。 |
|
6楼#
发布于:2002-04-03 23:29
另外,顺便请教一下各位,如何给别人打分?我登录进来之后硬是没找到打分的地方 :( 谢谢!
|
|
7楼#
发布于:2002-04-04 01:02
reference , http://www.insidewindows.info/
you will get detail ntifs.h PsSetCreateProcessNotifyRoutine and PsSetLoadImageNotifyRoutine is quite good for common use. apispy32 use it as in nt/2k system for new load process because nt memory copy-on-write.. |
|