質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

Q&A

解決済

1回答

1170閲覧

シェルコードの実行に失敗してしまう

t4gforce

総合スコア5

アセンブリ言語

アセンブリ言語とは、機械語を人間にわかりやすい形で記述した低水準言語です。

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

シェル

シェル(shell)はUnix や Linux 系のOSで使用されるコマンドインタプリタを指します。

0グッド

0クリップ

投稿2020/08/02 04:08

前提・実現したいこと

「たのしいバイナリの歩き方」という本を参考に勉強をしています。
C言語で配列に入れたシェルコードを実行しようとしているのですが、実行に失敗します。
具体的には、システムコールを呼び出す部分 int 0x80が実行がスキップされてしまいます。
どなたかご教授お願いいたします。

発生している問題・エラーメッセージ

Program received signal SIGSEGV, Segmentation fault.
0x0804a061 in ?? ()

該当のソースコード

コンパイル前のc言語でのソースコードはこちらです。
ファイル名はsample7.cです。

c

1unsigned char shellcode[] = { 2 0x31, 0xc0, // xor %eax, %eax 3 0x50, // push %eax 4 0x89, 0xe0, // mov %esp, %eax 5 0x83, 0xe8, 0x0c, // sub $0x0c, %eax 6 0x50, // push %eax 7 0x89, 0xe3, // mov %esp, %ebx 8 0x68, 0x2f, 0x73, 0x68, 0x00, // push $0x68732f 9 0x68, 0x2f, 0x62, 0x69, 0x6e, // push $0x6e69622f 10 0x89, 0xe2, // mov %esp, %edx 11 0x31, 0xc0, // xor %eax, %eax 12 0x50, // push %eax 13 0x53, // push %ebx 14 0x52, // push %edx 15 0x50, // push %eax 16 0xb0, 0x3b, // mov $0x3b, %al 17 0xcd, 0x80, // int $0x80 18}; 19 20int main(void) 21{ 22 void (*p)(void); 23 p = (void(*)())shellcode; 24 p(); 25 return 0; 26}

以下のコマンドでコンパイルしました。

#gcc -Wall -m32 -fno-stack-protector -fno-asynchronous-unwind-tables -z execstack -g sample7.c -o sample7

試したこと

まず、実行権限を与えて実行した結果は以下になります。

$ ./sample7 Segmentation fault

fileコマンドでバイナリを調べました

$ file sample7 sample7: setuid ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=0xf5a9899dfa70c47141d86c76067829a81ab73fab, not stripped

次にgdbで処理を1行ずつ確認しました。

$ gdb sample7 GNU gdb (Ubuntu/Linaro 7.4-2012.02-0ubuntu2) 7.4-2012.02 Copyright (C) 2012 Free Software Foundation, Inc. ...省略... This GDB was configured as "i686-linux-gnu". For bug reporting instructions, please see: <http://bugs.launchpad.net/gdb-linaro/>... Reading symbols from /home/tk/target/sample7...done. (gdb) disas main Dump of assembler code for function main: 0x080483b4 <+0>: push %ebp 0x080483b5 <+1>: mov %esp,%ebp 0x080483b7 <+3>: and $0xfffffff0,%esp 0x080483ba <+6>: sub $0x10,%esp 0x080483bd <+9>: movl $0x804a040,0xc(%esp) 0x080483c5 <+17>: mov 0xc(%esp),%eax 0x080483c9 <+21>: call *%eax 0x080483cb <+23>: mov $0x0,%eax 0x080483d0 <+28>: leave 0x080483d1 <+29>: ret End of assembler dump. (gdb) b *0x080483c9 ; call *%eax の部分にブレークポイントをセット Breakpoint 1 at 0x80483c9: file sample7.c, line 24. (gdb) b *0x080483cb ; mov $0x0,%eax の部分にブレークポイントをセット Breakpoint 2 at 0x80483cb: file sample7.c, line 25. (gdb) run Starting program: /home/tk/target/sample7 Breakpoint 1, 0x080483c9 in main () at sample7.c:24 ; call *%eaxの部分で止まる 24 p(); (gdb) si ; shellcode内部に入る 0x0804a040 in shellcode () (gdb) disas shellcode Dump of assembler code for function shellcode: => 0x0804a040 <+0>: xor %eax,%eax 0x0804a042 <+2>: push %eax 0x0804a043 <+3>: mov %esp,%eax 0x0804a045 <+5>: sub $0xc,%eax 0x0804a048 <+8>: push %eax 0x0804a049 <+9>: mov %esp,%ebx 0x0804a04b <+11>: push $0x68732f 0x0804a050 <+16>: push $0x6e69622f 0x0804a055 <+21>: mov %esp,%edx 0x0804a057 <+23>: xor %eax,%eax 0x0804a059 <+25>: push %eax 0x0804a05a <+26>: push %ebx 0x0804a05b <+27>: push %edx 0x0804a05c <+28>: push %eax 0x0804a05d <+29>: mov $0x3b,%al 0x0804a05f <+31>: int $0x80 End of assembler dump. (gdb) b *0x0804a05f ; 最終行 int $0x80にブレークポイントをセット Breakpoint 3 at 0x804a05f (gdb) c Continuing. Breakpoint 3, 0x0804a05f in shellcode () ; int 0x80の前で処理が止まる (gdb) disas shellcode Dump of assembler code for function shellcode: 0x0804a040 <+0>: xor %eax,%eax 0x0804a042 <+2>: push %eax 0x0804a043 <+3>: mov %esp,%eax 0x0804a045 <+5>: sub $0xc,%eax 0x0804a048 <+8>: push %eax 0x0804a049 <+9>: mov %esp,%ebx 0x0804a04b <+11>: push $0x68732f 0x0804a050 <+16>: push $0x6e69622f 0x0804a055 <+21>: mov %esp,%edx 0x0804a057 <+23>: xor %eax,%eax 0x0804a059 <+25>: push %eax 0x0804a05a <+26>: push %ebx 0x0804a05b <+27>: push %edx 0x0804a05c <+28>: push %eax 0x0804a05d <+29>: mov $0x3b,%al => 0x0804a05f <+31>: int $0x80 End of assembler dump. (gdb) si ; int $0x80でシステムコールが実行されるはず・・・ 0x0804a061 in ?? () ; 実行されずプログラムカウンタが進んだ (gdb) x/i *0x0804a061 0x0: Cannot access memory at address 0x0 (gdb) si Program received signal SIGSEGV, Segmentation fault. 0x0804a061 in ?? ()

知識が足りず、どのようにして対処すればよいのかわからない状態です。
int $0x80のシステムコールが無視されてしまうので、なにか対処法を教えていただきたいです。

補足情報(FW/ツールのバージョンなど)

OS : Ubuntu 12.04 LTS 32bit
32bitであることは、コマンドでも確認しました。

$ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=12.04 DISTRIB_CODENAME=precise DISTRIB_DESCRIPTION="Ubuntu 12.04 LTS" $ uname -a Linux tk-VirtualBox 3.2.0-126-generic-pae #169-Ubuntu SMP Fri Mar 31 14:43:09 UTC 2017 i686 i686 i386 GNU/Linux

gcc (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
GNU gdb (Ubuntu/Linaro 7.4-2012.02-0ubuntu2) 7.4-2012.02

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

それFreeBSD用では?

投稿2020/08/02 06:12

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

t4gforce

2020/08/02 06:41 編集

回答していただきありがとうございます。 そのソースコードはFreeBSD用ですが、FreeBSDの過去の(書籍で指定している)バージョンが見つからなかったので、Ubuntuで試しています。 重ねて質問になってしまいますが、Ubuntu(カーネルは3.2.0)では、int 0x80でシステムコールをすることはできず、syscallやsysenterを使うしかないのでしょうか? いくつかのサイトでは、linuxカーネル2.6.xxでint 0x80でシステムコールを呼び出している例があったので、疑問に思いました。
t4gforce

2020/08/02 08:39

呼び出し規約が違ったのですね。 詳しく教えてくださりありがとうございました。とても参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問