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

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

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

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

C

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

バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

Q&A

解決済

2回答

1772閲覧

CTF : stackの扱いについて教えて下さい

fen57

総合スコア47

アセンブリ言語

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

C

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

バイナリ

バイナリは、「0」と「1」だけで表現されている2進数のデータ形式。または、テキスト以外の情報でデータが記述されているファイルを指します。コンピューター内の処理は全て2進数で表記されています。

GDB

GDBはGNUソフトウェアシステムのための標準的なデバッガーです。

0グッド

0クリップ

投稿2021/06/21 11:35

編集2021/06/21 12:20

CTFの問題を解いています。
その途中で、スタックに積まれる値にわからないところがあるので教えていただきたいです。

ソースコードは以下です
main.c

c

1#include <stdio.h> 2 3int main() 4{ 5 char buf[0x10] = ""; 6 7 fgets(buf, sizeof(buf), stdin); 8 printf(buf); 9 10 return 0; 11}

このソースを-no-pieでコンパイルしました

$ gcc -o main -no-pie main.c

できたバイナリをobjdumpで表示すると、以下のようになっています。

0000000000401176 <main>: 401176: f3 0f 1e fa endbr64 40117a: 55 push rbp 40117b: 48 89 e5 mov rbp,rsp 40117e: 48 83 ec 20 sub rsp,0x20 401182: 64 48 8b 04 25 28 00 mov rax,QWORD PTR fs:0x28 401189: 00 00 40118b: 48 89 45 f8 mov QWORD PTR [rbp-0x8],rax 40118f: 31 c0 xor eax,eax 401191: 48 c7 45 e0 00 00 00 mov QWORD PTR [rbp-0x20],0x0 401198: 00 401199: 48 c7 45 e8 00 00 00 mov QWORD PTR [rbp-0x18],0x0 4011a0: 00 4011a1: 48 8b 15 98 2e 00 00 mov rdx,QWORD PTR [rip+0x2e98] # 404040 <stdin@@GLIBC_2.2.5> 4011a8: 48 8d 45 e0 lea rax,[rbp-0x20] 4011ac: be 10 00 00 00 mov esi,0x10 4011b1: 48 89 c7 mov rdi,rax 4011b4: e8 c7 fe ff ff call 401080 <fgets@plt> 4011b9: 48 8d 45 e0 lea rax,[rbp-0x20] 4011bd: 48 89 c7 mov rdi,rax 4011c0: b8 00 00 00 00 mov eax,0x0 4011c5: e8 a6 fe ff ff call 401070 <printf@plt> 4011ca: b8 00 00 00 00 mov eax,0x0 4011cf: 48 8b 4d f8 mov rcx,QWORD PTR [rbp-0x8] 4011d3: 64 48 33 0c 25 28 00 xor rcx,QWORD PTR fs:0x28 4011da: 00 00 4011dc: 74 05 je 4011e3 <main+0x6d> 4011de: e8 7d fe ff ff call 401060 <__stack_chk_fail@plt> 4011e3: c9 leave 4011e4: c3 ret 4011e5: 66 2e 0f 1f 84 00 00 nop WORD PTR cs:[rax+rax*1+0x0] 4011ec: 00 00 00 4011ef: 90 nop

objdumpの結果から、スタックは以下のようになっていると予想したのですが、
rbp - 0x20 : buf ← rspが指している
rbp - 0x8 : canary
rbp - 0x0 : 古いrbp
rbp + 0x8 : mainの戻りアドレス

gdbで表示すると、予想した結果と少し異なる結果になっています。

gdb-peda$ b *0x00000000004011b4 Breakpoint 1 at 0x4011b4 gdb-peda$ run Starting program: /home/user/fmt_str/main [----------------------------------registers-----------------------------------] RAX: 0x7fffffffdee0 --> 0x0 RBX: 0x4011f0 (<__libc_csu_init>: endbr64) RCX: 0x4011f0 (<__libc_csu_init>: endbr64) RDX: 0x7ffff7fba980 --> 0xfbad2088 RSI: 0x10 RDI: 0x7fffffffdee0 --> 0x0 RBP: 0x7fffffffdf00 --> 0x0 RSP: 0x7fffffffdee0 --> 0x0 RIP: 0x4011b4 (<main+62>: call 0x401080 <fgets@plt>) R8 : 0x0 R9 : 0x7ffff7fe0d50 (endbr64) R10: 0x7 R11: 0x2 R12: 0x401090 (<_start>: endbr64) R13: 0x7fffffffdff0 --> 0x1 R14: 0x0 R15: 0x0 EFLAGS: 0x246 (carry PARITY adjust ZERO sign trap INTERRUPT direction overflow) [-------------------------------------code-------------------------------------] 0x4011a8 <main+50>: lea rax,[rbp-0x20] 0x4011ac <main+54>: mov esi,0x10 0x4011b1 <main+59>: mov rdi,rax => 0x4011b4 <main+62>: call 0x401080 <fgets@plt> 0x4011b9 <main+67>: lea rax,[rbp-0x20] 0x4011bd <main+71>: mov rdi,rax 0x4011c0 <main+74>: mov eax,0x0 0x4011c5 <main+79>: call 0x401070 <printf@plt> Guessed arguments: arg[0]: 0x7fffffffdee0 --> 0x0 arg[1]: 0x10 arg[2]: 0x7ffff7fba980 --> 0xfbad2088 [------------------------------------stack-------------------------------------] 0000| 0x7fffffffdee0 --> 0x0 0008| 0x7fffffffdee8 --> 0x0 0016| 0x7fffffffdef0 --> 0x7fffffffdff0 --> 0x1 0024| 0x7fffffffdef8 --> 0x1d2e5dab3e6bbb00 0032| 0x7fffffffdf00 --> 0x0 0040| 0x7fffffffdf08 --> 0x7ffff7df60b3 (<__libc_start_main+243>: mov edi,eax) 0048| 0x7fffffffdf10 --> 0x7ffff7ffc620 --> 0x5044800000000 0056| 0x7fffffffdf18 --> 0x7fffffffdff8 --> 0x7fffffffe22c ("/home/user/fmt_str/main") [------------------------------------------------------------------------------] Legend: code, data, rodata, value Breakpoint 1, 0x00000000004011b4 in main () gdb-peda$ x/8gx $rsp 0x7fffffffdee0: 0x0000000000000000 0x0000000000000000 0x7fffffffdef0: 0x00007fffffffdff0 0x1d2e5dab3e6bbb00 0x7fffffffdf00: 0x0000000000000000 0x00007ffff7df60b3 # ←戻りアドレス 0x7fffffffdf10: 0x00007ffff7ffc620 0x00007fffffffdff8 gdb-peda$ x/4wx 0x00007ffff7df60b3 0x7ffff7df60b3 <__libc_start_main+243>: 0x06e8c789 0x4800022b 0x0824448b 0xa23d8d48

スタックの0x1d2e5dab3e6bbb00がcanaryで、0x0000000000000000が古いrbpだと思うのですが、
0x00007fffffffdff0は何でしょうか?

よろしくお願いいたします。

追記1 : アセンブルリストの追記です

$ cat main.s .file "main.c" .text .globl main .type main, @function main: .LFB0: .cfi_startproc endbr64 pushq %rbp .cfi_def_cfa_offset 16 .cfi_offset 6, -16 movq %rsp, %rbp .cfi_def_cfa_register 6 subq $32, %rsp movq %fs:40, %rax movq %rax, -8(%rbp) xorl %eax, %eax movq $0, -32(%rbp) movq $0, -24(%rbp) movq stdin(%rip), %rdx leaq -32(%rbp), %rax movl $16, %esi movq %rax, %rdi call fgets@PLT leaq -32(%rbp), %rax movq %rax, %rdi movl $0, %eax call printf@PLT movl $0, %eax movq -8(%rbp), %rcx xorq %fs:40, %rcx je .L3 call __stack_chk_fail@PLT .L3: leave .cfi_def_cfa 7, 8 ret .cfi_endproc .LFE0: .size main, .-main .ident "GCC: (Ubuntu 9.3.0-17ubuntu1~20.04) 9.3.0" .section .note.GNU-stack,"",@progbits .section .note.gnu.property,"a" .align 8 .long 1f - 0f .long 4f - 1f .long 5 0: .string "GNU" 1: .align 8 .long 0xc0000002 .long 3f - 2f 2: .long 0x3 3: .align 8 4:

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

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

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

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

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

guest

回答2

0

ベストアンサー

gdbで表示すると、予想した結果と少し異なる結果になっています。

予想通りだと思いますがなにかご不満でしょうか?

0x00007fffffffdff0は何でしょうか?

特に意味のないアラインメントに見えます
想像ですが、rspの下位4ビットが0になるような呼び出し規約になっていて
8バイト分余計に確保することでbufの開始アドレスの下位4ビットを0にできる、と推測できます。

bufのサイズをいろいろ変更すると何かわかるかもしれません

投稿2021/06/21 12:32

asm

総合スコア15147

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

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

fen57

2021/06/21 12:52

ありがとうございます! メモリアラインメントということを考慮に入れていませんでした。とても勉強になりました。 bufを変更して色々と試してみようと思います!
guest

0

そもそものはなし、わざわざ逆アセンブルするんじゃなく、アセンブルリストを直接出したほうがよくないですか?

投稿2021/06/21 11:57

y_waiwai

総合スコア87774

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

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

fen57

2021/06/21 12:02

スタックの状態が見たかったので、gdbで見ればいいかと思い、-dでコンパイルする必要はないと考えたのですが、 アセンブルリストを直接出すとなにかメリットがあるのでしょうか?
y_waiwai

2021/06/21 12:11

逆アセンブルするメリットってのが全く無いですが。 アドレスずれてないと保障できます?w
fen57

2021/06/21 12:21

アセンブルリストを追記しました。 自分の知識不足で、アセンブルリストを眺めてもスタックの0x00007fffffffdff0が何かわからないので、ご教授お願いいたします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問