横取りというか覗き見る。つづき
SH4でも使いたかったけど、当然コンパイルが通らないのでなんとかする。
straceのソースを読んでみても、ぐちゃぐちゃしててよくわからなかった。レジスタとかよく知らないので、とりあえずstraceをstraceしてみる。
$ strace -e trace=ptrace strace -e trace=write echo hoge
i686の場合
ptrace(PTRACE_PEEKUSER, 20205, 4*ORIG_EAX, [0x4]) = 0 ptrace(PTRACE_PEEKUSER, 20205, 4*EAX, [0xffffffda]) = 0 ptrace(PTRACE_PEEKUSER, 20205, 4*EBX, [0x1]) = 0 ptrace(PTRACE_PEEKUSER, 20205, 4*ECX, [0xb7f21000]) = 0 ptrace(PTRACE_PEEKUSER, 20205, 4*EDX, [0x5]) = 0 ptrace(PTRACE_PEEKDATA, 20205, 0xb7f21000, [0x65676f68]) = 0 ptrace(PTRACE_PEEKDATA, 20205, 0xb7f21004, [0xa]) = 0 write(1, "hoge\n", 5ptrace(PTRACE_SYSCALL, 20205, 0x1, SIG_0) = 0 hoge ptrace(PTRACE_PEEKUSER, 1301, 4*REG_REG3, [0x4]) = 0 ptrace(PTRACE_PEEKUSER, 1301, 4*REG_REG0, [0x5]) = 0 ) = 5
sh4の場合
ptrace(PTRACE_PEEKUSER, 1301, 4*REG_REG3, [0x4]) = 0 ptrace(PTRACE_PEEKUSER, 1301, 4*REG_REG0, [0]) = 0 ptrace(PTRACE_PEEKUSER, 1301, 4*REG_REG4, [0x1]) = 0 ptrace(PTRACE_PEEKUSER, 1301, 4*REG_REG5, [0x2956c000]) = 0 ptrace(PTRACE_PEEKUSER, 1301, 4*REG_REG6, [0x5]) = 0 ptrace(PTRACE_PEEKDATA, 1301, 0x2956c000, [0x65676f68]) = 0 ptrace(PTRACE_PEEKDATA, 1301, 0x2956c004, [0xa]) = 0 write(1, "hoge\n", 5ptrace(PTRACE_SYSCALL, 1301, 0x1, SIG_0) = 0 hoge ptrace(PTRACE_PEEKUSER, 21209, 4*ORIG_EAX, [0x4]) = 0 ptrace(PTRACE_PEEKUSER, 21209, 4*EAX, [0x5]) = 0 ) = 5
レジスタの構成
レジスタ | i686 | sh |
---|---|---|
システムコール番号 | orig_eax | REG_REG3 |
出るときは戻り値。入るときはわかんない | eax | REG_REG0 |
システムコールの第1引数 | ebx | REG_REG4 |
システムコールの第2引数 | ecx | REG_REG5 |
システムコールの第3引数 | edx | REG_REG6 |
システムコールの第4引数 | esi | REG_REG7 |
システムコールの第5引数 | edi | REG_REG8 |
たぶんこんな感じで対応。
REG_REG3なんていう定義はどのヘッダにも書いてないので、自分で適当につける。SH4のasm/ptrace.hには
#define REG_REG0 0 #define REG_REG15 15
と書いてあったので、これから推測して適当に即値をつける。
スレッドを使ったプログラムだと、親スレッドの出力しか覗けない。
straceコマンドだと、-fとか-Fオプションを付ければスレッドのシステムコールも追うことが出来る。(つまりプロセス扱い)
どうやってんのかとstraceのソースを追ってみたら、/proc/(pid)/taskを見てた。どうやらここで得たプロセスID全部に対して 何かやってるっぽい。
あと、sarge用のstraceにはバグがあって、スレッドを使ったプログラムを追うと、Ctrl+Cでデタッチしきれなくなって元のプロセスごと殺すしかなくなる。迷惑すぎる。