GNU/Linux >> Linux の 問題 >  >> Linux

Windows とネイティブ API のシステム コール?

インポートなしでアセンブリで Windows API 呼び出しを行うことに (教育的な演習として) 興味があったので、NtDll!NtCreateFile が行うことを行うために、次の FASM アセンブリを作成しました。これは私の 64 ビット バージョンの Windows (Win10 1803 バージョン 10.0.17134) での大まかなデモであり、呼び出し後にクラッシュしますが、syscall の戻り値はゼロなので成功しています。すべてが Windows x64 呼び出し規約に従ってセットアップされ、次にシステム コール番号が RAX に読み込まれ、呼び出しを実行するための syscall アセンブリ命令になります。私の例ではファイル c:\HelloWorldFile_FASM が作成されるため、「管理者として」実行する必要があります。

format PE64 GUI 4.0


entry start


section '.text' code readable executable


 start: 
 ;puting the first four parameters into the right registers

                            mov rcx, _Handle
                            mov rdx, [_access_mask]
                            mov r8, objectAttributes
                            mov r9, ioStatusBlock

 ;I think we need 1 stack word of padding:

                            push 0x0DF0AD8B


 ;pushing the other params in reverse order:

                            push [_eaLength]
                            push [_eaBuffer]
                            push [_createOptions]
                            push [_createDisposition]
                            push [_shareAcceses]
                            push [_fileAttributes]
                            push [_pLargeInterger]

 ;adding the shadow space (4x8)

 ;                               push 0x0
 ;                               push 0x0
 ;                               push 0x0
 ;                               push 0x0

 ;pushing the 4 register params into the shadow space for ease of debugging

                            push r9
                            push r8
                            push rdx
                            push rcx

 ;now pushing the return address to the stack:

                            push endOfProgram

                            mov r10, rcx ;copied from ntdll!NtCreateFile, not sure of the reason for this
                            mov eax, 0x55
                            syscall

 endOfProgram:
                            retn




 section '.data' data readable writeable

 ;parameters------------------------------------------------------------------------------------------------

 _Handle                         dq      0x0
 _access_mask                    dq      0x00000000c0100080
 _pObjectAttributes              dq      objectAttributes        ; at 00402058
 _pIoStatusBlock                 dq           ioStatusBlock
 _pLargeInterger                 dq      0x0
 _fileAttributes                 dq      0x0000000000000080
 _shareAcceses                   dq      0x0000000000000002
 _createDisposition              dq      0x0000000000000005
 _createOptions                  dq      0x0000000000000060
 _eaBuffer                       dq      0x0000000000000000       ; "optional" param
 _eaLength                       dq      0x0000000000000000

 ;----------------------------------------------------------------------------------------------------------


                            align   16
 objectAttributes:
 _oalength                       dq      0x30
 _rootDirectory                  dq      0x0
 _objectName                     dq           unicodeString
 _attributes                     dq      0x40
 _pSecurityDescriptor            dq      0x0
 _pSecurityQualityOfService      dq      securityQualityOfService


 unicodeString:
 _unicodeStringLength            dw      0x34
 _unicodeStringMaxumiumLength    dw      0x34, 0x0, 0x0
 _pUnicodeStringBuffer           dq      _unicodeStringBuffer


 _unicodeStringBuffer            du      '\??\c:\HelloWorldFile_FASM'       ; may need to "run as adinistrator" for the file create to work.



 ioStatusBlock:
 _status_pointer                 dq      0x0
 _information                    dq      0x0


 securityQualityOfService:
 _sqlength                       dd      0xC
 _impersonationLevel             dd      0x2
 _contextTrackingMode            db      0x1
 _effectiveOnly                  db      0x1, 0x0, 0x0

Ntdll!NtCreateFile のドキュメントを使用し、カーネル デバッガーを使用して多くのパラメーターを参照およびコピーしました。

__kernel_entry NTSTATUS NtCreateFile(
  OUT PHANDLE                      FileHandle,
  IN ACCESS_MASK                   DesiredAccess,
  IN POBJECT_ATTRIBUTES            ObjectAttributes,
  OUT PIO_STATUS_BLOCK             IoStatusBlock,
  IN PLARGE_INTEGER AllocationSize OPTIONAL,
  IN ULONG                         FileAttributes,
  IN ULONG                         ShareAccess,
  IN ULONG                         CreateDisposition,
  IN ULONG                         CreateOptions,
  IN PVOID EaBuffer                OPTIONAL,
  IN ULONG                         EaLength
);

Windows でアセンブリ プログラミングを行っている場合、手動の syscall は行いません。 NTDLL とネイティブ API を使用してそれを行います。

ネイティブ API は、単なるカーネル モード側のラッパーです。正しい API のシステムコールを実行するだけです。

質問全体が冗長になるように、手動で syscall する必要はありません。

Linux syscall コードは変更されませんが、Windows は変更されます。そのため、追加の抽象化レイヤー (別名 NTDLL) を介して作業する必要があります。

編集:

また、アセンブリ レベルで作業している場合でも、Win32 API に完全にアクセスできます。最初から NT API を使用する必要はありません。アセンブリ プログラムでは、インポート、エクスポートなどはすべて正常に機能します。

EDIT2:

本当に手動で syscall を実行したい場合は、関連する Windows バージョンごとに NTDLL をリバースし、(PEB を介して) バージョン検出を追加し、呼び出しごとに syscall ルックアップを実行する必要があります。

しかし、それはばかげているでしょう。 NTDLL には理由があります。

リバース エンジニアリングの部分は既に行われています。各 Windows カーネルのシステム コール番号の表については、https://j00ru.vexillium.org/syscalls/nt/64/ を参照してください。 (以降の行は、Windows 10 のバージョン間でも変更されることに注意してください。) 繰り返しますが、これは、自分のマシンで asm や Windows 内部について詳しく学ぶための個人使用のみの実験以外では、悪い考えです。他の人に配布するコードにシステム コールをインライン化しないでください。


Windows syscall 規則について知っておく必要があるもう 1 つのことは、私が理解しているように、ビルド プロセスの一部として syscall テーブルが生成されるということです。これは、それらが単純に変更できることを意味します-誰もそれらを追跡しません.誰かがリストの一番上に新しいものを追加したとしても、それは問題ではありません。 NTDLL は引き続き機能するため、NTDLL を呼び出す他のすべてのユーザーは引き続き機能します。

システムコール (int または sysenter) を実行するために使用されるメカニズムでさえ、固定されておらず、過去に変更されています。マシンの CPU。


Windows システム コールは、kernel32.dll などのシステム DLL を呼び出すことによって実行されます。 または gdi32.dll 、通常のサブルーチン呼び出しで行われます。 OS 特権レイヤーにトラップするメカニズムは文書化されていませんが、DLL は kernel32.dll のようなものなので問題ありません。

システム コールによって、CreateProcess() のような文書化された Windows API エントリ ポイントを参照しています。 または GetWindowText() .通常、デバイス ドライバーは Windows DDK とは異なる API を使用します。


Linux
  1. Linux – Linuxカーネルシステムコールの実装を見つける方法は?

  2. 侵害されたWindowsサーバーを調査する

  3. ネイティブ ライブラリを使用して Linux システムに Tomcat 7 をインストールする

  1. straceを使用したLinuxでのシステムコールの理解

  2. ファイルの内容をStdoutに出力するコマンド?

  3. Windows PowerShell は Unix/Linux の「pwd」に相当しますか?

  1. statvfs() と statfs() システムコールの違いは?

  2. Linux のネイティブ GUI API とは何ですか?

  3. malloc() から行われる Windows および Linux のネイティブ OS/システム呼び出しは何ですか?