Processname from PEProcess

Sorry Don, both of these are false. At least since NT4 this has been a NULL
terminated ansi string and the technique Russinovich used is to scan for the
offset in DriverEntry when you find yourself in the system process context.
So these names can be altered but does this not hold for all other methods
as well ? This method at least has worked on all versions of Windows I have
seen.

Of course this is hacking away into undocumented structures and plain evil
but the alternative mentioned NtQueryInformationProcess is documented for
usermode only and includes the warning “may be altered or unavailable in
future versions of Windows”. According to my standards this is equally bad
practice.

So for me the root of the problem is that there are no documented interfaces
for querying process names in the kernel. All this of course because they
know what’s best for us, just as if the only possible purpose to know a
process name is to use it as a criteria to make decisions for a security
product.

//Daniel

“Don Burn” wrote in message news:xxxxx@ntfsd…
> No, it will give the process name not the executable name, it just turns
> out by default that Windows makes this the same, but it can be set
> differently! As far as using it for the offset, that works for exactly
> that version of the kernel, so the guys driver is still broken.
>

>And this is a piece of crap since in the past depending on the system the
>entry in the EPROCESS structure was either a UNICODE_STRING or a
>PUNICODE_STRING

I don’t use it, but I do disagree with your take on the idea of using
NtQueryInformationProcess(). If it is documented for a specific OS version,
you can limit your usage of that query to those listed as supported, but not
have it run on an OS version newer than documented until you have a chance
to verify it still works and is documented. I think that caveat is to allow
Microsoft to change it without anyone being able to say it broke some form
of ‘contract’.

I do agree that using it for security purposes is not a good idea. Only
digital signatures verifiable from a trusted source can give you a chance of
security. Even with that using process injection and many other techniques
can compromise almost all attempts to secure an OS where the user has admin
rights.

wrote in message news:xxxxx@ntfsd…
> Sorry Don, both of these are false. At least since NT4 this has been a
> NULL terminated ansi string and the technique Russinovich used is to scan
> for the offset in DriverEntry when you find yourself in the system process
> context. So these names can be altered but does this not hold for all
> other methods as well ? This method at least has worked on all versions of
> Windows I have seen.
>
> Of course this is hacking away into undocumented structures and plain evil
> but the alternative mentioned NtQueryInformationProcess is documented for
> usermode only and includes the warning “may be altered or unavailable in
> future versions of Windows”. According to my standards this is equally bad
> practice.
>
> So for me the root of the problem is that there are no documented
> interfaces for querying process names in the kernel. All this of course
> because they know what’s best for us, just as if the only possible purpose
> to know a process name is to use it as a criteria to make decisions for a
> security product.
>
> //Daniel
>
>
> “Don Burn” wrote in message news:xxxxx@ntfsd…
>> No, it will give the process name not the executable name, it just turns
>> out by default that Windows makes this the same, but it can be set
>> differently! As far as using it for the offset, that works for exactly
>> that version of the kernel, so the guys driver is still broken.
>>
> …
>>And this is a piece of crap since in the past depending on the system the
>>entry in the EPROCESS structure was either a UNICODE_STRING or a
>>PUNICODE_STRING
>
>
>
>
>

> Sorry Don, both of these are false. At least since NT4 this has been a NULL

terminated ansi string and the technique Russinovich used is to scan for the
offset in DriverEntry when you find yourself in the system process context.

More so - this is the string Task Manager shows, it gets it by ZwQueryInformationProcess I think.

This string is truncated to IIRC 13 chars, and is not a full pathname.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

>variant, the call fails. The first time I saw this I recall that it was

a bit painful (we ended up allocating user address space buffers so we
could pass them into the call.)

For instance, FSCTL_GET_VOLUME_BITMAP on NT4.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

On Sat, 30 May 2009, Maxim S. Shatskih wrote:

This string is truncated to IIRC 13 chars, and is not a full pathname.

It is possible to get the full path from the undocumented structures that
is available, below is two messages that has been posted before to this
list that shows how to do it:

RH> Hello!

RH> How can I get the full pathname for the process which requested current
RH> IRP? I currently receive the process name (as in FileMon sample), but I
RH> don’t want “iexplore.exe”. I want the full path name: “C:\Program
RH> Files\Internet Explorer\iexplore.exe”.

RH> Anyone knows how this can be done?

RH> Best wishes,
RH> Razvan Hobeanu

try that. I did that and it works

typedef struct _RTL_USER_PROCESS_PARAMETERS {
UCHAR dummy[0x38]; //ñìåùåíèå â ïàðàìåòðå 0x38 - ïðîöåññ, çàïóñòèâøèé ýòîò
UNICODE_STRING ImagePathName;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

#define SYSNAME “System”

ULONG FileSpyGetProcessNameOffset( VOID)
{
PEPROCESS curproc;
int i;

//NTSTATUS Status = STATUS_SUCCESS;

curproc = PsGetCurrentProcess();

// Scan for 12KB, hoping the KPEB never grows that big!
//
for( i = 0; i < 3*PAGE_SIZE; i++ )
{
if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) ))
{
return i;
}
}

//
// Name not found - oh, well
//
return 0;
}

ProcessNameOffset = FileSpyGetProcessNameOffset();

PCHAR GetPathImageProcess( PCHAR PathImage )
{
PEPROCESS curproc;
char *nameptr;
DWORD dw = 0;
LPDWORD tdw;
ANSI_STRING ansi;
NTSTATUS ntStatus;
PRTL_USER_PROCESS_PARAMETERS pupp = NULL;

if( ProcessNameOffset )
{
curproc = PsGetCurrentProcess();
//nameptr = (PCHAR) curproc + ProcessNameOffset; //+0x1DC
//ÄËß NT 4
if( 476==ProcessNameOffset )
{
tdw = (LPDWORD)(((PCHAR)curproc)+0x18C); //??? 18C
dw = *tdw; //_PEB
tdw = (LPDWORD)((PCHAR)dw+0x10);
dw = *tdw; //ProcessParameters
tdw = (LPDWORD)((PCHAR)dw + 0x0);
dw = *tdw;
}
else
{
//ÄËß WIN 2000
tdw = (LPDWORD)(((PCHAR)curproc)+0x1B0); //???
dw = *tdw; //_PEB 0x7ffdf000
tdw = (LPDWORD)((PCHAR)dw+0x10);
dw = *tdw;
tdw = (LPDWORD)((PCHAR)dw + 0x0);
dw = *tdw;
}
//ïðèâåëè ó÷àñòîê ïàìÿòè ê äàííîé ñòðóêòóðå
pupp = (PRTL_USER_PROCESS_PARAMETERS)(tdw);
ntStatus = RtlUnicodeStringToAnsiString( &ansi, &pupp->ImagePathName, TRUE);
if( ntStatus==STATUS_SUCCESS )
{
dw = ansi.Length;
if( dw > 2045 )
dw = 2045;
memcpy( PathImage, ansi.Buffer, dw );
PathImage[dw] = 0;
RtlFreeAnsiString( &ansi );
}//ïîëó÷àþ îòêóäà áûë çàïóùåí
}
else
{
strcpy( PathImage, “???” );
}
return PathImage;
}


Hi, all.
I build a file system filter driver based on FILEMON. In IRP_MJ_CREATE dispatch, I want to
get the process full path name and the file full path name which is to be opened by the
process, the code like this:

////////////////////////////////////////////////////////////////////////////////////
PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
hookExt = HookDevice->DeviceExtension;

case IRP_MJ_CREATE:
fileObject = currentIrpStack->FileObject;
fullPathName = ExAllocatePool(NonPagedPool, MAXPATHLEN );
if(fullPathName)
{
FilemonGetFullPath( fileObject, hookExt, fullPathName );
}

CurrentProcessName = GetCurrentProcessFileName( );
if ((CurrentProcessName != NULL))
{
//

RtlInitUnicodeString(&ProcessUnicodeName, CurrentProcessName); //Errors happened here!
}
////////////////////////////////////////////////////////////////////////////////////
PCWSTR GetCurrentProcessFileName()

{
DWORD dwAddress = (DWORD)PsGetCurrentProcess(); //PEPROCESS
if((dwAddress == 0) || (dwAddress == 0xFFFFFFFF))
return NULL;

dwAddress += 0x1B0; //PEPROCESS->Peb
if((dwAddress = *(DWORD*)dwAddress) == 0)
return NULL;

dwAddress += 0x10; //Peb->ProcessParameters
if((dwAddress = *(DWORD*)dwAddress) == 0)
return NULL;

dwAddress += 0x3C; //Peb->ProcessParameters.ImageFile
dwAddress = *((DWORD*)dwAddress);
return (PCWSTR)dwAddress;
}
//////////////////////////////////////////////////////////////////////////////////////////////
All is work fine except some conditions. For example, we want to debugg an application in VC6(or BCB) and
set breakpoints at the fist line in winmain. When we press F5 to start debugging, before stop at the
breakpoint we set, a fage fault occurs
at the “RtlInitUnicodeString(&ProcessUnicodeName, CurrentProcessName)”. At this point, we get
the fullpathname:
fullpathname = “c:\dev\debug\test.exe” // the application we debugg.
CurrentProcessName != NULl, such as 0x8e8.
: dd 0x8e8
0x8e8 ??? ??? ??? ???
it means NULL! That means at this time EPROCESS->PEB->PROCESSPARAMETERS->IMAGEFILENAME still not be
initilized with proper value. And exam the process list of the system using SOFTICE proc command,
I see process “test.exe” is at RUNNING state with both USERTIME and KERNELTIME equal to Zero. Also,
I can get the IRP_MJ_CREATE dispatch’ process id using PsGetCurrentProcessId(). Ccompare this pid
with the process list we get from softice proc command, I find IRP_MJ_CREATE dispatch is running with
the context in process “test.exe”! It means process “test.exe” want to open “c:\dev\debug\test.exe”.
The IRQL is equal to PASSIVE_LEVEL.
It is strange!

Please give me some advices.

Bo’s post reminded me that as Daniel pointed out I was incorrect, the item I
rememver as being a UNICODE_STRING or a PUNICODE_STRING is the path to the
process, the process name has alway been inline. So using the code below,
is likely to crash, since both the offset can change, and whether is a
UNICODE_STRING or a pointer to one depends on the system.


Don Burn (MVP, Windows DDK)
Windows Filesystem and Driver Consulting
Website: http://www.windrvr.com
Blog: http://msmvps.com/blogs/WinDrvr

“Bo Brantén” wrote in message news:xxxxx@ntfsd…
> On Sat, 30 May 2009, Maxim S. Shatskih wrote:
>
>> This string is truncated to IIRC 13 chars, and is not a full pathname.
>
> It is possible to get the full path from the undocumented structures that
> is available, below is two messages that has been posted before to this
> list that shows how to do it:
>
> RH> Hello!
>
> RH> How can I get the full pathname for the process which requested
> current
> RH> IRP? I currently receive the process name (as in FileMon sample), but
> I
> RH> don’t want “iexplore.exe”. I want the full path name: “C:\Program
> RH> Files\Internet Explorer\iexplore.exe”.
>
> RH> Anyone knows how this can be done?
>
> RH> Best wishes,
> RH> Razvan Hobeanu
>
> try that. I did that and it works
> -------------------------------------------------------
> typedef struct _RTL_USER_PROCESS_PARAMETERS {
> UCHAR dummy[0x38]; //ñìåùåíèå â ïàðàìåòðå 0x38 - ïðîöåññ,
> çàïóñòèâøèé ýòîò
> UNICODE_STRING ImagePathName;
> } RTL_USER_PROCESS_PARAMETERS, PRTL_USER_PROCESS_PARAMETERS;
>
> #define SYSNAME “System”
>
> ULONG FileSpyGetProcessNameOffset( VOID)
> {
> PEPROCESS curproc;
> int i;
>
> //NTSTATUS Status = STATUS_SUCCESS;
>
> curproc = PsGetCurrentProcess();
>
>
> // Scan for 12KB, hoping the KPEB never grows that big!
> //
> for( i = 0; i < 3
PAGE_SIZE; i++ )
> {
> if( !strncmp( SYSNAME, (PCHAR) curproc + i, strlen(SYSNAME) ))
> {
> return i;
> }
> }
>
> //
> // Name not found - oh, well
> //
> return 0;
> }
>
> ProcessNameOffset = FileSpyGetProcessNameOffset();
>
> PCHAR GetPathImageProcess( PCHAR PathImage )
> {
> PEPROCESS curproc;
> char *nameptr;
> DWORD dw = 0;
> LPDWORD tdw;
> ANSI_STRING ansi;
> NTSTATUS ntStatus;
> PRTL_USER_PROCESS_PARAMETERS pupp = NULL;
>
> if( ProcessNameOffset )
> {
> curproc = PsGetCurrentProcess();
> //nameptr = (PCHAR) curproc + ProcessNameOffset; //+0x1DC
> //ÄËß NT 4
> if( 476==ProcessNameOffset )
> {
> tdw = (LPDWORD)(((PCHAR)curproc)+0x18C);
> //??? 18C
> dw = *tdw; //_PEB
> tdw = (LPDWORD)((PCHAR)dw+0x10);
> dw = *tdw; //ProcessParameters
> tdw = (LPDWORD)((PCHAR)dw + 0x0);
> dw = *tdw;
> }
> else
> {
> //ÄËß WIN 2000
> tdw = (LPDWORD)(((PCHAR)curproc)+0x1B0);
> //???
> dw = *tdw; //_PEB 0x7ffdf000
> tdw = (LPDWORD)((PCHAR)dw+0x10);
> dw = *tdw;
> tdw = (LPDWORD)((PCHAR)dw + 0x0);
> dw = *tdw;
> }
> //ïðèâåëè ó÷àñòîê ïàìÿòè ê äàííîé ñòðóêòóðå
> pupp = (PRTL_USER_PROCESS_PARAMETERS)(tdw);
> ntStatus = RtlUnicodeStringToAnsiString( &ansi,
> &pupp->ImagePathName, TRUE);
> if( ntStatus==STATUS_SUCCESS )
> {
> dw = ansi.Length;
> if( dw > 2045 )
> dw = 2045;
> memcpy( PathImage, ansi.Buffer, dw );
> PathImage[dw] = 0;
> RtlFreeAnsiString( &ansi );
> }//ïîëó÷àþ îòêóäà áûë çàïóùåí
> }
> else
> {
> strcpy( PathImage, “???” );
> }
> return PathImage;
> }
>
> -------------------------------------------------------------------------------
>
> Hi, all.
> I build a file system filter driver based on FILEMON. In IRP_MJ_CREATE
> dispatch, I want to get the process full path name and the file full path
> name which is to be opened by the process, the code like this:
>
> ////////////////////////////////////////////////////////////////////////////////////
> PIO_STACK_LOCATION currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
> PIO_STACK_LOCATION nextIrpStack = IoGetNextIrpStackLocation(Irp);
> hookExt = HookDevice->DeviceExtension;
>
> case IRP_MJ_CREATE:
> fileObject = currentIrpStack->FileObject;
> fullPathName = ExAllocatePool(NonPagedPool, MAXPATHLEN );
> if(fullPathName)
> {
> FilemonGetFullPath( fileObject, hookExt, fullPathName );
> }
> …
> CurrentProcessName = GetCurrentProcessFileName( );
> if ((CurrentProcessName != NULL))
> {
> //
> …
> RtlInitUnicodeString(&ProcessUnicodeName,
> CurrentProcessName); //Errors happened here!
> }
> ////////////////////////////////////////////////////////////////////////////////////
> PCWSTR GetCurrentProcessFileName()
>
> {
> DWORD dwAddress = (DWORD)PsGetCurrentProcess(); //PEPROCESS
> if((dwAddress == 0) || (dwAddress == 0xFFFFFFFF))
> return NULL;
>
> dwAddress += 0x1B0; //PEPROCESS->Peb
> if((dwAddress = (DWORD)dwAddress) == 0)
> return NULL;
>
> dwAddress += 0x10;
> //Peb->ProcessParameters
> if((dwAddress = (DWORD)dwAddress) == 0)
> return NULL;
>
> dwAddress += 0x3C;
> //Peb->ProcessParameters.ImageFile
> dwAddress = ((DWORD)dwAddress);
> return (PCWSTR)dwAddress;
> }
> //////////////////////////////////////////////////////////////////////////////////////////////
> All is work fine except some conditions. For example, we want to debugg an
> application in VC6(or BCB) and
> set breakpoints at the fist line in winmain. When we press F5 to start
> debugging, before stop at the breakpoint we set, a fage fault occurs
> at the “RtlInitUnicodeString(&ProcessUnicodeName, CurrentProcessName)”.
> At this point, we get the fullpathname:
> fullpathname = “c:\dev\debug\test.exe” // the application
> we debugg.
> CurrentProcessName != NULl, such as 0x8e8. : dd 0x8e8
> 0x8e8 ??? ??? ??? ???
> it means NULL! That means at this time
> EPROCESS->PEB->PROCESSPARAMETERS->IMAGEFILENAME still not be
> initilized with proper value. And exam the process list of the system
> using SOFTICE proc command, I see process “test.exe” is at RUNNING state
> with both USERTIME and KERNELTIME equal to Zero. Also,
> I can get the IRP_MJ_CREATE dispatch’ process id using
> PsGetCurrentProcessId(). Ccompare this pid
> with the process list we get from softice proc command, I find
> IRP_MJ_CREATE dispatch is running with
> the context in process “test.exe”! It means process “test.exe” want to
> open “c:\dev\debug\test.exe”.
> The IRQL is equal to PASSIVE_LEVEL.
> It is strange!
>
> Please give me some advices.
>
>
> Information from ESET NOD32 Antivirus, version of virus
> signature database 4116 (20090529)

>
> The message was checked by ESET NOD32 Antivirus.
>
> http://www.eset.com
>
>
>

Information from ESET NOD32 Antivirus, version of virus signature database 4116 (20090529)

The message was checked by ESET NOD32 Antivirus.

http://www.eset.com

This brings back memories. :slight_smile: That message is almost 7 years old now - the original thread is here:

http://www.osronline.com/showThread.cfm?link=31216.

The “solution” (looking into the EPROCESS and/or PEB using undocumented/prone-to-change offsets) mentioned by Bo Branten has been offered by Konstantin Shilov in the above-mentioned thread. I didn’t use it in the end because of crashes due to offset changes on various Windows versions.

Therefore, I wouldn’t advise anyone to use this solution in a commercial/shipping product unless they are willing to update their driver every time a new Windows version/service pack comes around (which could result in a change of at least one of those offsets).

In case that driver runs on an “unknown” (with regard to those offsets) version of Windows, it should refuse to load or at least guarantee not to crash the system (by looking into EPROCESS and/or PEB).

Razvan

— On Sat, 5/30/09, Bo Brant?n wrote:
> It is possible to get the full path from the undocumented
> structures that is available, below is two messages that has
> been posted before to this list that shows how to do it:
>
> RH> Hello!
>
> RH> How can I get the full pathname for the process
> which requested current
> RH> IRP? I currently receive the process name (as in
> FileMon sample), but I
> RH> don’t want “iexplore.exe”. I want the full path
> name: “C:\Program
> RH> Files\Internet Explorer\iexplore.exe”.
>
> RH> Anyone knows how this can be done?
>
> RH> Best wishes,
> RH> Razvan Hobeanu
>
> try that. I did that and it works
> -------------------------------------------------------
> typedef struct _RTL_USER_PROCESS_PARAMETERS {
> ? ? ? ? UCHAR dummy[0x38];? ?
> ? //??? ? ??? 0x38 -
> ???, ??? ???
> ? ? ? ? UNICODE_STRING ImagePathName;
> } RTL_USER_PROCESS_PARAMETERS,
> PRTL_USER_PROCESS_PARAMETERS;
>
> #define SYSNAME? ? “System”
>
> ULONG FileSpyGetProcessNameOffset( VOID)
> {
> ? ? ? ? PEPROCESS? ?
> ???curproc;
> ? ? int? ? ? ? ?
> ???i;
>
> ? ? ? ? //NTSTATUS Status =
> STATUS_SUCCESS;
>
> ? ? curproc = PsGetCurrentProcess();
>
>
> ? ? ? ? // Scan for 12KB, hoping the
> KPEB never grows that big!
> ? ? //
> ? ? for( i = 0; i < 3
PAGE_SIZE; i++ )
> ? ? ? ? {
> ? ? ? ? if( !strncmp( SYSNAME, (PCHAR)
> curproc + i, strlen(SYSNAME) ))
> ? ? ? ? ? ? ? ? {
> ? ? ? ? ? ? return i;
> ? ? ? ? }
> ? ? }
>
> ? ? //
> ? ? // Name not found - oh, well
> ? ? //
> ? ? return 0;
> }
>
> ProcessNameOffset = FileSpyGetProcessNameOffset();
>
> PCHAR GetPathImageProcess( PCHAR PathImage )
> {
> ? ? ? ? PEPROCESS? ?
> ???curproc;
> ? ? ? ? char? ? ? ?
> ? ? *nameptr;
> ? ? ? ? DWORD? ? ?
> ? ? ? ? ? ???dw =
> 0;
> ? ? ? ? LPDWORD? ? ?
> ? ? ? ? ???tdw;
> ? ? ? ? ANSI_STRING? ? ?
> ? ? ???ansi;
> ? ? ? ? NTSTATUS? ? ?
> ? ? ? ? ? ntStatus;
> ? ? ? ? PRTL_USER_PROCESS_PARAMETERS
> pupp = NULL;
>
> ? ? ? ? if( ProcessNameOffset )
> ? ? ? ? {
> ? ? ? ? ? ? ? ?
> curproc = PsGetCurrentProcess();
> ? ? ? ? ? ? ? ?
> //nameptr = (PCHAR) curproc + ProcessNameOffset; //+0x1DC
> ? ? ? ? ? ? ? ?
> //??? NT 4
> ? ? ? ? ? ? ? ? if(
> 476==ProcessNameOffset )
> ? ? ? ? ? ? ? ? {
> ? ? ? ? ? ? ? ?
> ? ? ? ? tdw =
> (LPDWORD)(((PCHAR)curproc)+0x18C);? ? ?
> ? //??? 18C
> ? ? ? ? ? ? ? ?
> ? ? ? ? dw = *tdw;? ? ?
> //_PEB
> ? ? ? ? ? ? ? ?
> ? ? ? ? tdw =
> (LPDWORD)((PCHAR)dw+0x10);
> ? ? ? ? ? ? ? ?
> ? ? ? ? dw = *tdw;? ? ?
> //ProcessParameters
> ? ? ? ? ? ? ? ?
> ? ? ? ? tdw = (LPDWORD)((PCHAR)dw +
> 0x0);
> ? ? ? ? ? ? ? ?
> ? ? ? ? dw = *tdw;
> ? ? ? ? ? ? ? ? }
> ? ? ? ? ? ? ? ?
> else
> ? ? ? ? ? ? ? ? {
> ? ? ? ? ? ? ? ?
> ? ? ? ? //??? WIN 2000
> ? ? ? ? ? ? ? ?
> ? ? ? ? tdw =
> (LPDWORD)(((PCHAR)curproc)+0x1B0);? ? ?
> ? //???
> ? ? ? ? ? ? ? ?
> ? ? ? ? dw = *tdw;? ? ?
> //_PEB? 0x7ffdf000
> ? ? ? ? ? ? ? ?
> ? ? ? ? tdw =
> (LPDWORD)((PCHAR)dw+0x10);
> ? ? ? ? ? ? ? ?
> ? ? ? ? dw = *tdw;
> ? ? ? ? ? ? ? ?
> ? ? ? ? tdw = (LPDWORD)((PCHAR)dw +
> 0x0);
> ? ? ? ? ? ? ? ?
> ? ? ? ? dw = *tdw;
> ? ? ? ? ? ? ? ? }
> ? ? ? ? ? ? ? ?
> //??? ??? ??? ? ???
> ???
> ? ? ? ? ? ? ? ?
> pupp = (PRTL_USER_PROCESS_PARAMETERS)(tdw);
> ? ? ? ? ? ? ? ?
> ntStatus = RtlUnicodeStringToAnsiString( &ansi,
> &pupp->ImagePathName, TRUE);
> ? ? ? ? ? ? ? ? if(
> ntStatus==STATUS_SUCCESS )
> ? ? ? ? ? ? ? ? {
> ? ? ? ? ? ? ? ?
> ? ? ? ? dw = ansi.Length;
> ? ? ? ? ? ? ? ?
> ? ? ? ? if( dw > 2045 )
> ? ? ? ? ? ? ? ?
> ? ? ? ? ? ? ? ? dw =
> 2045;
> ? ? ? ? ? ? ? ?
> ? ? ? ? memcpy( PathImage, ansi.Buffer,
> dw );
> ? ? ? ? ? ? ? ?
> ? ? ? ? PathImage[dw] = 0;
> ? ? ? ? ? ? ? ?
> ? ? ? ? RtlFreeAnsiString( &ansi );
> ? ? ? ? ? ? ? ?
> }//??? ??? ??? ???
> ? ? ? ? }
> ? ? ? ? else
> ? ? ? ? {
> ? ? ? ? ? ? ? ?
> strcpy( PathImage, “???” );
> ? ? ? ? }
> ? ? ? ? return PathImage;
> }
>
> -------------------------------------------------------------------------------
>
> Hi, all.
> I build a file system filter driver based on FILEMON. In
> IRP_MJ_CREATE dispatch, I want to get the process full path
> name and the file full path name which is to be opened by
> the process, the code like this:
>
> ////////////////////////////////////////////////////////////////////////////////////
> PIO_STACK_LOCATION? currentIrpStack =
> IoGetCurrentIrpStackLocation(Irp);
> PIO_STACK_LOCATION? nextIrpStack?
> ???= IoGetNextIrpStackLocation(Irp);
> hookExt = HookDevice->DeviceExtension;
>
> case IRP_MJ_CREATE:
> ? ? ? ? ? ? fileObject =
> currentIrpStack->FileObject;
> ? ? ? ? ? ? fullPathName =
> ExAllocatePool(NonPagedPool, MAXPATHLEN );
> ??? ??? ???
> if(fullPathName)
> ??? ??? ??? {
> ??? ??? ???
> ??? FilemonGetFullPath( fileObject, hookExt,
> fullPathName );
> ? ? ? ? ? ? }
> ? ? ? ? ? ? …
> ??? ??? ???
> CurrentProcessName = GetCurrentProcessFileName( );
> ??? ??? ??? if
> ((CurrentProcessName != NULL))
> ??? ??? ??? {
> ??? ??? ???
> ??? //
> ??? ??? ???
> ??? …
> ? ? ? ? ? ? ? ?
> RtlInitUnicodeString(&ProcessUnicodeName,
> CurrentProcessName); //Errors happened here!
> ??? ??? ??? }
> ////////////////////////////////////////////////////////////////////////////////////
> PCWSTR GetCurrentProcessFileName()
>
> {
> ??? DWORD dwAddress =
> (DWORD)PsGetCurrentProcess();? ?
> ???//PEPROCESS
> ??? if((dwAddress == 0) || (dwAddress ==
> 0xFFFFFFFF))
> ??? ??? return NULL;
>
> ??? dwAddress += 0x1B0;? ? ?
> ? ? ? ? ? ? ? ?
> ? ? ? ? ? ? ?
> //PEPROCESS->Peb
> ??? if((dwAddress = (DWORD)dwAddress) ==
> 0)
> ??? ??? return NULL;
>
> ??? dwAddress += 0x10;? ? ?
> ? ? ? ? ? ? ? ?
> ? ? ? ? ? ?
> ???//Peb->ProcessParameters
> ??? if((dwAddress = (DWORD)dwAddress) ==
> 0)
> ??? ??? return NULL;
>
> ??? dwAddress += 0x3C;? ? ?
> ? ? ? ? ? ? ? ?
> ? ? ? ? ? ? ?
> //Peb->ProcessParameters.ImageFile
> ??? dwAddress = ((DWORD)dwAddress);
> ??? return (PCWSTR)dwAddress;
> }
> //////////////////////////////////////////////////////////////////////////////////////////////
> All is work fine except some conditions. For example, we
> want to debugg an application in VC6(or BCB) and
> set breakpoints at the fist line in winmain. When we press
> F5 to start debugging, before stop at the breakpoint we set,
> a fage fault occurs
> at the? “RtlInitUnicodeString(&ProcessUnicodeName,
> CurrentProcessName)”. At this point, we get the
> fullpathname:
> ? ? ? ? ?
> ???fullpathname? =
> “c:\dev\debug\test.exe”???// the application
> we debugg.
> ? ? ? ? ?
> ???CurrentProcessName != NULl, such as 0x8e8.
> : dd 0x8e8
> 0x8e8? ?
> ??? ???
> ???
> it means NULL! That means at this time
> EPROCESS->PEB->PROCESSPARAMETERS->IMAGEFILENAME
> still not be
> initilized with proper value. And exam the process list of
> the system using SOFTICE proc command, I see process
> “test.exe” is at RUNNING state with both USERTIME and
> KERNELTIME equal to Zero. Also,
> I can get the IRP_MJ_CREATE dispatch’ process id using
> PsGetCurrentProcessId(). Ccompare this pid
> with the process list we get from softice proc command, I
> find IRP_MJ_CREATE dispatch is running with
> the context in process “test.exe”! It means process
> “test.exe” want to open “c:\dev\debug\test.exe”.
> The IRQL is equal to PASSIVE_LEVEL.
> It is strange!
>
> Please give me some advices.
>
> —
>

> It is possible to get the full path from the undocumented structures that

is available, below is two messages that has been posted before to this
list that shows how to do it:

One of the ways is to access the RTL_USER_PROCESS_PARAMETERS in the user space of the target process, the structure is a part of the PEB and contains the full pathname of the EXE. The PEB address can be obtained by NtQueryInformationProcess.

This is how psapi!GetModuleFileNameEx works, at least pre-Vista, and, for instance, XP SP2 firewall (ipnathlp service) uses GetModuleFileNameEx to enforce the per-pathname rules.


Maxim S. Shatskih
Windows DDK MVP
xxxxx@storagecraft.com
http://www.storagecraft.com

Thanks for giving me a lot of inputs through these discussions.

So, it looks like I should move out of the kernel space & try to get the process name/path in user mode. I had thought of doing it in the kernel mode only to avoid the round trip to user mode.

The particular case I was trying to address is this -
The driver should sit in the create path of all files with a particular reparse point set on it. The driver in general would force a particular kind of read (say for example a download across network) before completing the IO request. However, for some applications like desktop search applications, i would want to deny a read to avoid downloads. I was thinking of using the process name to identify such processes.

xxxxx@yahoo.com wrote:

Thanks for giving me a lot of inputs through these discussions.

So, it looks like I should move out of the kernel space & try to get the process name/path in user mode. I had thought of doing it in the kernel mode only to avoid the round trip to user mode.

The particular case I was trying to address is this -
The driver should sit in the create path of all files with a particular reparse point set on it. The driver in general would force a particular kind of read (say for example a download across network) before completing the IO request. However, for some applications like desktop search applications, i would want to deny a read to avoid downloads. I was thinking of using the process name to identify such processes.

Have you seen this reply?

Date: Sun, 31 May 2009 00:36:28 +0400
From: Maxim S. Shatskih

One of the ways is to access the RTL_USER_PROCESS_PARAMETERS in the >
user space of the target process, the structure is a part of the PEB and
> contains the full pathname of the EXE. The PEB address can be
obtained > by NtQueryInformationProcess.

This works well enough, at least on XP SP2.

Regards,
– pa