Подскажите пожалуйства, друзья наиболее верный вариант. Моему драйверу необходимо: 1. получать список существующих процессов. 2. узнать загружены ли необходимые DLL в контекст этого процеса, именно ntdll, kernel32 3. узнавать Win32 Server PID процесса , т.е. процесса csrss пренадлежащему данному сеансу(session), что и выбранный процесс. 4. Производить некоторое действие над процессом. 5. получать уведомление о завершении таких процессов, что-бы освобождать ресурсы, выделенные драйверов в его контексте. Что заведомо не подходит: 1. PsSetCreateProcessNotifyRoutine - как не странно, но callback не срабатывает всегда при удалении процессов csrss, и при перезагрузке ОС. 2. PsSetLoadImageNotifyRoutine - и контроль какой из процeссов загрузил некую DLL тоже не всегда срабатывает для некоторых процессов. Хотелось бы сделать код максимально документированно и переносимо. Вот мне видиться такой вариант: 1. ZwQuerySystemInformation или же работа с списком EPROCESS, но смещения меняются, и необходимо при работе со списком процессов некая синхронизация, что-бы никто другой не поменял список пока мы с ним работаем. Хотя в случае использования ZwQuerySystemInformation такой гарантии тоже нет. 2. Для существующих процессов возможно- подключение в контекст процесса и анализ списка _PEB->PEB_LDR_DATA Для вновь создаваемых - перехват MmMapViewOfSection и анализ SectionHandle, например так http://www.wasm.ru/print.php?article=drvw2k14 что под вистой уже не так 3. Сложностей особенных нет ZwQuerySystemInformation/ZwQueryInformationProcess или работа или _PEB->SessionId 5. Уведомление о удаление процессов: 1. Не проверенно: NTSTATUS NtTerminateProcess( IN HANDLE ProcessHandle, IN NTSTATUS ExitStatus ); для уведомления о завершении процессов csrss.exe причем вызывают эту функцию несколько раз, необходимо получить по ProcessHandle указатель на EPROCESS и проверять флаг EPROCESS->ProcessDelete 2. Обьект-процесс nt!PspProcessDelete этой функции передается параметр указатель на EPROCESS в это время удаляется обьект-процесс, нет активных потоков EPROCESS->ProcessDelete=1 в этом случае вызывается уведомление о завершении на порядок большего числ процессов, но всеравно список не полный.
Osen Доказательство в студию, хотя не нужно, создай процесс и посмотри какие модули в нём есть(если сможешь посмотреть...), создавать нужно без потоков, тоесть не тупо CreateProcess(), а смотреть нужно сразу после NtCreateProcess, пока есчо не мешают. Потом раскажешь о своём опыте..
Загрузка kernel32.dll идет в загрузчике (ntdll!LdrpInitializeProcess) при инициализации процесса (для GUI и CUI процессов): Код (Text): .text:7C8337CC loc_7C8337CC: ; CODE XREF: LdrpInitializeProcess(x,x)+88B9j .text:7C8337CC mov eax, [ebp+ImageNtHeaders] .text:7C8337CF mov ax, word ptr [eax+(_IMAGE_NT_HEADERS.OptionalHeader+44h)] ; Subsystem .text:7C8337D3 cmp ax, IMAGE_SUBSYSTEM_WINDOWS_GUI .text:7C8337D7 jz short loc_7C8337DF .text:7C8337D9 cmp ax, IMAGE_SUBSYSTEM_WINDOWS_CUI .text:7C8337DD jnz short loc_7C833849 .text:7C8337DF .text:7C8337DF loc_7C8337DF: ; CODE XREF: LdrpInitializeProcess(x,x)-3408j .text:7C8337DF lea eax, [ebp+var_88] .text:7C8337E5 push eax .text:7C8337E6 push offset dword_7C8338A0 ; -> kernel32.dll .text:7C8337EB push 0 .text:7C8337ED push 0 .text:7C8337EF call _LdrLoadDll@16 ; LdrLoadDll(x,x,x,x) .text:7C8337F4 ... .text:7C833849 loc_7C833849: PS: From Windows Server 2003 SP2
Clerk Я написал уже - нужен более документированный способ, какая-то альтернатива. Плюс как получать уведомления для создания и удаленяи всех процессов я так и не нашел.
xorrax Я то знаю, а вот Осень нет, даже что блок данных загрузчика находитсо в хипе, который также нтдлл создаёт. Osen Жду ответа где ложь.
Clerk Создаем процесс, который импортирует только ntdll.dll, в нем будет kernel32.dll 100% Я проверил, может проверить ты.
А почему без потоков? Таких процессов какбэ много не бывает, это ваакуум, которого не существует. Зачем нужен процесс без потоков?
Osen У тебя система инфицирована кривым какимто кодом, он при создании процесса внедряет модуль с именем kernel32.dll в процесс, есчо до старта любого потока.
Osen Процесс ведь не создаётся(в висте вроде можно) сразу с потоком, его нужно отдельно создать. этот промежуток времени видимо и интересен автору. Если нужно выполнить действия с загрузчиком в произвольный момент времени, то существует вероятность что в это время поток есчо не создан(ну или создан но не начал исполнятся). Вот тут и нужно определить какие модуля присутствуют, хотя это легко сделоть просто чтение некоторых переменных, которые заполняются после загрузки kernel32, необязательно лезть для этого в лдр.