Проблема с NtQueryInformationProcess

Тема в разделе "WASM.WIN32", создана пользователем cc, 18 окт 2006.

  1. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    Продолжаю серию своих вопросов :). Ну просто что-то никак не получается до конца доделать, только немного продвигаюсь, тут же возникают новые вопросы :dntknw:. На этот раз проблема в следующем: мне нужно получить полный путь создаваемого процесса, я использую NtQueryInformationProcess, через структуру PROCESS_BASIC_INFORMATION получаю указатель на PEB, далее из PEB получаю RTL_USER_PROCESS_PARAMETERS. Насколько я понял, полный путь создаваемого процесса должен лежать в ImagePathName, так вот, я его оттуда извлекаю, а там содержится почему-то путь не создаваемого процесса, а процесса, создавшего его! В чем дело, ума не приложу. Вроде во всех доках написано что это имя создаваемого процесса. Вот мой код (перехват функции ZwCreateThread):
    Код (Text):
    1. NTSTATUS __stdcall xZwCreateThread(PHANDLE ThreadHandle, ACCESS_MASK DesiredAccess,
    2.     POBJECT_ATTRIBUTES ObjectAttributes, HANDLE ProcessHandle, PCLIENT_ID ClientId,
    3.     PCONTEXT ThreadContext, PINITIAL_TEB InitialTeb, BOOLEAN CreateSuspended)
    4. {
    5.     NTSTATUS ns;
    6.     PROCESS_BASIC_INFORMATION ProcBasicInfo;
    7.     DWORD RetLen, BytesCount;
    8.     PEB Peb;
    9.     PRTL_USER_PROCESS_PARAMETERS pRtlUserProcParams;
    10.  
    11.     Set_ZwCreateThread(false);
    12.     ns=__ZwCreateThread(ThreadHandle, DesiredAccess, ObjectAttributes, ProcessHandle,
    13.         ClientId, ThreadContext, InitialTeb, CreateSuspended);
    14.     Set_ZwCreateThread(true);
    15.     ZeroMemory(&ProcBasicInfo, sizeof(PROCESS_BASIC_INFORMATION));
    16.     __ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &ProcBasicInfo,
    17.         sizeof(PROCESS_BASIC_INFORMATION), &RetLen);
    18.     ReadProcessMemory(ProcessHandle, ProcBasicInfo.PebBaseAddress, &Peb, sizeof(PEB),
    19.         &BytesCount);
    20.     pRtlUserProcParams=Peb.ProcessParameters;
    21.     char buf[256];
    22.     wsprintf(buf, "%ws", pRtlUserProcParams->ImagePathName.Buffer);
    23.     /* вот в этом месте вылазит сообшение с полным путем процесса, создающего новый процесс, а мне нужен путь создаваемого процесса */
    24.     MessageBox(0, buf, 0, 0);
    25.     return ns;
    26. }
    Подскажите в чем моя ошибка и как надо было бы сделать правильно.
     
  2. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    А такой результат получаешь только на новых процессах или на существующих тоже?
     
  3. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    Сейчас проверил - всегда получаю этот результат. Проблема оказывается еще глубже чем я предполагал: всегда, для какого бы процесса не вызывал приведенный код, всегда возвращается путь того процесса, из которого идет вызов! В чем моя ошибка?
     
  4. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Прочитай ImagePathName также как PEB через ReadProcessMemory
     
  5. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    В смысле? Там же не PUNICODE_STRING а UNICODE_STRING, откуда читать тогда?
     
  6. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Код (Text):
    1. typedef struct _UNICODE_STRING {
    2. ULONG Length;
    3. ULONG MaximumLength;
    4. PWCHAR Buffer; // ---- указатель на имя!!! Читай по этому адресу Length байт
    5. }
    Еще ProcessParameters тоже указатель, значит по его адресу нужно также прочитать структуру RTL_USER_PROCESS_PARAMETERS через ReadProcessMemory(). Естественно, перед тем как читать Buffer
     
  7. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Просто вся фишка в том, что адреса PEB как правило совпадают в разных процессах.
     
  8. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    Ну в общем сделал как ты сказал, для других, уже созданных процессов работает, нормально показывает их полный путь, для создаваемых же, то бишь для тех, хэндл которых я перехватывал в ZwCreateThread, - нифига, выдает просто пустую строку :dntknw:. В чем проблема? Может быть надо дождаться сначала вызова ZwResumeThread чтобы проинициализировался главный поток процесса и только тогда получится получить путь? Но мне нельзя ждать инициализации главного потока, ведь это что-то типа системы безопасности и еще ДО запуска процесса (ну или его главного потока) надо в базе проверить, можно ли этому приложению запускаться или нет. Что подскажешь?
     
  9. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    В CreateProcessW перед NtCreateThread вызывается функция BasePushProcessParameters, которая и заталкивает PEB в адресное пространство нового процесса. После этого PEB никто больше уже вроде бы и не трогает. Если только csrss... Хотя как проверить это не знаю.

    По этому поводу можно не заморачиваться. Срубить процесс можно в любой момент, в том числе и в хуке на ZwResumeThread(). Попробуй перехватить ZwResumeThread() и сделать в нем все то же самое, думаю, вопросов не возникнет. Там в случае убиения процесса не вызывая оригинальную функцию, сразу вызывается TerminateThread(). Так как это единственный поток в процессе, то процесс также завалится и не будет даже leak`ов на неосвобожденный стек
     
  10. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    Попробовал. Та же самая фигня, возвращается пустая строка :dntknw:. Блин, че ж делать то? Должно же существовать какое-то решение...
     
  11. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Попробуй CommandLine посмотреть.
     
  12. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    Код покажи.
     
  13. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    CommandLine смотрел, также пустой. Вот мой код:
    Код (Text):
    1. PROCESS_BASIC_INFORMATION ProcBasicInfo;
    2. DWORD RetLen, BytesCount;
    3. PEB Peb;
    4. RTL_USER_PROCESS_PARAMETERS RtlUserProcParams;
    5.  
    6. ZeroMemory(&ProcBasicInfo, sizeof(PROCESS_BASIC_INFORMATION));
    7. __ZwQueryInformationProcess(ProcessHandle, ProcessBasicInformation, &ProcBasicInfo,
    8.     sizeof(PROCESS_BASIC_INFORMATION), &RetLen);
    9. ReadProcessMemory(ProcessHandle, ProcBasicInfo.PebBaseAddress, &Peb, sizeof(PEB),
    10.     &BytesCount);
    11. ReadProcessMemory(ProcessHandle, Peb.ProcessParameters, &RtlUserProcParams,
    12.     sizeof(RTL_USER_PROCESS_PARAMETERS), &BytesCount);
    13. WCHAR wszBuffer[256];
    14. ReadProcessMemory(ProcessHandle, RtlUserProcParams.ImagePathName.Buffer, wszBuffer,
    15.     RtlUserProcParams.ImagePathName.Length, &BytesCount);
    16. char buf[256];
    17. wsprintf(buf, "%ws", wszBuffer);
    18. MessageBox(0, buf, 0, 0); // просто для тестирования вывожу эту строку сообщением
     
  14. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Код (Text):
    1. ReadProcessMemory(ProcessHandle, RtlUserProcParams.ImagePathName.Buffer, wszBuffer,
    2.     RtlUserProcParams.ImagePathName.Length, &BytesCount);
    Здесь RtlUserProcParams.ImagePathName.Length не равен нулю? Проверь еще похож ли на правду адрес RtlUserProcParams.ImagePathName.Buffer и статус ReadProcessMemory. Есть подозрение, что с Peb все в порядке, но какой-то косяк с чтением
     
  15. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    PEB.ImageBaseAddress равен чему-либо?
     
  16. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Стопудово Peb заполняется полностью еще до вызова ZwCreateThread(), в том числе все строки.
     
  17. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    <затупил>
     
  18. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    n0name: Peb.ImageBaseAddress равен 0x100000, то бишь не нулевой. Значение верное (посмотрел, у запускаемого файла действительно это значение базы)

    gilg: как ни странно, RtlUserProcParams.ImagePathName.Length=58, адрес RtlUserProcParams.ImagePathName.Buffer равен 0x87C, статус у всех трех ReadProcessMemory - true

    Хм, странно все это однако... Вроде все нормально, а ведь не работает зараза... :dntknw:
     
  19. cc

    cc New Member

    Публикаций:
    0
    Регистрация:
    15 окт 2006
    Сообщения:
    34
    Пардон, был неправ. В третьем вызове ReadProcessMemory (где читаю строку) статус false.
     
  20. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    gilg
    угу, чё то я тоже когда прочитал твой пост, подумал что так и есть, только минуты через 3 дошло что в контесте то этого процесса и выполняется перехват.
    GetLastError?