Информация об изменениях

Сообщение Re[7]: NtQueryInformationProcess от 22.08.2017 6:37

Изменено 22.08.2017 6:42 Alexander G

Re[7]: NtQueryInformationProcess
Здравствуйте, Burbulis1978, Вы писали:

B>У меня была робкая надежда что внутри NtQueryInformationProces будет как раньше,по хэндлу получаться PEPROCESS а оттуда уже распихивание в структуру

B>PROCESS_BASIC_INFORMATION.

Скорее всего, происходящее в ядре особо существенно не поменялось. (Приведенный код — видимо, код ядра Windows или Reactos).

Но на 64-разрядных системах ядро тоже 64-разрядное! Непосредственно с ядром в таких системах взаимодействует всегда 64-разрядная ntdll.

Для работы 32-разрядных приложений в таких системах существует Wow64 уровень, и приложения работают с 32-разрядной ntdll, остальные системные dll тоже 32-разрядные.

Т.к. x86-64 процессор сам по себе поддерживает x86 режим, то для Wow64 уровня задач не очень много, но он явно делает это:
1. Осуществляет трансляцию между 32битными и 64битными структурами для системных вызовов. Поинтеры там перебить на 64-разрядные, SIZE_T, и т.д.
2. Подсовывает 32-разрядную System32 папку (File System Redirection)
3. Подсовывает 32-разрядные ключи реестра (Registry Redirection)

Переключение в 64-битный режим делается раньше вышеприведенных трансляций.

Про TEB / PEB. Это служебные структуры, используемые, в основном, в User Mode для всевозможных контекстов.
Для быстрого доступа к TEB, его адрес записан в сегментном регистре, для того, чтобы этот быстрый доступ к TEB было удобно сделать высокоуровневым, в одном из полей TEB указатель на себя. Местами TEB используется в реализации служебных функций (там есть поле для GetLastError), местами обращения к нему неявно вставляются компилятором (это Structured Exception Handling и (статический) Thread Local Storage).
В каждом TEB есть указатель на PEB. PEB тоже хранит всяческие служебные контексты, уже для процесса. в поле Ldr хранятся списки загруженных модулей.

Поскольку TEB и PEB такие базовые вещи, что будут нужны и ехешнику непосредственно (SEH, TLS), и используемым в нём 32-разрядным системным модулям, и 64-битной ntdll вместе с Wow64 слоем, и при этом они являются структурами с указателями, в Wow64 процессе нужны отдельно 32-битный и 64-битный TEB/TEB. И они разные. Некоторые поля могут быть только в 64-битном или только в 32-битном TEB. Ну и из-за специфики Wow64, некоторые служебные поля в этих парных TEB/TEB могут иметь не тот смысл, что в "чистом 32-битном" или "чистом 64-битном".
Важный момент отличия 32-битного и 64-битного TEB: в 32-битном TEB хранится список загруженных 32-битных модулей, в 64-битном — список 64-битных, который очень небольшой (64-битная ntdll, три-четыре dllки Wow64 слоя, ну и сам ехешник содержится и в 64-битном, и в 32-битном списке).

Поскольку клиенты NtQueryInformationProcess будут ожидать такой PEB, какой разрядности запрос, ну то есть какой разрядности сами клиенты, их нельзя удовлетворить, если 32-битный клиент спрашивает за 64-битный процесс. Поэтому 32-разрядная NtQueryInformationProcess не возвращает TEB для 64-разрядного процесса.

С учётом всего этого:
1. Смотря что с PEB делать, для Wow64 процесса может быть нужен либо 32-битный, либо 64-битный PEB, либо безразлично. Если нужен конкретный, обычно это 32-битный.
2. С PEB со всеми этими поинтерами в нём удобно работать в контексте процесса, к которому этот PEB относится. Внедрить dll-ку и работать через NtCurrentTeb()->Peb. Тогда для х64 систем нужны две dll-ки, 32-разрядная для 32-разрядных процессов, 64-разрядная для 64-разрядных процессов. В случае интенсивной работы с Ldr единственный нормальный вариант (не будешь же Loader Lock захватывать интерпроцессно).
3. В случае отсутствия надобности лезть в потроха загрузчика, но при этом наличия интенсивной работы с различными NT API, следует использовать 64-разрядный процесс на 64-разрядных системах. Если в итоге нужно, чтобы основное приложение было одно 32-битныое, следует завести вспомогательное 64-битное, и использовать IPC.
4. В принципе "какой-нибудь PEB другого процесса" можно получить из процесса любой разрядности без внедрения dll и без NtQueryInformationProcess. Главный вопрос — что дальше.
Re[7]: NtQueryInformationProcess
Здравствуйте, Burbulis1978, Вы писали:

B>У меня была робкая надежда что внутри NtQueryInformationProces будет как раньше,по хэндлу получаться PEPROCESS а оттуда уже распихивание в структуру

B>PROCESS_BASIC_INFORMATION.

Скорее всего, происходящее в ядре особо существенно не поменялось. (Приведенный код — видимо, код ядра Windows или Reactos).

Но на 64-разрядных системах ядро тоже 64-разрядное! Непосредственно с ядром в таких системах взаимодействует всегда 64-разрядная ntdll.

Для работы 32-разрядных приложений в таких системах существует Wow64 уровень, и приложения работают с 32-разрядной ntdll, остальные системные dll тоже 32-разрядные.

Т.к. x86-64 процессор сам по себе поддерживает x86 режим, то для Wow64 уровня задач не очень много, но он явно делает это:
1. Осуществляет трансляцию между 32битными и 64битными структурами для системных вызовов. Поинтеры там перебить на 64-разрядные, SIZE_T, и т.д.
2. Подсовывает 32-разрядную System32 папку (File System Redirection)
3. Подсовывает 32-разрядные ключи реестра (Registry Redirection)

Переключение в 64-битный режим делается раньше вышеприведенных трансляций.

Про TEB / PEB. Это служебные структуры, используемые, в основном, в User Mode для всевозможных контекстов.
Для быстрого доступа к TEB, его адрес записан в сегментном регистре, для того, чтобы этот быстрый доступ к TEB было удобно сделать высокоуровневым, в одном из полей TEB указатель на себя. Местами TEB используется в реализации служебных функций (там есть поле для GetLastError), местами обращения к нему неявно вставляются компилятором (это Structured Exception Handling и (статический) Thread Local Storage).
В каждом TEB есть указатель на PEB. PEB тоже хранит всяческие служебные контексты, уже для процесса. в поле Ldr хранятся списки загруженных модулей.

Поскольку TEB и PEB такие базовые вещи, что будут нужны и ехешнику непосредственно (SEH, TLS), и используемым в нём 32-разрядным системным модулям, и 64-битной ntdll вместе с Wow64 слоем, и при этом они являются структурами с указателями, в Wow64 процессе нужны отдельно 32-битный и 64-битный TEB/TEB. И они разные. Некоторые поля могут быть только в 64-битном или только в 32-битном TEB/PEB. Ну и из-за специфики Wow64, некоторые служебные поля в этих парных TEB/TEB могут иметь не тот смысл, что в "чистом 32-битном" или "чистом 64-битном".
Важный момент отличия 32-битного и 64-битного PEB: в 32-битном PEB::Ldr хранится список загруженных 32-битных модулей, в 64-битном — список 64-битных, который очень небольшой (64-битная ntdll, три-четыре dllки Wow64 слоя, ну и сам ехешник содержится и в 64-битном, и в 32-битном списке).

Поскольку клиенты NtQueryInformationProcess будут ожидать такой PEB, какой разрядности запрос, ну то есть какой разрядности сами клиенты, их нельзя удовлетворить, если 32-битный клиент спрашивает за 64-битный процесс. Поэтому 32-разрядная NtQueryInformationProcess не возвращает TEB для 64-разрядного процесса.

С учётом всего этого:
1. Смотря что с PEB делать, для Wow64 процесса может быть нужен либо 32-битный, либо 64-битный PEB, либо безразлично. Если нужен конкретный, обычно это 32-битный.
2. С PEB со всеми этими поинтерами в нём удобно работать в контексте процесса, к которому этот PEB относится. Внедрить dll-ку и работать через NtCurrentTeb()->Peb. Тогда для х64 систем нужны две dll-ки, 32-разрядная для 32-разрядных процессов, 64-разрядная для 64-разрядных процессов. В случае интенсивной работы с Ldr единственный нормальный вариант (не будешь же Loader Lock захватывать интерпроцессно).
3. В случае отсутствия надобности лезть в потроха загрузчика, но при этом наличия интенсивной работы с различными NT API, следует использовать 64-разрядный процесс на 64-разрядных системах. Если в итоге нужно, чтобы основное приложение было одно 32-битныое, следует завести вспомогательное 64-битное, и использовать IPC.
4. В принципе "какой-нибудь PEB другого процесса" можно получить из процесса любой разрядности без внедрения dll и без NtQueryInformationProcess. Главный вопрос — что дальше.