trace
shibuya.lisp#4以来の上京で、haskell.nightに行ってきた。haskell本が同時に2冊も 発行されるなんて、天変地異の前触れじゃなかろうか。しかも破格の値段との事。
LAMBDAの刻印本を入手。7章まで読んでみたけど、簡潔にして明瞭。数学の本を読んで いるみたい。RWHの方は、逆引きとして活用させてもらおう。理論と実例で旨く住み分け してるな。出版社のあの方達に敬意を表して、両方揃えておくのがBestだろう。
翌日は、秋葉原を散策。すっかりフィギュアの街になっているけど、裏通りに行ったら 盗聴機とその検知機を売っている店を発見。
マッチとポンプを揃えている怪しい店であった。マッチとポンプ、どちらが売れるんだ ろう。そして、どんな客層か、一日店員のアルバイトをしてみたいぞ。 社会勉強の為に。
エイリアン検出
前回は、golangが吐き出したバイナリーを、FreeBSDへ持ってきて実行すると Kernelを囲む殻(shell)ががっちりとガードしてくれる所を見た。
[sakae@fb ~/work]$ ./8.out -bash: ./8.out: cannot execute binary file [sakae@fb ~/work]$ /bin/sh $ ./8.out ./8.out: 1: Syntax error: "(" unexpected $ exit [sakae@fb ~/work]$ /bin/tcsh sakae@FB /home/sakae/work> ./8.out ./8.out: Exec format error. Binary file not executable.
ちょっと /bin/sh の挙動が怪しいっちゃ怪しいが、ちゃんと防衛してる。どこかの ウィルス防衛ソフトみたいだな。(ああ、あちらさんは、物によっては非常にのろまで 困るけど)
で、この防衛ってどうやってるのだろう? ちと興味が出てきたので、調べてみたい。 例によって、挫折するかも知れんけど!
上記3つの防衛ソフトのうち bash は、GNUからの輸入品なので取り敢えず除外すると して、まずは、tcshでは、どこで上記のエラーを出してるか調べてみる。
[sakae@fb ~]$ cd /usr/src/bin/tcsh bash: cd: /usr/src/bin/tcsh: No such file or directory [sakae@fb ~]$ cd /usr/src/bin/csh [sakae@fb /usr/src/bin/csh]$ ls Makefile config.h host.defs iconv_stub.c USD.doc/ config_p.h iconv.h
FreeBSDでは、tcsh = csh だと言う事をうっかり忘れてた。で、cshを見たけどめぼしい ものは何もない、こういう時はMakefileだな。
TCSHDIR= ${.CURDIR}/../../contrib/tcsh .PATH: ${TCSHDIR}
どうやら、寄贈品みたいだ。これって、Bill Joyからですかね?
[sakae@fb /usr/src/contrib/tcsh]$ grep 'Binary file not executable' *.[ch] sh.err.c: elst[ERR_ARCH] = CSAVS(1, 122, "%s: %s. Binary file not executable");
いやな予感がするなあと思って、sh.err.c を見たら、やっぱりで、エラーメッセージを 集めただけでした。どこから呼ばれているかを調べるのは、至難だなあ。方針を変えて もう一つのエラーはどうかな?
[sakae@fb /usr/src/contrib/tcsh]$ grep 'Exec format error' *.[ch] [sakae@fb /usr/src/contrib/tcsh]$ cd /usr/src [sakae@fb /usr/src]$ find . -name '*.c' | xargs grep 'Exec format error' ./contrib/binutils/libiberty/strerror.c: ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"), ./contrib/cvs/lib/strerror.c: ENTRY(ENOEXEC, "ENOEXEC", "Exec format error"), ./lib/libc/gen/errlst.c: "Exec format error", /* 8 - ENOEXEC */
tcsh内では見つからなかったので、システムワイドに調べてみた。特に手がかりに なりそうなものは無いなあ。これじゃ、man errno した方が良かったかも。
8 ENOEXEC Exec format error.「実行形式エラーです」実行を要求されたファイ ルのパーミッションは適切でしたが、実行可能ファイルとして要求され る形式ではありませんでした。
問題は、これがどのシステムコールによってもたらされるかだな。簡単な静的解析で 分かるかと思ったら、そうはいかなかったのね。そうなると、動的解析か。 gdbで追いかける、trace するぐらいしか思いつかんなあ。
traceはschemeの専売特許にあらず
FreeBSDには、traceによく似たktraceというのが用意されている。(Linuxだとstraceかな)これが使えるか試してみる。
ktraceの使い方は、引数にどんな内容を捕捉するかと、実行するコマンド名を指定する のが基本だ。しかし、実行コマンドとしていきなりtcshを指定しちゃうと、初期化 ファイルの読み込み等も捕捉されちゃって、ログが膨大になる。こういう時は、起動してる プロセスのtraceを取る方が、後の解析が楽になる。
[sakae@fb ~/work]$ ps PID TT STAT TIME COMMAND 636 v0 I 0:00.05 -bash (bash) 1073 v0 I+ 0:00.01 /bin/sh /usr/local/bin/startx 1091 v0 I+ 0:00.01 xinit /home/sakae/.xinitrc -- -auth /home/sakae/.serv : 1352 p1 I+ 0:00.05 /bin/tcsh : [sakae@fb ~/work]$ ktrace -t + -p 1352 [sakae@fb ~/work]$ ls 8.out* ktrace.out
別端末で起動してる/bin/tcshを終了すると、traceも終了して、ktrace.outという ログが作成される。但しこのログはバイナリーログなので、専用の解析ツール kdump を 使って閲覧する。
[sakae@fb ~/work]$ kdump : 1352 tcsh NAMI "./8.out" 1352 tcsh RET stat 0 : 1352 tcsh CALL vfork 1352 tcsh RET vfork 1370/0x55a : 1352 tcsh CALL wait4(0xffffffff,0xbfbfe05c,0x3,0xbfbfe060) 1352 tcsh RET wait4 1370/0x55a 1352 tcsh CALL wait4(0xffffffff,0xbfbfe05c,0x3,0xbfbfe060) 1352 tcsh RET wait4 -1 errno 10 No child processes :
残念ながら、私の乏しい知識では、これぐらいしか読みとれなかった。 でも、このログには、exec系のシステムコールが出てきてないな。だって、tcshの プロセスしか指定しなかったんだから、当たり前と言えばあたりまえ。ちゃんと 子プロセスまで追跡してログしないとだめだな。
[sakae@fb ~/work]$ ktrace -i /bin/tcsh
こうやって起動しておいて、ログを取り解析
2073 tcsh CALL vfork 2084 tcsh RET fork 0 : 2084 tcsh CALL execve(0x80c2000,0x80b7fe0,0x80c1100) 2084 tcsh NAMI "./8.out" 2084 tcsh RET execve -1 errno 8 Exec format error 2084 tcsh CALL open(0x80c2000,0,0xbfbfe0a8) 2084 tcsh NAMI "./8.out" 2084 tcsh RET open 3 2084 tcsh CALL read(0x3,0xbfbfe0e6,0x2) 2084 tcsh GIO fd 3 read 2 bytes 0x0000 7f45 |.E| 2084 tcsh RET read 2 2084 tcsh CALL close(0x3) 2084 tcsh RET close 0 2084 tcsh CALL write(0x2,0x80b3ca0,0x38) 2084 tcsh GIO fd 2 wrote 56 bytes "./8.out: Exec format error. Binary file not executable. " 2084 tcsh RET write 56/0x38 2084 tcsh CALL exit(0x1) 2073 tcsh RET vfork 2084/0x824 : 2073 tcsh CALL wait4(0xffffffff,0xbfbfe04c,0x3,0xbfbfe050) 2073 tcsh RET wait4 2084/0x824 2073 tcsh CALL wait4(0xffffffff,0xbfbfe04c,0x3,0xbfbfe050) 2073 tcsh RET wait4 -1 errno 10 No child processes 2073 tcsh CALL sigprocmask(0x3,0xbfbfe110,0)
プロセス2073が、最初起動したtcsh。そこから、vforkで2084が生まれ、 その中でexecveに より、8.out に変身しようとして、変身失敗してる。
そうか、execve で、何をやっているか見ればいいんだな。
execve
調べてみると、このコマンドはバイナリーファイルの起動のみならず、インタープリタの起動も請け負っているそうだ。P言語もR言語も、このシステムコールのお世話になって いるとても重要な働きをしてるんだなあ。 man の返り値の説明を読むと、上で出てきたのと微妙に違う表現になってる。
[ENOEXEC] 新しいプロセスファイルに適切なアクセス許可がありますが 、ヘッダのマジック番号が無効です。
さて、問題のexecveはシステムコールだから、/usr/src/sys の下で探せばいいのかな。
[sakae@fb /usr/src/sys]$ find . -name '*.c' | xargs grep execve -l : ./kern/imgact_aout.c ./kern/imgact_elf.c ./kern/imgact_gzip.c ./kern/imgact_shell.c ./kern/init_main.c ./kern/init_sysent.c ./kern/kern_descrip.c ./kern/kern_exec.c ./kern/kern_kse.c ./kern/kern_mib.c ./kern/kern_prot.c ./kern/kern_thread.c ./kern/subr_prof.c ./kern/syscalls.c ./kern/vfs_subr.c :
このあたりかなあ? 特に kern_exec.c あたりが怪しそう。 do_execve という関数の中に
for (i = 0; error == -1 && execsw[i]; ++i) { if (execsw[i]->ex_imgact == NULL || execsw[i]->ex_imgact == img_first) { continue; } error = (*execsw[i]->ex_imgact)(imgp); } if (error) { if (error == -1) { if (textset == 0) imgp->vp->v_vflag &= ~VV_TEXT; error = ENOEXEC; } goto exec_fail_dealloc; } : /* * Zero length files can't be exec'd */ if (attr->va_size == 0) return (ENOEXEC);
ENOEXECに注目してくと、上記のようになった。execsw[i]で、いろいろチェック してるんだな。本当の kernel-debuggerが欲しくなったぞ。 まあ、それは今のハードでは、ちと非力すぎるので諦めるしか。
ちと、趣を変えて、ENOEXECで grep してみると imgact_xx.c というのが引っかかって くる。息抜きに imgact_shell.c を見てみる。
/* * Don't allow a shell script to be the shell for a shell * script. :-) */ if (imgp->interpreted) return(ENOEXEC);
こんなスマイルマークが入っていたりして、和むなあ。この伝でいけば、elfファイルを 厳しくチェックしてるのは、imgact_elf.c って、事になるな。
ここをみると、11箇所に渡ってチェックしてるよ。それぞれは、elfの構造を 理解しないと無理だな。
最後は、いつも中途半端なんだよなぁ。ちと、反省! で、反省の証として、ちっちゃなプログラムを書いたよ。
母が分身を作って、変身させる
超小型のやつです。
// small sh // Usage: ./a.out /full/path/cmd #include <stdio.h> #include <unistd.h> int main(int argc, char *argv[], char *envp[]){ pid_t pid; pid = vfork(); if ( pid > 0 ){ // mother wait(NULL); printf("Mother finish\n"); } else { // child if (execve(argv[1], &argv[1], &envp[0]) == -1){ perror("Child Fail"); return 1; } return 0; } return 0; }
実行例です。
[sakae@fb ~/work]$ ./a.out /usr/bin/wc mysh.c 24 56 459 mysh.c Mother finish [sakae@fb ~/work]$ ./a.out /home/sakae/work/8.out Child Fail: Exec format error Mother finish Segmentation fault: 11 (core dumped)
悪い物を食べたようで、ゲロ吐いてますねぇ。 例の ktrace -i を使って、ログを取り、kdump -m 30 で、IO出力値を制限しつつ 表示してみます。また、正常な物を食べた時の例も表示。興味のない人は、見る 必要ありません。
こうして見ると、atomと言うか知らない単語が幾つも出てきています。一つづ単語帳を 開いて、意味を調べてみますかねぇ。 いい勉強になるぞ。
coreになった時
880 ktrace RET ktrace 0 880 ktrace CALL execve(0xbfbfe812,0xbfbfe708,0xbfbfe714) 880 ktrace NAMI "./a.out" 880 ktrace NAMI "/libexec/ld-elf.so.1" 880 a.out RET execve 0 880 a.out CALL mmap(0,0xf70,0x3,0x1000,0xffffffff,0,0,0) 880 a.out RET mmap 868687872/0x33c72000 880 a.out CALL munmap(0x33c72000,0xf70) 880 a.out RET munmap 0 880 a.out CALL __sysctl(0xbfbfe4a8,0x2,0x33c6e618,0xbfbfe4a4,0,0) 880 a.out RET __sysctl 0 880 a.out CALL mmap(0,0x8000,0x3,0x1002,0xffffffff,0,0,0) 880 a.out RET mmap 868687872/0x33c72000 880 a.out CALL issetugid 880 a.out RET issetugid 0 880 a.out CALL open(0x33c69468,0,0x1b6) 880 a.out NAMI "/etc/libmap.conf" 880 a.out RET open 3 880 a.out CALL fstat(0x3,0xbfbfdbc0) 880 a.out RET fstat 0 880 a.out CALL read(0x3,0x33c76000,0x1000) 880 a.out GIO fd 3 read 112 bytes "# Remap 5.x and 6.x libpthread" 880 a.out RET read 112/0x70 880 a.out CALL read(0x3,0x33c76000,0x1000) 880 a.out GIO fd 3 read 0 bytes "" 880 a.out RET read 0 880 a.out CALL close(0x3) 880 a.out RET close 0 880 a.out CALL open(0x33c686c0,0,0) 880 a.out NAMI "/var/run/ld-elf.so.hints" 880 a.out RET open 3 880 a.out CALL read(0x3,0xbfbfe470,0x80) 880 a.out GIO fd 3 read 128 bytes 0x0000 4568 6e74 0100 0000 8000 0000 8200 0000 |Ehnt............| 0x0010 0000 0000 8100 0000 0000 0000 0000 |..............| 880 a.out RET read 128/0x80 880 a.out CALL lseek(0x3,0,0x80,0,0) 880 a.out RET lseek 128/0x80 880 a.out CALL read(0x3,0x33c74100,0x82) 880 a.out GIO fd 3 read 130 bytes "/lib:/usr/lib:/usr/lib/compat:" 880 a.out RET read 130/0x82 880 a.out CALL close(0x3) 880 a.out RET close 0 880 a.out CALL access(0x33c78000,0) 880 a.out NAMI "/lib/libc.so.6" 880 a.out RET access 0 880 a.out CALL open(0x33c730c0,0,0) 880 a.out NAMI "/lib/libc.so.6" 880 a.out RET open 3 880 a.out CALL fstat(0x3,0xbfbfe4b0) 880 a.out RET fstat 0 880 a.out CALL read(0x3,0x33c6d560,0x1000) 880 a.out GIO fd 3 read 4096 bytes 0x0000 7f45 4c46 0101 0109 0000 0000 0000 0000 |.ELF............| 0x0010 0300 0300 0100 0000 d0ed 0100 3400 |............4.| 880 a.out RET read 4096/0x1000 880 a.out CALL mmap(0,0xe8000,0x5,0x20002,0x3,0,0,0) 880 a.out RET mmap 868720640/0x33c7a000 880 a.out CALL mprotect(0x33d45000,0x1000,0x7) 880 a.out RET mprotect 0 880 a.out CALL mprotect(0x33d45000,0x1000,0x5) 880 a.out RET mprotect 0 880 a.out CALL mmap(0x33d46000,0x6000,0x3,0x12,0x3,0,0xcb000,0) 880 a.out RET mmap 869556224/0x33d46000 880 a.out CALL mmap(0x33d4c000,0x16000,0x3,0x1012,0xffffffff,0,0,0) 880 a.out RET mmap 869580800/0x33d4c000 880 a.out CALL close(0x3) 880 a.out RET close 0 880 a.out CALL sysarch(0xa,0xbfbfe520) 880 a.out RET sysarch 0 880 a.out CALL mmap(0,0xa8,0x3,0x1000,0xffffffff,0,0,0) 880 a.out RET mmap 869670912/0x33d62000 880 a.out CALL munmap(0x33d62000,0xa8) 880 a.out RET munmap 0 880 a.out CALL mmap(0,0x5958,0x3,0x1000,0xffffffff,0,0,0) 880 a.out RET mmap 869670912/0x33d62000 880 a.out CALL munmap(0x33d62000,0x5958) 880 a.out RET munmap 0 880 a.out CALL mmap(0,0x9000,0x3,0x1002,0xffffffff,0,0,0) 880 a.out RET mmap 869670912/0x33d62000 880 a.out CALL sigprocmask(0x1,0x33c6d4a0,0xbfbfe4f0) 880 a.out RET sigprocmask 0 880 a.out CALL sigprocmask(0x3,0x33c6d4b0,0) 880 a.out RET sigprocmask 0 880 a.out CALL vfork 881 a.out RET fork 0 881 a.out CALL execve(0xbfbfe818,0xbfbfe714,0xbfbfe71c) 881 a.out NAMI "/home/sakae/work/8.out" 881 a.out RET execve -1 errno 8 Exec format error 881 a.out CALL writev(0x2,0xbfbfde60,0x4) 881 a.out GIO fd 2 wrote 30 bytes "Child Fail: Exec format error " 881 a.out RET writev 30/0x1e 881 a.out CALL exit(0x1) 880 a.out RET vfork 881/0x371 880 a.out CALL wait4(0xffffffff,0,0,0) 880 a.out RET wait4 881/0x371 880 a.out CALL fstat(0x1,0xbfbfded0) 880 a.out RET fstat 0 880 a.out CALL readlink(0x33d3e377,0xbfbfdef0,0x3f) 880 a.out NAMI "/etc/malloc.conf" 880 a.out RET readlink -1 errno 2 No such file or directory 880 a.out CALL issetugid 880 a.out RET issetugid 0 880 a.out CALL mmap(0,0x1000,0x3,0x1002,0xffffffff,0,0,0) 880 a.out RET mmap 869707776/0x33d6b000 880 a.out CALL break(0x804b000) 880 a.out RET break 0 880 a.out CALL break(0x804c000) 880 a.out RET break 0 880 a.out CALL ioctl(0x1,TIOCGETA,0xbfbfdf10) 880 a.out RET ioctl 0 880 a.out CALL write(0x1,0x804b000,0xe) 880 a.out GIO fd 1 wrote 14 bytes "Mother finish " 880 a.out RET write 14/0xe 880 a.out PSIG SIGSEGV SIG_DFL 880 a.out NAMI "a.out.core"
正常持、wcの一生が見られます。
956 a.out CALL vfork 957 a.out RET fork 0 957 a.out CALL execve(0xbfbfe81c,0xbfbfe714,0xbfbfe720) 957 a.out NAMI "/usr/bin/wc" 957 a.out NAMI "/libexec/ld-elf.so.1" 957 wc RET execve 0 956 a.out RET vfork 957/0x3bd 956 a.out CALL wait4(0xffffffff,0,0,0) 957 wc CALL mmap(0,0xf70,0x3,0x1000,0xffffffff,0,0,0) 957 wc RET mmap 868691968/0x33c73000 957 wc CALL munmap(0x33c73000,0xf70) 957 wc RET munmap 0 957 wc CALL __sysctl(0xbfbfe4b8,0x2,0x33c6f618,0xbfbfe4b4,0,0) 957 wc RET __sysctl 0 957 wc CALL mmap(0,0x8000,0x3,0x1002,0xffffffff,0,0,0) 957 wc RET mmap 868691968/0x33c73000 957 wc CALL issetugid 957 wc RET issetugid 0 957 wc CALL open(0x33c6a468,0,0x1b6) 957 wc NAMI "/etc/libmap.conf" 957 wc RET open 3 957 wc CALL fstat(0x3,0xbfbfdbd0) 957 wc RET fstat 0 957 wc CALL read(0x3,0x33c77000,0x1000) 957 wc GIO fd 3 read 112 bytes "# Remap 5.x and 6.x libpthread" 957 wc RET read 112/0x70 957 wc CALL read(0x3,0x33c77000,0x1000) 957 wc GIO fd 3 read 0 bytes "" 957 wc RET read 0 957 wc CALL close(0x3) 957 wc RET close 0 957 wc CALL open(0x33c696c0,0,0) 957 wc NAMI "/var/run/ld-elf.so.hints" 957 wc RET open 3 957 wc CALL read(0x3,0xbfbfe480,0x80) 957 wc GIO fd 3 read 128 bytes 0x0000 4568 6e74 0100 0000 8000 0000 8200 0000 |Ehnt............| 0x0010 0000 0000 8100 0000 0000 0000 0000 |..............| 957 wc RET read 128/0x80 957 wc CALL lseek(0x3,0,0x80,0,0) 957 wc RET lseek 128/0x80 957 wc CALL read(0x3,0x33c75100,0x82) 957 wc GIO fd 3 read 130 bytes "/lib:/usr/lib:/usr/lib/compat:" 957 wc RET read 130/0x82 957 wc CALL close(0x3) 957 wc RET close 0 957 wc CALL access(0x33c79000,0) 957 wc NAMI "/lib/libc.so.6" 957 wc RET access 0 957 wc CALL open(0x33c740c0,0,0) 957 wc NAMI "/lib/libc.so.6" 957 wc RET open 3 957 wc CALL fstat(0x3,0xbfbfe4c0) 957 wc RET fstat 0 957 wc CALL read(0x3,0x33c6e560,0x1000) 957 wc GIO fd 3 read 4096 bytes 0x0000 7f45 4c46 0101 0109 0000 0000 0000 0000 |.ELF............| 0x0010 0300 0300 0100 0000 d0ed 0100 3400 |............4.| 957 wc RET read 4096/0x1000 957 wc CALL mmap(0,0xe8000,0x5,0x20002,0x3,0,0,0) 957 wc RET mmap 868724736/0x33c7b000 957 wc CALL mprotect(0x33d46000,0x1000,0x7) 957 wc RET mprotect 0 957 wc CALL mprotect(0x33d46000,0x1000,0x5) 957 wc RET mprotect 0 957 wc CALL mmap(0x33d47000,0x6000,0x3,0x12,0x3,0,0xcb000,0) 957 wc RET mmap 869560320/0x33d47000 957 wc CALL mmap(0x33d4d000,0x16000,0x3,0x1012,0xffffffff,0,0,0) 957 wc RET mmap 869584896/0x33d4d000 957 wc CALL close(0x3) 957 wc RET close 0 957 wc CALL sysarch(0xa,0xbfbfe530) 957 wc RET sysarch 0 957 wc CALL mmap(0,0x118,0x3,0x1000,0xffffffff,0,0,0) 957 wc RET mmap 869675008/0x33d63000 957 wc CALL munmap(0x33d63000,0x118) 957 wc RET munmap 0 957 wc CALL mmap(0,0x5958,0x3,0x1000,0xffffffff,0,0,0) 957 wc RET mmap 869675008/0x33d63000 957 wc CALL munmap(0x33d63000,0x5958) 957 wc RET munmap 0 957 wc CALL mmap(0,0x9000,0x3,0x1002,0xffffffff,0,0,0) 957 wc RET mmap 869675008/0x33d63000 957 wc CALL sigprocmask(0x1,0x33c6e4a0,0xbfbfe500) 957 wc RET sigprocmask 0 957 wc CALL sigprocmask(0x3,0x33c6e4b0,0) 957 wc RET sigprocmask 0 957 wc CALL open(0xbfbfe240,0,0x1b6) 957 wc NAMI "/usr/share/locale/ja_JP.EUC-JP/LC_CTYPE" 957 wc RET open -1 errno 2 No such file or directory 957 wc CALL open(0xbfbfe828,0,0) 957 wc NAMI "mysh.c" 957 wc RET open 3 957 wc CALL read(0x3,0xbfbee620,0x10000) 957 wc GIO fd 3 read 459 bytes "// small sh // Usage: ./a.out " 957 wc RET read 459/0x1cb 957 wc CALL read(0x3,0xbfbee620,0x10000) 957 wc GIO fd 3 read 0 bytes "" 957 wc RET read 0 957 wc CALL fstat(0x1,0xbfbedd70) 957 wc RET fstat 0 957 wc CALL readlink(0x33d3f377,0xbfbedd90,0x3f) 957 wc NAMI "/etc/malloc.conf" 957 wc RET readlink -1 errno 2 No such file or directory 957 wc CALL issetugid 957 wc RET issetugid 0 957 wc CALL mmap(0,0x1000,0x3,0x1002,0xffffffff,0,0,0) 957 wc RET mmap 869711872/0x33d6c000 957 wc CALL break(0x804c000) 957 wc RET break 0 957 wc CALL break(0x804d000) 957 wc RET break 0 957 wc CALL ioctl(0x1,TIOCGETA,0xbfbeddb0) 957 wc RET ioctl 0 957 wc CALL close(0x3) 957 wc RET close 0 957 wc CALL write(0x1,0x804c000,0x20) 957 wc GIO fd 1 wrote 32 bytes " 24 56 459 mysh." 957 wc RET write 32/0x20 957 wc CALL exit(0) 956 a.out RET wait4 957/0x3bd 956 a.out CALL fstat(0x1,0xbfbfded0) 956 a.out RET fstat 0 956 a.out CALL readlink(0x33d3e377,0xbfbfdef0,0x3f) 956 a.out NAMI "/etc/malloc.conf" 956 a.out RET readlink -1 errno 2 No such file or directory 956 a.out CALL issetugid 956 a.out RET issetugid 0 956 a.out CALL mmap(0,0x1000,0x3,0x1002,0xffffffff,0,0,0) 956 a.out RET mmap 869707776/0x33d6b000 956 a.out CALL break(0x804b000) 956 a.out RET break 0 956 a.out CALL break(0x804c000) 956 a.out RET break 0 956 a.out CALL ioctl(0x1,TIOCGETA,0xbfbfdf10) 956 a.out RET ioctl 0 956 a.out CALL write(0x1,0x804b000,0xe) 956 a.out GIO fd 1 wrote 14 bytes "Mother finish " 956 a.out RET write 14/0xe 956 a.out CALL exit(0)