Здравствуйте, ononim, Вы писали:
B>>После выхода из NtQueryInformationProcess
B>>Возращается NTSTATUS == STATUS_SUCCESS ,dwSize == RLength. функция выполняется.Без падений и синих экранов.
B>>А вот с processinfo засада
ProcessInfo->PebBaseAddress == NULL.
B>>С помощью гугла ещё до обращения сбда находил какието лекарства, связанные со смещением этого поля в зависимости от версии OS.
B>>Но они не помогли.
O>Очень похоже на то что вы из 32хбитного процесса пытаетесь получить PEB 64хбитного.
O>Надо понимать, что у 32хбитных процессов в 64хюитной винде два PEB(а) (ну и сразу скажу — у потоков таких процессов — по два TEB'а). Один PEB — 64хбитный, второй — 32хбитный.
O>32хбитная версия NtQueryInformationProcess выдает адрес 32хбитного PEB'а. 64хбитная — 64хбитного соответственно.
O>У 64хбитных процессов нету 32хбитного PEB-а, поэтому 32хбитная NtQueryInformationProcess для таких процессов возвращает PebBaseAddress=NULL.
O>Адекватное решение (а не тот хак что я ниже писал) — в 64хбитной винде юзать 64хбитные приложения. 64хбитный PEB — он есть у всех. Правда возникает вопрос зачем вам этот PEB. Например, помимо того что в 32хбитных процессах есть два PEBa(и по два TEB-а), у них еще есть и по два PEB loader list'а. Причем они разные. Один содержит 64хбитные длл (там обычно только ntdll wow64 и прочие кишки wow64 подсистемы), а второй — 32хбитные. Впрочем оба содержат ентри на имаж ехешника. Так что это нужно тоже учитывать, и если захочется из 64хбитного процесса получить адрес 32хбитного PEB-а, то можно воспользоваться NtQueryInformationProcess(ProcessWow64Information). По документации она возвращает 0 для 64хбитных процессов, и не 0 для 32хбитных. А по факту для последних она возвращает адрес на их 32хюитный PEB. Надо понимать что если захочется воспользоваться этой информацией из 64хбитного кода, то структуру 32хбитного PEBа и все структуры к нему относящиеся придется кропотливо вручную дефайнить.
Нда, бяда пячаль. Ну что, будем думать что делать дальше.
У меня была робкая надежда что внутри NtQueryInformationProces будет как раньше,по хэндлу получаться PEPROCESS а оттуда уже распихивание в структуру
PROCESS_BASIC_INFORMATION.
case ProcessBasicInformation:
if ( ProcessInformationLength != (ULONG) sizeof(PROCESS_BASIC_INFORMATION) ) {
return STATUS_INFO_LENGTH_MISMATCH;
}
st = ObReferenceObjectByHandle(
ProcessHandle,
PROCESS_QUERY_INFORMATION,
PsProcessType,
PreviousMode,
(PVOID *)&Process,
NULL
);
if ( !NT_SUCCESS(st) ) {
return st;
}
BasicInfo.ExitStatus = Process->ExitStatus;
BasicInfo.PebBaseAddress = Process->Peb;
BasicInfo.AffinityMask = Process->Pcb.Affinity;
BasicInfo.BasePriority = Process->Pcb.BasePriority;
BasicInfo.UniqueProcessId = (ULONG_PTR)Process->UniqueProcessId;
BasicInfo.InheritedFromUniqueProcessId = (ULONG_PTR)Process->InheritedFromUniqueProcessId;
ObDereferenceObject(Process);
//
// Either of these may cause an access violation. The
// exception handler will return access violation as
// status code. No further cleanup needs to be done.
//
try {
*(PPROCESS_BASIC_INFORMATION) ProcessInformation = BasicInfo;
if (ARGUMENT_PRESENT(ReturnLength) ) {
*ReturnLength = sizeof(PROCESS_BASIC_INFORMATION);
}
} except(EXCEPTION_EXECUTE_HANDLER) {
return STATUS_SUCCESS;
}
return STATUS_SUCCESS;
Вот так и рушатся надежды. На лёгкий выход из сложной ситуации.