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

fs:[0x28] (スタック カナリア) を設定するものは何ですか?

(ほぼ) すべてのプロセス strace について、この初期化を追跡するのは簡単です。 プロセス実行の最初の段階で非常に疑わしいシステムコールを示しています:

arch_prctl(ARCH_SET_FS, 0x7fc189ed0740) = 0

それが man 2 arch_prctl です 言います:

   ARCH_SET_FS
          Set the 64-bit base for the FS register to addr.

ええ、それが必要なようです。 arch_prctl を呼び出す人を見つけるには 、バックトレースを探しましょう:

(gdb) catch syscall arch_prctl
Catchpoint 1 (syscall 'arch_prctl' [158])
(gdb) r
Starting program: <program path>

Catchpoint 1 (call to syscall arch_prctl), 0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
(gdb) bt
#0  0x00007ffff7dd9cad in init_tls () from /lib64/ld-linux-x86-64.so.2
#1  0x00007ffff7ddd3e3 in dl_main () from /lib64/ld-linux-x86-64.so.2
#2  0x00007ffff7df04c0 in _dl_sysdep_start () from /lib64/ld-linux-x86-64.so.2
#3  0x00007ffff7dda028 in _dl_start () from /lib64/ld-linux-x86-64.so.2
#4  0x00007ffff7dd8fb8 in _start () from /lib64/ld-linux-x86-64.so.2
#5  0x0000000000000001 in ?? ()
#6  0x00007fffffffecef in ?? ()
#7  0x0000000000000000 in ?? ()

したがって、FS セグメント ベースは ld-linux によって設定されます。 glibc の一部です 、プログラムのロード中 (プログラムが静的にリンクされている場合、このコードはバイナリに埋め込まれます)。ここですべてが行われます。

起動時に、ローダーは TLS を初期化します。これには、メモリの割り当てと、TLS の開始点を指すように FS ベース値を設定することが含まれます。これは arch_prctl 経由で行われます システムコール。 TLS 初期化後 security_init 関数が呼び出され、スタック ガードの値が生成され、それが fs:[0x28] のメモリ ロケーションに書き込まれます。 指し示す:

  • スタック ガード値の初期化
  • スタック ガード値の書き込み、詳細

そして 0x28 stack_guard のオフセットです TLS の開始位置にある構造体のフィールド。


表示されているのは (GCC では) スタック スマッシング プロテクター (SSP) と呼ばれ、コンパイラによって生成されるバッファー オーバーフロー保護の形式です。値は起動時にプログラムによって生成される乱数であり、ウィキペディアの記事で言及されているように、スレッド ローカル ストレージ (TLS) に配置されます。他のコンパイラは、このタイプの保護を実装するために異なる戦略を使用する場合があります。

なぜ値を TLS に保存するのですか?値はそこにあるため、CS、DS、および SS レジスタからそのアドレスにアクセスすることはできず、悪意のあるコードからスタックを変更しようとしている場合、格納されている値を推測することは非常に困難です。


Linux
  1. Linuxユーザーとは何ですか?

  2. システム管理者とは何ですか?

  3. 「lc_all=c」は何をしますか?

  1. 16進値でソートしますか?

  2. エコー$は何ですか?行う??

  3. Linux 環境変数値の最大サイズは?

  1. nmコマンドのシンボル値は何を意味しますか?

  2. ulimit -s unlimited は何をしますか?

  3. スタックポインタの値を出力する