51

純粋に教育目的で、Windows 7 で独自の最小限の NT サブシステムを作成してみたいと思います。これは、Microsoft の Unix ベース アプリケーション用サブシステムの posix.exe に相当するものです。

しかし、このトピックに関する公開ドキュメントが見つからないようです。サブシステムはどの API を実装する必要がありますか? どのように Windows に登録されますか? サブシステム イメージはどのように構築する必要がありますか (PE ヘッダーにどのフラグを設定する必要があるかなど)?

主題全体の概要が記載された本や Web サイト、または他の誰かが作成した「hello world」NT サブシステムのソース コードさえも見つけたいと思っています。しかし、ここで正しい方向に私を向けることができれば、何でもありがたいです...

4

2 に答える 2

20

サブシステムの主なコンポーネントは次のとおりです。

  • ユーザー モード サーバー。サーバーは (A)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 のシステム コールの 2 つしか使用できないため、新しいシステム サービス テーブルを追加することはできません。

少しグーグルした後、http://winntposix.sourceforge.net/を見つけました。あなたが探しているものと非常に似ていると思います。私が言及した多くのものを使用しています。

于 2011-01-11T01:46:43.117 に答える
15

また、ネイティブ API にも夢中です。:)

そして、一部の人々が考えるほど危険でも文書化されていないわけでもないことを嬉しく思います. :]

"Hello, world" のソース コードはありません。これは、ネイティブ API がコンソールと簡単にやり取りできないためです。コンソールは Win32 サブシステムの一部であり、ポートとのクライアント/サーバー通信が必要なためです。コンソール アプリケーションを作成する必要がある場合は、CSRSS と直接通信する必要があります。CSRSS のメッセージ形式は文書化されていません (ただし、その形式の一部はReactOS のソースに含まれていますが、ReactOS に慣れれば多くの利点があります)。

興味深いと思われる例をすぐにここに投稿します。今のところ、唯一のオプションは NTDLL.dll とリンクすることであり、そのためには Driver Development Kit が必要であることに注意してください(lib ファイルが必要なため)。


更新:これをチェックしてください!

(これほど反抗的なものを投稿する人は他にいないと思います。ネイティブ API で GUI を表示する?! 私は気が狂っているに違いありません!)

#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:

Kernel32 の独自の DLL バージョンを作成して、Kernel32 がすべてのプロセスで行うようにロードする (したがって、新しいサブシステムを作成する) 場合は、それが可能だとは思わないことをお知らせしたいと思います。数日前に私が尋ねたこの質問とかなり似ていますが、NT PE ローダーを拡張して新しいサブシステムについて知ることはできないようですので、それは不可能だと思います。

于 2011-01-09T09:37:29.517 に答える