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

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

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

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

C

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

バイナリ

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

GDB

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

解決済

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

fen57
fen57

総合スコア39

アセンブリ言語

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

C

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

バイナリ

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

GDB

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

2回答

0評価

0クリップ

767閲覧

投稿2021/06/21 11:35

編集2021/06/21 12:20

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

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

c

#include <stdio.h> int main() { char buf[0x10] = ""; fgets(buf, sizeof(buf), stdin); printf(buf); return 0; }

このソースを-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:

良い質問の評価を上げる

以下のような質問は評価を上げましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

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

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

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

teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

  • プログラミングに関係のない質問
  • やってほしいことだけを記載した丸投げの質問
  • 問題・課題が含まれていない質問
  • 意図的に内容が抹消された質問
  • 過去に投稿した質問と同じ内容の質問
  • 広告と受け取られるような投稿

評価を下げると、トップページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

まだ回答がついていません

会員登録して回答してみよう

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

ただいまの回答率
87.20%

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

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

質問する

関連した質問

同じタグがついた質問を見る

アセンブリ言語

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

C

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

バイナリ

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

GDB

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