Slide 1

Slide 1 text

アセンブリにHello! trimscash

Slide 2

Slide 2 text

自己紹介 trimscash 趣味 CTF 幽霊と化してる

Slide 3

Slide 3 text

なぜアセンブリで遊ぶのか 縛りプレイ的楽しさ! コンピュータの動作がより分かるように! CTFで使える! デバッグができるようになる!

Slide 4

Slide 4 text

なぜアセンブリで遊ぶのか

Slide 5

Slide 5 text

なぜアセンブリで遊ぶのか

Slide 6

Slide 6 text

アセンブリってなんだ?

Slide 7

Slide 7 text

アセンブリってなんだ. .intel_syntax noprefix .global main main: mov rax, 1 # write mov rdi, 1 # std 1 lea rsi, _helloworld # string address mov rdx, 10 # length syscall mov rax, 60 # exit mov rdi, 0 syscall .data _helloworld: .asciz "helloworld" こんなの→ コンピュータがわかる機械語(数値 人間がわかるように したもの!

Slide 8

Slide 8 text

アセンブリってなんだ. CPUが理解できる指示! 機械語とは.. C言語やら,RustやらPythonやら書い たとて, 最終的に機械語になる!!

Slide 9

Slide 9 text

アセンブリってなんだ. .intel_syntax noprefix .global main main: mov rax, 1 # write mov rdi, 1 # std 1 lea rsi, _helloworld # string address mov rdx, 10 # length syscall mov rax, 60 # exit mov rdi, 0 syscall .data _helloworld: .asciz "helloworld" こんなの→ コンピュータがわかる機械語(数値 人間がわかるように したもの!

Slide 10

Slide 10 text

アセンブリってなんだ. コンパイルして実行形式のファイルを得る C言語 実行形式ファイル(機械語の集まり

Slide 11

Slide 11 text

アセンブリってなんだ. 中を見てみると.. 読めん!わからん! 実行形式ファイル(機械語の集まり

Slide 12

Slide 12 text

アセンブリってなんだ. 実行形式ファイル(機械語の集まり 人間はふつう読めない... じゃあ見やすく 機械語一つ一つに名前を 付けてあげよう! ←これがアセンブリ,だいぶ見やすくなった.

Slide 13

Slide 13 text

アセンブリを学ぶ まずはHelloWorldしてみよう! 環境: x86_64(macとかでなければOK), Linux (wslでOK) , gcc

Slide 14

Slide 14 text

.intel_syntax noprefix .global main main: mov rax, 1 # writeを指定 mov rdi, 1 # std 1 標準出力 lea rsi, _helloworld # string address 文字列のアドレス mov rdx, 10 # length syscall # syscall呼び出し mov rax, 60 # exitを指定 mov rdi, 0 # 引数に0 (error_code syscall # syscall呼び出し .data _helloworld: # 文字列が置かれているアドレスに名前を付けた. .asciz “helloworld” # ここに文字列のデータを置く

Slide 15

Slide 15 text

.intel_syntax noprefix # アセンブラの構文指定 .global main # main をグローバルにする ディレクティブ コンパイラへ渡す説明文. .data # これより下ではデータを保存していると指定 _helloworld: .asciz “helloworld” # ascizで文字列をここに保存

Slide 16

Slide 16 text

main: # プログラムが格納されているここのアドレスにmainと命名. mov rax, 1 # write mov rdi, 1 # std 1 ######### 略 ラベル アドレスに名前つけられる. 末尾にコロンをつける. .data _helloworld: # ラベル, このアドレスに文字列が格納 .asciz “helloworld”

Slide 17

Slide 17 text

レジスタ CPU内部にある小さいメモリ. main: mov rax, 1 mov rdi, 1 lea rsi, _helloworld mov rdx, 10 syscall mov rax, 60 mov rdi, 0 syscall

Slide 18

Slide 18 text

レジスタ レジスタ一覧. https://www.jamieweb.net/info/x86_64-general-purpose-registers-reference/

Slide 19

Slide 19 text

命令 CPUに動作を命令する. このプログラムには3つしかない. mov syscall lea

Slide 20

Slide 20 text

mov rax, 1 # rax = 1 mov命令 左辺のレジスタorメモリに右辺の値をコピーする. 上例の動作: rax = 1

Slide 21

Slide 21 text

lea rsi, _helloworld lea命令 左辺のレジスタorメモリに右辺のアドレス自体 をコピーする. 上例の動作: rsi = _helloworldのさすアドレス

Slide 22

Slide 22 text

syscall syscall命令 カーネル(OS)の機能(syscall)を呼び出す. raxにsyscallを指定する番号を入れる. その他レジスタに引数を渡す.

Slide 23

Slide 23 text

syscall命令 raxにsyscallを指定する番号を入れる. Syscall一覧https://filippo.io/linux-syscall-table/

Slide 24

Slide 24 text

syscall命令 raxにsyscallを指定する番号を入れる. Syscall一覧https://filippo.io/linux-syscall-table/

Slide 25

Slide 25 text

syscall命令 例:exit(0) Syscall一覧https://filippo.io/linux-syscall-table/

Slide 26

Slide 26 text

syscall命令 例:exit(0) mov rax, 60 # exitを指定 mov rdi, 0 # 引数に0 (error_code syscall # syscall呼び出し

Slide 27

Slide 27 text

syscall命令 例:exit(0) mov rax, 60 # exitを指定 mov rdi, 0 # 引数に0 (error_code syscall # syscall呼び出し

Slide 28

Slide 28 text

アセンブリを書く 知識はそろった!手を動かそう! gcc -c filename.s -o filename.o && ld -e main -o filename filename.o コンパイル,リンクは↑のコマンドで(linux

Slide 29

Slide 29 text

.intel_syntax noprefix .global main main: mov rax, 1 # writeを指定 mov rdi, 1 # std 1 標準出力 lea rsi, _helloworld # string address 文字列のアドレス mov rdx, 10 # length syscall # syscall呼び出し mov rax, 60 # exitを指定 mov rdi, 0 # 引数に0 (error_code syscall # syscall呼び出し .data _helloworld: # 文字列が置かれているアドレスに名前を付けた. .asciz “helloworld” # ここに文字列のデータを置く

Slide 30

Slide 30 text

アセンブリを書く 画面に文字を出力するには? 標準出力に文字をwriteする! writeのsyscallを呼ぼう! Syscall一覧https://filippo.io/linux-syscall-table/

Slide 31

Slide 31 text

例:write(stdout, “helloworld”, 10) mov rax, 1 # writeを指定 mov rdi, 1 # 標準出力を指定.1は標準出力 lea rsi, _helloworld # 文字列のアドレス mov rdx, 10 # 文字列の長さ(出力するbyte数 syscall # syscall呼び出し

Slide 32

Slide 32 text

.intel_syntax noprefix .global main main: mov rax, 1 # writeを指定 mov rdi, 1 # std 1 標準出力 lea rsi, _helloworld # string address 文字列のアドレス mov rdx, 10 # length syscall # syscall呼び出し mov rax, 60 # exitを指定 mov rdi, 0 # 引数に0 (error_code syscall # syscall呼び出し .data _helloworld: # 文字列が置かれているアドレスに名前を付けた. .asciz “helloworld” # ここに文字列のデータを置く

Slide 33

Slide 33 text

アセンブリを動かす 書けた!コンピュータを動かそう! gcc -c filename.s -o filename.o && ld -e main -o filename filename.o コンパイル,リンクは↑のコマンドで(linux

Slide 34

Slide 34 text

アセンブリを動かす gcc -c filename.s -o filename.o && ld -e main -o filename filename.o コンパイル,リンクは↑のコマンドで(linux

Slide 35

Slide 35 text

アセンブリを動かす 動いた!!!!やったね! 動いた!!!!やったね!

Slide 36

Slide 36 text

アセンブリ ほかにも知るべきことはたくさんありここでは,伝えきることができない! (スタックとか,リターンアドレスとか,いろんな命令とか,いろいろ)(略). そして僕の説明がわかりにくかったかもしれない! のでリンクを張る. - 人間コンパイラコンテストのチュートリアル https://github.com/Alignof/HCCC_Tutorial/tree/master - x86のやつだけどわかりやすいやつ https://doomo.main.jp/x86asm/ - レジスタ一覧 https://www.jamieweb.net/info/x86_64-general-purpose-registers-reference/ - syscall一覧 https://filippo.io/linux-syscall-table - (CTF)pwn入門(僕が書いたやつ.スタックとか説明してるよあとCTFやれ https://qiita.com/trimscash/items/71f417f99508f8ca78f8

Slide 37

Slide 37 text

最後に ほかにも知るべきことはたくさんありここでは, 伝えきることができない! 自分で調べて,学び,手を動かすことが大切! 授業だけではもったいない... 結局...

Slide 38

Slide 38 text

最後に みんなアセンブラを書こう!

Slide 39

Slide 39 text

そして みんなCTFをやろう!

Slide 40

Slide 40 text

アセンブリにHello! trimscash