fr33f0r4ll

自分用雑記

Linux! C! signal!

過去のpwn問でsignalを使う問題があったけど、今までよく知らなかったのでメモ。

あらかじめ定義されているシグナルごとにハンドラを登録し、シグナルを受け取ったときにハンドラの処理を実行して割り込みを処理をする。

linuxだとこんな感じになる。

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

// ハンドラ関数
// signumにはシグナルを表す数値が渡される
void test_signal_handler(int signum) {
  printf("sigint! %d\n", signum);
  exit(1);
}

int main(int argc, char** argv){
  // test_signal_handlerをSIGINTを受け取ったときのハンドラとして登録している
  // SIGINTはプロセスを終了させるためのシグナル、C-c
  signal(SIGINT, test_signal_handler);

  // SIGUSR1, SIGUSR2などのユーザが定義できるシグナルもある
  // ハンドラはシグナルを無視するSIG_IGNなどの値を設定することもできる
  signal(SIGUSR1, SIG_IGN);

  sleep(3600);
  
  return 0;
}

このプログラムを実行すると1時間スリープするが、実行中にCtrl-Cを押したりしてSIGINTを送るとメッセージを表示してすぐに終了するようになっている。 sleep中でも割り込んで違う処理を実行させられることが確認できる。

解析するときにはsignalに渡されているアドレスから関数の位置を特定しないといけない。

raiseを使えばプロセスにシグナルを送信できる。