Image Path Name of processes.

Hi all,

I’m writing a device driver at kernel mode and I need to know some informations’ processes like the Image Path Name (in the PEB that is in the process address space at 0x7FFDF000) but not only that the current process but also of the other processes which I’ve the handle.

How can I read PEB structure of the other processes?

Someone can help me???

Thanks, Aurox

At 11.08 13/06/2002, you wrote:

I’m writing a device driver at kernel mode and I need to know some
informations’ processes like the Image Path Name (in the PEB that is in
the process address space at 0x7FFDF000) but not only that the current
process but also of the other processes which I’ve the handle.
How can I read PEB structure of the other processes?

First of all: you need to use undocumented calls and procedures. Do it at
your own risk. Possibly re-evaluate the problem, ask yourself if there
aren’t better ways to achieve what you need. Don’t do it in a commercial
product, because it will very likely break in future versions of Windows,
or not work at all even in some present and past versions

NtReadVirtualMemory. Since ntoskrnl.exe doesn’t export it, you have to roll
your own. ReactOS (http:</http:>) ntoskrnl’s version reads like
this, it should work, or at least give you enough hints:

NTSTATUS STDCALL
NtReadVirtualMemory(IN HANDLE ProcessHandle,
IN PVOID BaseAddress,
OUT PVOID Buffer,
IN ULONG NumberOfBytesToRead,
OUT PULONG NumberOfBytesRead)
{
NTSTATUS Status;
PMDL Mdl;
PVOID SystemAddress;
PEPROCESS Process;

Status = ObReferenceObjectByHandle(ProcessHandle,
PROCESS_VM_WRITE,
NULL,
UserMode,
(PVOID*)(&Process),
NULL);
if (Status != STATUS_SUCCESS)
{
return(Status);
}

Mdl = MmCreateMdl(NULL,
Buffer,
NumberOfBytesToRead);
MmProbeAndLockPages(Mdl,
UserMode,
IoWriteAccess);

KeAttachProcess(Process);

SystemAddress = MmGetSystemAddressForMdl(Mdl);
memcpy(SystemAddress, BaseAddress, NumberOfBytesToRead);

KeDetachProcess();

if (Mdl->MappedSystemVa != NULL)
{
MmUnmapLockedPages(Mdl->MappedSystemVa, Mdl);
}
MmUnlockPages(Mdl);
ExFreePool(Mdl);

ObDereferenceObject(Process);

*NumberOfBytesRead = NumberOfBytesToRead;
return(STATUS_SUCCESS);
}

PS: if you also need a definition of all the fields in the PEB, have a look
at ReactOS’s napi/teb.h header:

http://mok.lvcm.com/cgi-bin/reactos/ros-cvs/~checkout~/reactos/include/napi/
teb.h

Hello from Cuba!

To get the address of a process’s PEB you have to use the system service ZwQueryInformationProcess which prototype is as follows:

NTSYSAPI
NTSTATUS
NTAPI
ZwQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass,
OUT PVOID ProcessInformation,
IN ULONG ProcessInformationLength,
OUT PULONG ReturnLength OPTIONAL
);

The PROCESSINFOCLASS you need is ProcessBasicInformation which returns the following structure at ProcessInformation:

struct _PROCESS_BASIC_INFORMATION {
ULONG ExitStatus;
struct _PEB *PebBaseAddress;
ULONG AffinityMask;
ULONG BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
};

At the PebBaseAddress field you will find the PEB of the target process.

Hope this helps.

Ciao e buona fortuna!

-Albert Almeida

Hi All,
I am developing a HIDMini Driver for a USB Device.The Class I
have mentioned in my .inf file is HIDClass.On connecting my device to the
host,I receive AddDevice.How do I attach to the USB stack ?.Because the PDO
I receive is nothing but FDO created by HIDClass.If I try to attach my
device object to it,after my AddDevice routine,there is a PageFault in
HIDClass.How do write a HIDMini Driver which communicates with the USB
stack.I need to get the configuration,interface information from the device
which I can get through the USB stack.

Thanks & Regards,
Sai
**************************************************************************
This email (including any attachments) is intended for the sole use of the
intended recipient/s and may contain material that is CONFIDENTIAL AND
PRIVATE COMPANY INFORMATION. Any review or reliance by others or copying or
distribution or forwarding of any or all of the contents in this message is
STRICTLY PROHIBITED. If you are not the intended recipient, please contact
the sender by email and delete all copies; your cooperation in this regard
is appreciated.
**************************************************************************

Çäðàâñòâóéòå, aurox502.

Âû ïèñàëè 13 èþíÿ 2002 ã., 13:08:08:

aii> Hi all,

aii> I’m writing a device driver at kernel mode and I need to know some informations’ processes like the Image Path Name (in the PEB that is in the process address space at 0x7FFDF000) but not only
aii> that the current process but also of the other processes which I’ve the handle.

aii> How can I read PEB structure of the other processes?

aii> Someone can help me???

aii> Thanks, Aurox

aii> —
aii> You are currently subscribed to ntdev as: xxxxx@comstek.ru
aii> To unsubscribe send a blank email to %%email.unsub%%

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;
}


Ñ óâàæåíèåì,
Shilov mailto:xxxxx@comstek.ru

>> How can I read PEB structure of the other processes?

KeAttachProcess() / KeDetachProcess . for NT 4.0 warning those can bugcheck
if you are laready attached to a process and you attach again. In Win2k+,
use their safe counterparts, KeStackAttachProcess / KeStackDetachProcess.
Those are stackable versions of KeAttachProcess / KeDetachProcess. System
processes does not have a PEB. Any access to user address space should be
probed first. dont forget about SEH. Those APIs are prototyped only in IFS
kit , IIRC

Dan

----- Original Message -----
From: “Shilov Konstantin”
To: “NT Developers Interest List”
Sent: Wednesday, July 10, 2002 10:40 PM
Subject: [ntdev] Re: Image Path Name of processes.

> Çäðàâñòâóéòå, aurox502.
>
> Âû ïèñàëè 13 èþíÿ 2002 ã., 13:08:08:
>
> aii> Hi all,
>
> aii> I’m writing a device driver at kernel mode and I need to know some
informations’ processes like the Image Path Name (in the PEB that is in the
process address space at 0x7FFDF000) but not only
> aii> that the current process but also of the other processes which I’ve
the handle.
>
> aii> How can I read PEB structure of the other processes?
>
> aii> Someone can help me???
>
> aii> Thanks, Aurox
>
>
> aii> —
> aii> You are currently subscribed to ntdev as: xxxxx@comstek.ru
> aii> To unsubscribe send a blank email to %%email.unsub%%
>
> 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;
> }
>
> –
> Ñ óâàæåíèåì,
> Shilov mailto:xxxxx@comstek.ru
>
>
>
> —
> You are currently subscribed to ntdev as: xxxxx@rdsor.ro
> To unsubscribe send a blank email to %%email.unsub%%
>