Получить путь exe-файла по handle процесса в NT
От: MaxK  
Дата: 31.05.02 07:33
Оценка:
Задача такая. Есть хендл или PID процесса в NT-драйвере. Как по этим данным получить путь к exe-файлу, запустившего процесс. Путь надо получить именно в драйвере и он должен быть полным.
Заранее благодарен за советы и помощь
Re: Получить путь exe-файла по handle процесса в NT
От: vasketsov Россия http://ntprog.by.ru
Дата: 31.05.02 08:53
Оценка: 12 (2)
Здравствуйте MaxK, Вы писали:

MK>Задача такая. Есть хендл или PID процесса в NT-драйвере. Как по этим данным получить путь к exe-файлу, запустившего процесс. Путь надо получить именно в драйвере и он должен быть полным.

MK>Заранее благодарен за советы и помощь

Я так из вопроса и не понял, тебе по процессу надо его путь или путь родительского процесса.
Ну да это без разницы почти.
Итак, определяем имя файла по ProcessHandle.

NTSYSAPI
NTSTATUS
NTAPI
ZwQueryInformationProcess(
IN HANDLE ProcessHandle,
IN PROCESSINFOCLASS ProcessInformationClass, //тута 0 надо
OUT PVOID ProcessInformation, //буфер, формат ниже
IN ULONG ProcessInformationLength, //типа его размер
OUT PULONG ReturnLength OPTIONAL //типа NULL засунь.
);

брать ее из ntoskrnl.exe

typedef struct _PROCESS_BASIC_INFORMATION { // Information Class 0
NTSTATUS ExitStatus;
PPEB PebBaseAddress;
KAFFINITY AffinityMask;
KPRIORITY BasePriority;
ULONG UniqueProcessId;
ULONG InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

Так получаешь адрес PEB (PPEB PebBaseAddress) в адресном пространстве ТОГО процесса.
Если надо родителя — то тут можно взять ULONG InheritedFromUniqueProcessId — это Id родительского процесса.

Далее вот его формат.

typedef struct _PEB
{
/*000*/ BOOLEAN InheritedAddressSpace;
/*001*/ BOOLEAN ReadImageFileExecOptions;
/*002*/ BOOLEAN BeingDebugged;
/*003*/ BOOLEAN SpareBool; // Allocation size
/*004*/ HANDLE Mutant;
/*008*/ PVOID SectionBaseAddress;
/*00C*/ PPROCESS_MODULE_INFO ProcessModuleInfo;
/*010*/ PPROCESS_PARAMETERS ProcessParameters;
/*014*/ ULONG SubSystemData;
/*018*/ HANDLE ProcessHeap;
/*01C*/ PCRITICAL_SECTION FastPebLock;
/*020*/ PVOID AcquireFastPebLock; // function
/*024*/ PVOID ReleaseFastPebLock; // function
/*028*/ ULONG EnvironmentUpdateCount;
/*02C*/ PPVOID KernelCallbackTable; // functions
/*030*/ ULONG SystemReserved[2];
/*038*/ ULONG FreeList;
/*03C*/ ULONG TlsExpansionCounter; // number of bits
/*040*/ PRTL_BITMAP TlsBitmap; // ntdll!TlsBitMap
/*044*/ ULONG TlsBitmapBits[2]; // 64 bits
/*04C*/ ULONG ReadOnlySharedMemoryBase;
/*050*/ ULONG ReadOnlySharedMemoryHeap;
/*054*/ PTEXT_INFO TextInfo;
/*058*/ PVOID InitAnsiCodePageData;
/*05C*/ PVOID InitOemCodePageData;
/*060*/ PVOID InitUnicodeCaseTableData;
/*064*/ ULONG KeNumberProcessors;
/*068*/ ULONG NtGlobalFlag;
/*06C*/ ULONG NtGlobalFlagX;
/*070*/ LARGE_INTEGER MmCriticalSectionTimeout;
/*078*/ ULONG MmHeapSegmentReserve;
/*07C*/ ULONG MmHeapSegmentCommit;
/*080*/ ULONG MmHeapDeCommitTotalFreeThreshold;
/*084*/ ULONG MmHeapDeCommitFreeBlockThreshold;
/*088*/ ULONG NumberOfHeaps;
/*08C*/ ULONG MaximumNumberOfHeaps; // 16, *2 if exhausted
/*090*/ PHANDLE ProcessHeapsListBuffer;
/*094*/ ULONG GdiSharedHandleTable;
/*098*/ ULONG ProcessStarterHelper;
/*09C*/ ULONG GdiDCAttributeList;
/*0A0*/ PCRITICAL_SECTION LoaderLock;
/*0A4*/ ULONG NtMajorVersion;
/*0A8*/ ULONG NtMinorVersion;
/*0AC*/ WORD NtBuildNumber;
/*0AE*/ WORD CmNtCSDVersion;
/*0B0*/ ULONG PlatformId;
/*0B4*/ ULONG Subsystem;
/*0B8*/ ULONG MajorSubsystemVersion;
/*0BC*/ ULONG MinorSubsystemVersion;
/*0C0*/ KAFFINITY AffinityMask;
/*0C4*/ HANDLE GdiHandleBuffer[0x22];
/*14C*/ PVOID PostProcessInitRoutine;
/*150*/ PVOID TlsExpansionBitmap;
/*154*/ UCHAR TlsExpansionBitmapBits[0x80];
/*1D4*/ ULONG SessionId;
/*1D8*/ ULONG d1D8;
/*1DC*/ ULONG d1DC;
/*1E0*/ PWORD CSDVersion;
/*1E4*/ ULONG d1E4;
/*1E8*/ } PEB, * PPEB, **PPPEB;

тебя должно интересовать PPROCESS_PARAMETERS ProcessParameters.
вот и его формат.

typedef struct _PROCESS_PARAMETERS {
ULONG AllocationSize;
ULONG Size;
ULONG Flags;
ULONG Reserved;
long Console;
ULONG ProcessGroup;
HANDLE hStdInput;
HANDLE hStdOutput;
HANDLE hStdError;
UNICODE_STRING CurrentDirectoryName;
HANDLE CurrentDirectoryHandle;
UNICODE_STRING DllPath;
UNICODE_STRING ImageFile;
UNICODE_STRING CommandLine;
PWSTR Environment;
ULONG dwX;
ULONG dwY;
ULONG dwXSize;
ULONG dwYSize;
ULONG dwXCountChars;
ULONG dwYCountChars;
ULONG dwFillAttribute;
ULONG dwFlags;
ULONG wShowWindow;
UNICODE_STRING WindowTitle;
UNICODE_STRING Desktop;
UNICODE_STRING Reserved2;
UNICODE_STRING Reserved3;
} PROCESS_PARAMETERS, *PPROCESS_PARAMETERS;

А тут уже сам смотри, чего надо
UNICODE_STRING ImageFile;
UNICODE_STRING CommandLine;

Читать все через ZwReadVirtualMemory.

На самом деле это по барабану, в ядре или нет так делать.
Если в ядре — выхода в usermode не будет все равно.

Вот так.

Можно "проще", но это только для ядра.
Короче, берешь текущий EPROCESS.
У него по адресу 0xA0 сидит LIST_ENTRY ActiveProcessesList
Там и пробегайся по этим entries.
Только аккуратнее, там ссылки не на EPROCESS, а опять же на сами entries в этом списке. То есть смещение отнять придется. Вот так, пробежался и нашел процесс по идентификатору. А для найденного из EPROCESS берешь ссылку на PEB — и дальше как и раньше.
Васкецов Сергей
http://registry.km.ru
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.