Получения handle процесса и грамотное его закрытие.

Тема в разделе "WASM.WIN32", создана пользователем L1kvID, 24 май 2010.

  1. L1kvID

    L1kvID New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2009
    Сообщения:
    2
    Перехватил NtOpenProcess.
    Теперь необходимо получить полный путь процесса, который NtOpenProcess вызывает, и полный путь процесса, по отношению к которому эта функция вызывается.

    Делаю через PsLookupByProcessId и ObOpenObjectByPointer, а потом вызываю ZwQueryInformationProcess с параметром imagePath. Все работает, но возникает проблема: открытые хендлы функцией ObOpenObjectByPointer съедают память, а если применять к хендлам ZwClose(), то наблюдается интересная ситуация. Если закрываем хендлы, которые получили от ClientId, переданные NtOpenProcess все ок, а если закрывать хендлы которые получили, создав собственный ClientId с параметром UniqueProcess=(HANDLE) PsGetCurrentProcessI и UniqueThread=NULL, то все тоже работает. Но после запуска и завершения taskmanar`а система виснет как убитая. Помогите, что делать, чтобы этого не случалось?
     
  2. freyr

    freyr New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2010
    Сообщения:
    95
    NtOpenProcess

    процесс который вызывает эту функцию это (HANDLE)-1
    процесс который хочет открыть получаем из ClientId->UniqueProcess (PID) для него нужно получить HANDLE


    схематично так:

    PsLookupProcessByProcessId -> ObOpenObjectByPointer -> ObfDereferenceObject -> ZwQueryInformationProcess -> ZwClose


     
  3. L1kvID

    L1kvID New Member

    Публикаций:
    0
    Регистрация:
    27 апр 2009
    Сообщения:
    2
    Я так тоже делал. Но проблема в том, что драйвер все-равно при работе с taskmgr.exe вылетает в синьку с ошибкой 0x50 (PAGE_FAULT_IN_NONPAGED_AREA), а если оба хендла получать одинаковов через ObOpenObjectByPointer и не закрывать, то все работает без сбоев
     
  4. 0x6b65

    0x6b65 Забанен

    Публикаций:
    0
    Регистрация:
    8 окт 2009
    Сообщения:
    92
    Какой AccessMode (KernelMode или UserMode) был передан в функцию ObOpenObjectByPointer()? Должен быть KernelMode, если используются Zw-функции. Желательно вообще показать свой код реализации получения-закрытия описателя процесса.

    Еще нужен анализ bugcheck'а PAGE_FAULT_IN_NONPAGED_AREA: выхлоп !analyze -v.

    Телепатическими способностями тут мало кто обладает ;)
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    0x6b65
    Какраз наоборот. Сервисы - это пользовательский функционал, при ошибках в ядре ось закончит свою работу, фолты в ядре не допустимы.
     
  6. 0x6b65

    0x6b65 Забанен

    Публикаций:
    0
    Регистрация:
    8 окт 2009
    Сообщения:
    92
    Clerk
    Zw-функции это вызов Nt-сервисов через wrap'ер, который выставляет значение PreviousMode у текущей нити в KernelMode. Буферы, передаваемые в ZwQueryInformationProcess(), как я понимаю, используются выделенные в пуле или на стеке, т.е. Probe-функции на них вызвать не нужно (PreviousMode==KernelMode это гарантирует). Или я не понял твою фразу?

    И еще: если у описателя есть маска:
    Код (Text):
    1. #define KERNEL_HANDLE_MASK ((ULONG_PTR)((LONG)0x80000000))
    То будет использована системная таблица описателей, иначе - текущего процесса. Эта маска будет в описателе, созданном с PreviousMode == KernelMode. Для Zw-функций все описатели должны иметь эту маску.
    Что бы создать такой описатель в данном случае, нужно указывать в ObOpenObjectByPointer(AccessMode == KernelMode)
     
  7. freyr

    freyr New Member

    Публикаций:
    0
    Регистрация:
    23 фев 2010
    Сообщения:
    95
    Выдранно из вполне работающей проактивки, и даже по некоторым тестам являющейся лидером :)

    Код (Text):
    1. BOOLEAN GetProcessNameEx(HANDLE ProcessId, PWCHAR ProcessPath, ULONG ProcessPathLength)
    2. {
    3.     /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    4.     BOOLEAN         Status;
    5.     HANDLE          ProcessHandle;
    6.     PEPROCESS       Process;
    7.     /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
    8.  
    9.     Process = NULL;
    10.     ProcessHandle = NULL;
    11.    
    12.     if ( NT_SUCCESS(PsLookupProcessByProcessId(ProcessId, &Process)) )
    13.     {
    14.         if ( NT_SUCCESS(ObOpenObjectByPointer(Process, OBJ_KERNEL_HANDLE, 0, 0x1F0FFF, 0, 0, &ProcessHandle))
    15.             || NT_SUCCESS(ObOpenObjectByPointer(Process, OBJ_KERNEL_HANDLE, 0, 0, 0, 0, &ProcessHandle)) )
    16.         {
    17.             ObfDereferenceObject(Process);
    18.             Status = GetProcessName(ProcessHandle, ProcessPath, ProcessPathLength);
    19.             ZwClose(ProcessHandle);
    20.         }
    21.         else
    22.         {
    23.             ObfDereferenceObject(Process);
    24.             Status = FALSE;
    25.         }
    26.     }
    27.     else
    28.     {
    29.         Status = FALSE;
    30.     }
    31.     return (Status);
    32. }
    сверьтесь, код лично юзал, работает отлчино. если же вас все еще бсодит, смею предположить что проблема не в нем :)