web-dev-qa-db-ja.com

syscall番号→実行時の名前のマッピング

観測されたsyscallの数を解決する方法はありますか?

SYS_345(0xe, 0xbff94188, 0x2, 0x4000, 0xb6526000) = 2

実行中のカーネルで、ソースを調べずに、そのシンボル名に変更しますか?

[〜#〜] edit [〜#〜]古くなっているユースケースstraceカーネルソースを取得するのが面倒な外部ボックスのバイナリ。

5
phg

私の知る限り、実行中のカーネルからシステムコール番号からシステムコール名へのマッピングを決定する方法は保証されていません。システムコール番号に対応するコールを見つけるには、常にソースコードを掘り下げる必要があります...

この種のマッピングを実行する必要があるソフトウェアの開発者は、システムコールの独自のリストを維持する傾向があります。これは strace によって使用されるアプローチです。これは、そのようなプログラムの特定のバージョンが特定のカーネルに比べて古くなる可能性があることを意味しますが、実際には、システムコールの追加は、これが問題にならない程度にゆっくりと行われます。

マッピングはアーキテクチャに応じてさまざまな方法で保存されるため、カーネルソースで値を検索することも複雑です。 システムコールテーブル を使用するx86など、マッピングが「シンプル」なアーキテクチャでも、特定の番号の呼び出しを見つけるには、さまざまな場所で複数の検索が必要になる場合があります。

システムにGCCとシステムヘッダーが含まれている限り、システムのマッピングをすばやく確実に見つける方法の1つは、後者を使用することです。例えば、

awk 'BEGIN { print "#include <sys/syscall.h>" } /p_syscall_meta/ { syscall = substr($NF, 19); printf "syscalls[SYS_%s] = \"%s\";\n", syscall, syscall }' /proc/kallsyms |
sort -u | gcc -E -P - | less

linuxシステムコールのリストを/proc/kallsymsから抽出し、Cコード(またはCプリプロセッサコード)のスニペットを作成し、それをプリプロセッサにフィードして、次のようなものを生成します

syscalls[288] = "accept4";
syscalls[43] = "accept";
syscalls[21] = "access";
syscalls[163] = "acct";
syscalls[248] = "add_key";

etc.必要に応じてGCCフラグを使用してアーキテクチャを微調整し、カーネルに一致させることができます(eg-m32は、i386システムコール番号を表示します。または-mx32(x86-32番号)。

あなたの場合、345はi386のsendmmsgシステムコールの番号であり、x86-64またはx86-32のいずれにも対応していません。これは2011年に2.6.39の時期に導入されたため、カーネルと関連プログラムのベースとして長年の2.6.32を使用しているシステムはそれを認識しません(そのため、strace、および新しいカーネル)。

7
Stephen Kitt