Вопрос

Я хотел бы попробовать написать свою собственную минимальную NT-подсистему в Windows 7 для чисто образовательных целей-что-то вроде костей, эквивалентного posix.exe в подсистеме Microsoft для приложений на основе UNIX.

Но я не могу найти никакой публичной документации по этой теме. Какой API должен реализовать подсистему? Как он зарегистрирован в Windows? Как нужно создавать изображение подсистемы (какие флаги должны быть установлены в заголовке PE и т. Д.)?

Больше всего я хотел бы найти книгу или веб -сайт с обзором всего предмета или даже исходного кода для подсистемы «Hello World» NT, которую написал кто -то другой. Но что -либо вообще будет оценено, если вы сможете указать мне в правильном направлении здесь ...

Это было полезно?

Решение

Вот основные компоненты подсистемы:

  • Пользовательский сервер. Сервер создает (а) порт LPC и прослушивает и обрабатывает запросы клиентов.
  • Пользовательский клиент DLL. В DLL_INIT_ROUTINE вы можете подключиться к порту, установленному сервером. Этот DLL выявит API вашей подсистемы, и некоторые функции потребуют связи с сервером.
  • Драйвер поддержки режима ядра (вам может это не понадобиться).

Вы захотите сохранить процесс или состояние потока на вашем сервере или драйвере. Если вы храните его на сервере, вам может понадобиться что -то вроде NtRegisterThreadTerminatePort Чтобы убедиться, что вы очищаетесь, когда выходит процесс или поток. Если вы используете драйвер, вам нужно PssetCreateProcessNotifyRoutine.

И, наконец, если вы находитесь на XP и ниже, вы можете добавить новые системы системных вызовов. Вы можете сделать это, позвонив KeAddSystemServiceTable. Анкет Чтобы вызвать системные вызовы из пользовательского режима, вам необходимо создать подобные заглушки (для x86):

; XyzCreateFooBar(__out PHANDLE FooBarHandle, __in ACCESS_MASK DesiredAccess, ...)
mov     eax, SYSTEM_CALL_NUMBER
mov     edx, 0x7ffe0300
call    [edx]
retn    4

На Vista и выше вы больше не можете добавлять новые таблицы обслуживания систем, потому что есть место только для двоих: системные вызовы ядра и системные вызовы Win32K.

После небольшого гуглирования я нашел это: http://winntposix.sourceforge.net/. Анкет Я думаю, что это очень похоже на то, что вы ищете, и использует много вещей, которые я упомянул.

Другие советы

Я также одержим родным API. :)

И я рад сказать, что это нигде не так опасно или не такими недокументированными, как некоторые люди делают это. :

Нет исходного кода для «Привет, мира», потому что нативный API не так легко взаимодействует с консоли, поскольку он является частью подсистемы Win32 и требует связи клиента/сервера с портами. Если вам нужно написать приложение для консоли, вам необходимо напрямую общаться с CSRSS, форматы сообщений которых недокументированы (хотя некоторые из его формата можно найти в Источник Реакта - Это принесет вам много преимуществ, если вы познакомитесь с Reactos).

Скоро я опубликую пример, который может найти интересным; На данный момент имейте в виду, что ваш Только Опция когда -либо связана с ntdll.dll, и для этого вам нужен комплект для разработки водителя (поскольку вам нужен файл LIB).


Обновлять: Проверь это!

(У меня есть чувство, что никто другой не опубликует что -то столь же мятежное, как это. Показывая графический интерфейс с родным API?! Я должен быть сумасшедшим!)

#include <Windows.h>

typedef DWORD NTSTATUS;

//These are from ReactOS
typedef enum _HARDERROR_RESPONSE_OPTION
{
    OptionAbortRetryIgnore,
    OptionOk,
    OptionOkCancel,
    OptionRetryCancel,
    OptionYesNo,
    OptionYesNoCancel,
    OptionShutdownSystem
} HARDERROR_RESPONSE_OPTION, *PHARDERROR_RESPONSE_OPTION;

typedef enum _HARDERROR_RESPONSE
{
    ResponseReturnToCaller,
    ResponseNotHandled,
    ResponseAbort,
    ResponseCancel,
    ResponseIgnore,
    ResponseNo,
    ResponseOk,
    ResponseRetry,
    ResponseYes,
    ResponseTryAgain,
    ResponseContinue
} HARDERROR_RESPONSE, *PHARDERROR_RESPONSE;

typedef struct _UNICODE_STRING {
    USHORT  Length;
    USHORT  MaximumLength;
    PWSTR  Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

//You'll need to link to NTDLL.lib
//which you can get from the Windows 2003 DDK or any later WDK
NTSYSAPI VOID NTAPI RtlInitUnicodeString(IN OUT PUNICODE_STRING DestinationString,
    IN PCWSTR SourceString);
NTSYSAPI NTSTATUS NTAPI NtRaiseHardError(IN NTSTATUS ErrorStatus,
    IN ULONG NumberOfParameters, IN ULONG UnicodeStringParameterMask,
    IN PULONG_PTR Parameters,
    IN HARDERROR_RESPONSE_OPTION ValidResponseOptions,
    OUT PHARDERROR_RESPONSE Response);
#define STATUS_SERVICE_NOTIFICATION_2 0x50000018

int main()
{
    HARDERROR_RESPONSE response;
    ULONG_PTR items[4] = {0};
    UNICODE_STRING text, title;
    RtlInitUnicodeString(&text,
        L"Hello, NT!\r\nDo you like this?\r\n"
        L"This is just about as pretty as the GUI will get.\r\n"
        L"This message will self-destruct in 5 seconds...");
    RtlInitUnicodeString(&title, L"Native Message Box!");
    items[0] = (ULONG_PTR)&text;
    items[1] = (ULONG_PTR)&title;
    items[2] = (ULONG_PTR)OptionYesNo;
    items[3] = (ULONG_PTR)5000;
    NtRaiseHardError(STATUS_SERVICE_NOTIFICATION_2, ARRAYSIZE(items),
        0x1 | 0x2 /*First two parameters are UNICODE_STRINGs*/, items,
        OptionOk /*This is ignored, since we have a custom message box.*/,
        &response);
    return 0;
}

Если у вас есть вопросы, не стесняйтесь спросить! Я не боюсь родного API! :)


РЕДАКТИРОВАТЬ 2:

Если вы пытаетесь сделать свою собственную версию DLL Kernel32 и загрузить его, как Kernel32, с каждым процессом (отсюда и новой подсистемой), я просто хотел, чтобы вы знали, что я не думаю, что это возможно. Это довольно похоже на этот вопрос То, что я спросил пару дней назад, и кажется, что вы не можете продлить загрузчик NT PE, чтобы узнать о новых подсистемах, поэтому я не думаю, что это будет возможно.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top