Re[6]: NtQueryInformationProcess
От: Burbulis1978  
Дата: 21.08.17 19:51
Оценка:
Здравствуйте, 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;

Вот так и рушатся надежды. На лёгкий выход из сложной ситуации.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.