Linuxの標準的なプログラミング言語はCです。そのため、システムコールの最善の記述では、C関数を呼び出すように表示されます。 C関数としての記述と、アセンブリで実際のシステムコールにそれらをマップする方法の知識があれば、簡単に望む任意のシステムコールを使用することができます。
まず、Cプログラマに見えるように、すべてのシステムコールの参照が必要です。私が知っている最良のものは、Linux man-pages project、特にsystem callsセクションです。
は、それはあなたの問題の一つであるためのが、一例としてwrite
システムコールを見てみましょう。ご覧のとおり、最初のパラメータは符号付き整数で、通常はopen
システムコールによって返されるファイル記述子です。これらのファイル記述子は、通常、最初の3つのファイル記述子(0 = stdin、1 = stdout、2 = stderr)で発生するように、親プロセスから継承されている可能性があります。 2番目のパラメータはバッファへのポインタで、3番目のパラメータはバッファのサイズ(符号なし整数)です。最後に、関数は符号付き整数を返します。符号付き整数は、書き込まれたバイト数またはエラーの負数です。
これを実際のシステムコールにどのようにマップするのですか? 32ビットx86上でシステムコールを行う方法はたくさんあります(これはおそらくあなたのレジスタ名に基づいています)。 64ビットx86では完全に異なっていることに注意してください(32ビットモードでアセンブルして32ビット実行ファイルをリンクすることを忘れないでください;そうでないと状況が変わる例についてはthis questionを参照してください)。 32ビットx86の中で最も古く、最も単純で遅いのは、int $0x80
メソッドです。int $0x80
方法については
、あなたはそのためには、%ebx
、%ecx
、%edx
、%esi
、%edi
、および%ebp
に%eax
でシステムコール番号、およびパラメータを置きます。その後、int $0x80
を呼び出し、システムコールの戻り値は%eax
です。この戻り値はとは異なり、とは異なります。このリファレンスはCライブラリがどのようにそれを返すかを示していますが、システムコールはエラー時に-errno
を返します(例えば-EINVAL
)。この場合、Cライブラリはerrno
に移動し、-1
を返します。詳細については、syscalls(2)およびintro(2)を参照してください。
ので、write
例では、あなたが(%eax
でwrite
システムコール番号、%ebx
の最初のパラメータ(ファイル記述子番号)、%ecx
の2番目のパラメータ(文字列へのポインタ)、3番目のパラメータを置きます文字列の長さ)を%edx
に設定します。 %eax
には、書き込まれたバイト数か、エラー番号がネゲートされます(戻り値が-1〜-4095の場合は、ネゲートされたエラー番号です)。
最後に、システムコール番号はどのようにして見つけられますか?それらは/usr/include/linux/unistd.h
で見つけることができます。私のシステムでは、これはちょうど/usr/include/asm/unistd_32.h
を含む/usr/include/asm/unistd.h
を含んでいるので、数字はそこにあります(write
の場合、__NR_write
は4
です)。 /usr/include/linux/errno.h
(私のシステムでは、最初のものが/usr/include/asm-generic/errno-base.h
、残りが/usr/include/asm-generic/errno.h
であることがわかります)のエラー番号も同じです。他の定数や構造体を使用するシステムコールでは、対応する定義を見つけるためにどのヘッダを調べるべきかを文書に記述しています。
今のところ、私が言ったように、int $0x80
は最も古くて遅い方法です。より新しいプロセッサには特別なシステムコール命令があり、高速です。それらを使用するために、カーネルは、あなたのハードウェアで利用可能な最良の方法を使ってシステムコールを行うために呼び出すことのできる仮想ダイナミック共有オブジェクト(vDSO
;共有ライブラリのようですが、メモリのみ)を利用できます。また、システムコールや他のいくつかのことをすることなく、現在の時刻を取得するための特別な機能を提供します。もちろん、動的リンカーを使用していない場合は、使用するのが少し難しくなります。
もう1つ古い方法であるvsyscall
は、vDSO
に似ていますが、固定アドレスで1ページを使用します。最近のカーネルを使用している場合はシステムログに警告が表示され、さらに最近のカーネルではブート時に無効になり、将来は削除される可能性があります。それを使用しないでください。
Googleの検索エンジンやソースコード検索のエンゲージメントでも、それらがどのように使用されているのかの直接的な例を見つけることができます。私のポストのポイントは、いくつかの素晴らしいチートシートで検索と分析をスキップすることです。ありがとう。 –