hex.pp.ua

Создание процесса с использованием Native API

Как создать процесс из приложения, использующего Native API




При разработке приложений Native API может возникнуть необходимость запустить процесс. В native режиме невозможен запуск Win32-приложений, так как процессы подсистемы Win32 при создании требуют уведомления CSRSS о новом процессе (а он ещё неактивен). Зато в native режиме возможен запуск других native приложений с помощью функции RtlCreateUserProcess.

В параметрах функции нужно в соответствующих структурах передать полный путь к исполняемому файлу, причём в NT-формате (то есть с префиксом \??\), имя файла процесса для отображения в списке процессов и командную строку с параметрами (это строка, которой был запущен процесс, содержащая его ключи запуска).

Например, запускаем процесс autochk.exe с параметрами, находясь в каталоге C:\windows\system32. Тогда в RtlCreateUserProcess нужно будет передать следующие строки:

  • Имя файла для отображения в списке процессов: autochk.exe
  • Командная строка: autochk.exe /p \??\C:
  • Полный путь: \??\C:\windows\system32\autochk.exe
Native shell версии 0.10 с запущенной программой проверки диска autochk.exe
Native shell версии 0.10 с запущенной
программой проверки диска autochk.exe

На снимке экрана вы видите программу проверки диска autochk.exe, запущенную из Native shell. При попытке запустить не native, а Win32 приложение из Native shell произойдёт ошибка и вы увидите синий экран смерти с текстом STOP c0000145. Это происходит потому, что функция CreateNativeProcess в Native shell не проверяет подсистему запускаемого исполняемого файла. Запускать следует либо собственные native приложения, либо native приложения, идущие в комплекте Windows, такие как autocheck.exe, autoconv.exe, autofmt.exe, autolfn.exe. В Native режиме уже запущен smss.exe, можно попытаться запустить его вторую копию, но результат подобного действия непредсказуем!

Существует и более сложный в реализации способ запуска процессов с использованием Native API, описанный на сайте http://ntprog.by.ru/_process.htm. Там есть описания проверки подсистемы и нотификации CSRSS для запуска приложений Win32. Это может пригодиться в случае запуска процесса не в Native режиме, а в обычном режиме работы Windows. Консольная программа nrun.exe от Andrey Shedel реализует запуск native приложений из командной строки обычного режима Windows.

Следующий кусок кода реализует запуск процесса в моей программе Native shell версии 0.10. Для приведения пути в NT-формат используется функция RtlDosPathNameToNtPathName_U. Инициализация параметров процесса происходит с помощью функции RtlCreateProcessParameters.

Текст функции

NTSTATUS 
CreateNativeProcess(IN PCWSTR file_name, IN PCWSTR cmd_line)
{
 PCWSTR file_part; 
 UNICODE_STRING fname, nt_file, EnvString,
    NullString, UnicodeSystemDriveString;
 NTSTATUS status;
 // Имя исполняемого файла
 UNICODE_STRING imgname; 
 // Путь к исполняемому файлу в NT-формате
 UNICODE_STRING imgpath; 
 // Путь, где располагаются библиотеки в формате DOS
 UNICODE_STRING dllpath; 
 // Командная строка
 UNICODE_STRING cmdline; 
 // Параметры процесса
 PRTL_USER_PROCESS_PARAMETERS processparameters; 
 // Информация о процессе
 RTL_USER_PROCESS_INFORMATION 
  processinformation = {0}; 
 WCHAR Env[2] = {0, 0}; // Окружение процесса
 PKUSER_SHARED_DATA SharedData
  = (PKUSER_SHARED_DATA)USER_SHARED_DATA; // Данные ядра

 // Преобразование пути в NT-формат (прибавление префикса \??\)
 RtlDosPathNameToNtPathName_U(
  file_name, &nt_file, &file_part, NULL);

 RtlInitUnicodeString(&imgpath, nt_file.Buffer);
 RtlInitUnicodeString(&imgname, file_part);
 // %SystemRoot%
 RtlInitUnicodeString(&dllpath, SharedData->NtSystemRoot);
 // Параметры командной строки 
 RtlInitUnicodeString(&cmdline, cmd_line); 

 // Инициализация параметров процесса
 status = RtlCreateProcessParameters(
  &processparameters, &imgname, 
  &dllpath, &dllpath, &cmdline, Env, 0, 0, 0, 0);

 if (!NT_SUCCESS(status))
 {
   RtlCliDisplayString("RtlCreateProcessParameters failed\n");
   return FALSE;
 }

 DbgPrint("Launching Process: %s, DllPath=%s, CmdLine=%s", 
  &imgname, &dllpath, &cmdline);

 // Здесь происходит непосредственно запуск процесса
 status = RtlCreateUserProcess(&imgpath, OBJ_CASE_INSENSITIVE, 
  processparameters, NULL, NULL, NULL, FALSE, 
  NULL, NULL, &processinformation );

 if (!NT_SUCCESS(status))
 {
   RtlCliDisplayString("RtlCreateUserProcess failed\n");
   return FALSE;
 }

 status = NtResumeThread(processinformation.ThreadHandle, NULL);

 if (!NT_SUCCESS(status))
 {
   RtlCliDisplayString("NtResumeThread failed\n");
   return FALSE;
 }

 return STATUS_SUCCESS;
}
система комментирования CACKLE

Автор: амдф
Дата: 25 января 2011


Разделы сайта
Главная
Блог
Native API
NTFS и ReFS
Микроконтроллеры
Справочник NTDLL
Коды NTSTATUS
Разное

Избранное
NTFS Stream Explorer
Native Shell
Тенгвар

Остальное
nvpnhcknn (архив)
English pages
Контакты

Ленты atom
Лента Atom сайта Лента Atom блога



При копировании материалов хорошим тоном будет указание авторства и ссылка на сайт.