x86-64版Linuxのシステムコールを解析してみましょう!
初心者向けヒント1: システムコールの呼び出し規約とgccの拡張インラインアセンブラ
- x86-64版Linuxにおけるシステムコールの呼び出し規約は、 https://gitlab.com/x86-psABIs/x86-64-ABI からダウンロードできる
System V Application Binary Interface AMD64 Architecture Processor Supplement資料中のA.2.1 Calling Conventionsや、 https://man7.org/linux/man-pages/man2/syscall.2.html に記述があります。- システムコールを実行するには、システムコール番号を
raxレジスタに、最大6個までの引数を順にrdi,rsi,rdx,r10,r8,r9レジスタに格納してからsyscall命令を実行します。 - システムコール実行結果は
raxレジスタに格納されます。
- システムコールを実行するには、システムコール番号を
- gccの拡張インラインアセンブラ構文は、 https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html や https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html に記述があります。
- 本問題で使用している1つ目の
syscall命令用の拡張インラインアセンブラでは、次のことを指定しています。OutputOperandsパラメーターは未指定です。InputOperandsパラメーターで、拡張インラインアセンブラを実行する前に、raxレジスタに318を、rdiレジスタに&result_1を、rsiレジスタにsizeof(result_1)を、rdxレジスタに0を設定しています。Clobbersパラメーターで、拡張インラインアセンブラの実行中にrcxレジスタとr11レジスタ、メモリが変更されることを指定しています。- なお、
syscall命令そのものがrcxレジスタとr11レジスタを変更します。
- なお、
- 本問題で使用している2つ目の
syscall命令用の拡張インラインアセンブラでは、次のことを指定しています。OutputOperandsパラメーターで、拡張インラインアセンブラの実行後に、raxレジスタの内容をresult_2へ設定しています。InputOperandsパラメーターで、拡張インラインアセンブラを実行する前に、raxレジスタに102を設定しています。Clobbersパラメーターで、拡張インラインアセンブラの実行中にrcxレジスタとr11レジスタが変更されることを指定しています。
- 本問題で使用している1つ目の
初心者向けヒント2: 問題へのアプローチ
- 本問題を解くアプローチはいくつかあります。
- 1つの方法は、x86-64版Linuxのシステムコール番号を調査して、対応するシステムコールの引数や戻り値を確認する方法です。
- 別の方法は、逆コンパイラを使用する方法です。
- 逆コンパイラによって、システムコール呼び出しを最初から完璧に逆コンパイルできるものもあれば、初期状態では逆コンパイル結果が貧弱なものの追加操作で完璧に逆コンパイルできるものもあります。