Форум программистов, компьютерный форум, киберфорум
Наши страницы
_lunar_
Войти
Регистрация
Восстановить пароль
Оценить эту запись

Прототип RtlCreateUserProcessEx

Запись от _lunar_ размещена 29.01.2019 в 10:25
Обновил(-а) _lunar_ 08.02.2019 в 21:39

Потребовалось недавно создать процесс средствами Native API.
Из всего набора функций ntdll.dll имеются следующие варианты:
1. NtCreateProcess(Ex) - создаётся элементарно просто (NtOpenFile -> NtCreateSection -> NtCreateProcess -> NtGetContextThread -> NtCreateThread) но связать процесс с csrss слишком геморно, поэтому дальше чем не зарегистрированные хендлы объекта ядра пройти сложно. (Вообще между NtCreateThread и NtCreateThreadEx очень большая разница, но сейчас не об этом).
2. NtCreateUserProcess - в принципе оптимальный вариант, регистрация csrss проходит автоматически в процессе создания, но на Windows 10 с ней есть проблема: структура OBJECT_ATTRIBUTES в данном контексте предназначена только для вызовов из режима ядра, поэтому структура не учитывается при переключении контекста обратно в пользовательский режим. При возврате в режим пользователя адрес всегда равен нулю.
3. RtlCreateUserProcess(Ex) - функция, которая перешла из WinXP в качестве режима совместимости новых ОС со старыми программами. После выполнения она вызывает NtCreateUserProcess.

Решил взять её. RtlCreateUserProcess создать просто. Для этого сначала нужно передать в RtlCreateProcessParameters юникод строку и структуру RTL_USER_PROCESS_PARAMETERS. Если используется RtlCreateProcessParameters, то желательно вызывать RtlNormalizeProcessParams для нормализации параметров структуры RTL_USER_PROCESS_PARAMETERS. Либо воспользоваться RtlCreateProcessParametersEx у которой последним параметром идёт флаг нормализации равный 1.
Все прототипы этих функций в интернете есть (пишу код без CRT, VC runtime и стандартных хидеров из предыдущего блога http://www.cyberforum.ru/blogs/172954/blog5635.html)
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
typedef struct _RTL_USER_PROCESS_INFORMATION {
    /*+0x000*/ unsigned __int32 Length; // Uint4B
    /**/ void* __ptr64 hProcess; // Ptr64 Void
    /**/ void* __ptr64 hThread; // Ptr64 Void
    /**/ CLIENT_ID ClientId; // _CLIENT_ID
    /**/ SECTION_IMAGE_INFORMATION ImageInformation; // _SECTION_IMAGE_INFORMATION
} RTL_USER_PROCESS_INFORMATION;
 
typedef __int32(__stdcall* __ptr64 _RtlCreateProcessParameters)(
    RTL_USER_PROCESS_PARAMETERS* __ptr64* __ptr64 pProcessParameters,
    UNICODE_STRING* __ptr64 ImagePathName,
    UNICODE_STRING* __ptr64 DllPath,
    UNICODE_STRING* __ptr64CurrentDirectory,
    UNICODE_STRING* __ptr64 CommandLine,
    void* __ptr64 Environment,
    UNICODE_STRING* __ptr64 WindowTitle,
    UNICODE_STRING* __ptr64 DesktopInfo,
    UNICODE_STRING* __ptr64 ShellInfo,
    UNICODE_STRING* __ptr64 RuntimeData
    );
_RtlCreateProcessParameters RtlCreateProcessParameters;
 
typedef __int32(__stdcall* __ptr64 _RtlCreateProcessParametersEx)(
    RTL_USER_PROCESS_PARAMETERS* __ptr64* __ptr64 pProcessParameters,
    UNICODE_STRING* __ptr64 ImagePathName,
    UNICODE_STRING* __ptr64 DllPath,
    UNICODE_STRING* __ptr64 CurrentDirectory,
    UNICODE_STRING* __ptr64 CommandLine,
    void* __ptr64 Environment,
    UNICODE_STRING* __ptr64 WindowTitle,
    UNICODE_STRING* __ptr64 DesktopInfo,
    UNICODE_STRING* __ptr64 ShellInfo,
    UNICODE_STRING* __ptr64 RuntimeData,
    unsigned __int32 Flags
    );
_RtlCreateProcessParametersEx RtlCreateProcessParametersEx;
 
typedef RTL_USER_PROCESS_PARAMETERS* __ptr64 (__stdcall* __ptr64 _RtlNormalizeProcessParams)(
    RTL_USER_PROCESS_PARAMETERS* __ptr64 ProcessParameters
    );
_RtlNormalizeProcessParams RtlNormalizeProcessParams;
 
typedef __int32(__stdcall* __ptr64 _RtlCreateUserProcess)(
    UNICODE_STRING* __ptr64 NtImagePathName,
    unsigned __int32 AttributesDeprecated,
    RTL_USER_PROCESS_PARAMETERS* __ptr64 ProcessParameters,
    struct _SECURITY_DESCRIPTOR* __ptr64 ProcessSecurityDescriptor,
    struct _SECURITY_DESCRIPTOR* __ptr64 ThreadSecurityDescriptor,
    void* __ptr64 ParentProcess,
    unsigned char InheritHandles,
    void* __ptr64 DebugPort,
    void* __ptr64 TokenHandle,
    RTL_USER_PROCESS_INFORMATION* __ptr64 ProcessInformation
    );
_RtlCreateUserProcess RtlCreateUserProcess;
 
RTL_USER_PROCESS_PARAMETERS* __ptr64 proc = { 0 };
RTL_USER_PROCESS_INFORMATION info = { 0 };
 
UNICODE_STRING str;
str.Length = sizeof(L"\\??\\C:\\Users\\USER\\Documents\\programs\\AIDA\\cpuz_x64.exe") - sizeof(unsigned short);
str.MaximumLength = sizeof(L"\\??\\C:\\Users\\USER\\Documents\\programs\\AIDA\\cpuz_x64.exe");
str.Buffer = L"\\??\\C:\\Users\\USER\\Documents\\programs\\AIDA\\cpuz_x64.exe";
 
RtlCreateProcessParameters(&proc, &str, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0);
RtlNormalizeProcessParams(proc);
RtlCreateUserProcess(&str, 0x40, proc, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, 0, (void* __ptr64)0, (void* __ptr64)0, &info);
Хорошо, хендлы процесса и потока есть, иду в отладчик и смотрю цепочку вызовов до перехода в ядро (int 2e, syscall/sysenter)
ntdll!RtlCreateUserProcess -> ntdll!RtlCreateUserProcessEx -> RtlpCreateUserProcess -> ntdll!NtCreateUserProcess

Получается RtlCreateUserProcess это враппер над RtlCreateUserProcessEx и это лишние "телодвижения" перед переходом в ядро.
RtlpCreateUserProcess является внутренней (Internal) функцией и не экспортируется, поэтому делать её прототип бессмысленно, т.к. вызвать её нельзя.

Нужно вызывать RtlCreateUserProcessEx. Ок, полез в гугл за прототипом и тут я был слегка ошеломлен.
Ни гугл, ни сорсы Process Hacker, ни сорсы ReactOS не знают про существование этой функции. Нонсенс!

Делать нечего, нужна IDA и дизассемблированный листинг этой функции.
Открываем иду, переходим к RtlCreateUserProcess и жмакаем F5, видим следующее
Нажмите на изображение для увеличения
Название: 1.png
Просмотров: 43
Размер:	18.4 Кб
ID:	5170
RtlCreateUserProcess принимает 10 аргументов (что соответствует её прототипу) и возвращает вызов RtlCreateUserProcessEx с 5 аргументами.
Давайте посмотрим что это за аргументы.
a1 - это UNICODE_STRING* __ptr64 из аргументов RtlCreateUserProcess
a3 - это структура RTL_USER_PROCESS_PARAMETERS* __ptr64
a7 - это unsigned char
v11 - что-то типа флага (ида показывает 1, но это не так, он должен быть 0)
a10 - это структура RTL_USER_PROCESS_INFORMATION* __ptr64 из аргументов RtlCreateUserProcess

Вот собственно и прототип
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*NTSYSAPI
NTSTATUS
NTAPI
RtlCreateUserProcessEx(
    _In_ PUNICODE_STRING NtImagePathName,
    _In_ PRTL_USER_PROCESS_PARAMETERS ProcessParameters,
    _In_ BOOLEAN InheritHandles,
    _Reserved_ ULONG Flags,
    _Out_ PRTL_USER_PROCESS_INFORMATION ProcessInformation
);*/
 
typedef __int32(__stdcall* __ptr64 _RtlCreateUserProcessEx)(
    UNICODE_STRING* __ptr64 NtImagePathName,
    RTL_USER_PROCESS_PARAMETERS* __ptr64 ProcessParameters,
    unsigned char InheritHandles,
    unsigned __int32 Flags,
    RTL_USER_PROCESS_INFORMATION* __ptr64 ProcessInformation
    );
_RtlCreateUserProcessEx RtlCreateUserProcessEx;
 
RtlCreateProcessParametersEx(&proc, &str, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, (void* __ptr64)0, 0x1);
RtlCreateUserProcessEx(&str, proc, 0, 0, &info);
Всё, в структуре RTL_USER_PROCESS_INFORMATION будут лежать хендлы процесса и потока.
Что интересно, RtlCreateUserProcessEx уже сама вызывает RtlNormalizeProcessParams и параметры нормализуются автоматически при создании процесса
Нажмите на изображение для увеличения
Название: 2.png
Просмотров: 42
Размер:	17.8 Кб
ID:	5171



Добавлено
после общения с автором форка ProcessHacker, dmex добавил мой прототип функции RtlCreateUserProcessEx в исходный код
https://github.com/processhacker/pro...89ca9eba735080
Размещено в Без категории
Просмотров 206 Комментарии 0
Всего комментариев 0
Комментарии
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2019, vBulletin Solutions, Inc.
Рейтинг@Mail.ru