WindowsNTサブシステムの書き込み[閉じた
-
09-10-2019 - |
質問
純粋に教育的な目的で、Windows 7に独自の最小限のNTサブシステムを書いてみたいと思います。これは、UNIXベースのアプリケーション用のMicrosoftのサブシステムのPOSIX.EXEに相当する裸のボーンのようなものです。
しかし、私はこのトピックに関する公開文書を見つけることができないようです。サブシステムはどのAPIを実装する必要がありますか? Windowsにどのように登録されますか?サブシステムイメージをどのように構築する必要がありますか(どのフラグをPEヘッダーに設定する必要がありますかなど)。
主題全体の概要、または他の誰かが書いた「Hello World」NTサブシステムのソースコードを備えた本やWebサイトを最も見つけたいと思います。しかし、あなたがここで正しい方向に私を向けることができれば、何でも感謝されるでしょう...
解決
サブシステムの主要なコンポーネントは次のとおりです。
- ユーザーモードサーバー。サーバーは(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/. 。私はあなたが探しているものと非常に似ており、私が言及した多くのことを使用していると思います。
他のヒント
また、ネイティブAPIに夢中です。 :)
そして、私はそれが危険な場所や文書化されていない人もいるほど文書化されていないと言ってうれしいです。 :
ネイティブAPIはWin32サブシステムの一部であり、ポートとのクライアント/サーバー通信が必要なため、ネイティブAPIがコンソールとそれほど簡単に対話できないため、「Hello、World」のソースコードはありません。コンソールアプリケーションを作成する必要がある場合は、メッセージ形式が文書化されていないCSRSSと直接通信する必要があります(ただし、その形式の一部はにありますが、 Reactosのソース - Reactosに精通している場合、それはあなたに多くの利点をもたらすでしょう)。
あなたが面白いと思うかもしれないという例をすぐにここに投稿します。とりあえず、あなたのことに注意してください それだけ オプションは、ntdll.dllにリンクすることです。そのためには、ドライバー開発キットが必要です(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ローダーを拡張できないようです。