CTF Binary

Command gadgets

  • Binary解析

file string nm ldd

vi

バイナリ編集

vi -b $1

:%!xxd
:%!xxd -r

hexdump

C付けないとよくわかんないことになる

hexdump -v -C

hexedit

  • Ctrl-xで保存・終了
  • Ctrl-cで終了

od

16進数ダンプ

od -Ax -tx1z -v
od -txCa

stringsで出力した文字を横並びで表示する

strings file |tr '\n' '\t'|fold -w 80
strings file |grep -v "\W"|tr '\n' '\t'|fold -w 80
strings file |sort|uniq|tr '\n' '\t'|fold -w 80
strings file |grep -v "\W"|sort|uniq|tr '\n' '\t'|fold -w 80

readelf

とりあえず-aオプションをつけとけばいい。

readelf -a

objdump

objdump -d
objdump -d -M intel binary_file > out.asm

-M intel はintel記法で出力の意味

gdb

よく使うコマンド

ディスアセンブルする。なんとなく、if文とかの場所がわかる。

disassemble main

そこにブレークポイントを設定する。

b *0x000000000040059e
b *0x40059e

そこまで進める

run

値を出力して確認してみる

x/1s $esi
x/1s 0x4005a3

固定値が格納されているスタックの始まりのアドレスがわかったら、こんな感じで全部出力できる。(x/sは文字列の出力)

x/100s 0x400666

int型だったりすると、よくわかんないから16進数表現にすればいい。

x/100x 0x400666

任意の関数も呼べます

0x00000000004010df:  call   0x4006b6

だったら、

set $pc=0x4006b6
c

引数に$pcを指定すれば、直後に実行される命令列が見れる。

x/10i $pc

常にアセンブラとレジスタの値を表示しておくこともできる。ほとんどolly dbg

layout asm
layout reg

フラグレジスタ

条件ジャンプとフラグ
http://wisdom.sakura.ne.jp/programming/asm/assembly13.html

フラグレジスタの内訳 意味
ビット 11 (OF) オーバーフロー発生
ビット 10 (DF) ストリング命令の方向を指定するフラグ
ビット 7 (SF) 演算結果が負
ビット 6 (ZF) 演算結果がゼロ
ビット 2 (PF) 演算結果の奇数パリティ (1 が偶数個のときに立つ)
ビット 0 (CF) キャリー発生 / ボロー発生

なんだけど、リトルエンディアンなので、実際にはひっくり返ってる。

eflagsとかで表現されるが、setする時は$psになる。

状態表示

(gdb) i r
中略
eflags         0x202    [ IF ]

設定

set $ps=0x242

オリジナルな.gdb.init

set disassembly-flavor intel
set follow-fork-mode child
set history save on
set history filename ~/.gdb_history
set history size 32768
set history expansion on

define xall
  i r eip esp ebp eax
  x/5i $eip
  x/32xw $esp
end

document xall
  Stack and disas helper
end

define xenv
  x/20s *environ
end

document xenv
  Print the environment variables
  from the stack
end

出力例

(gdb) xall
eip 0x80484d5 0x80484d5
esp 0xffffd290 0xffffd290
ebp 0xffffd2c8 0xffffd2c8
eax 0xffffd2a0 -11616
=> 0x80484d5: call 0x8048350 <read@plt>
   0x80484da: lea eax,[ebp-0x28]
   0x80484dd: mov DWORD PTR [esp],eax
0xffffd290: 0x00000000 0xffffd2a0 0x00000032 0x08048319
0xffffd2a0: 0xffffd516 0x0000002f 0x0804a000 0x08048562
0xffffd2b0: 0x00000001 0xffffd374 0xffffd37c 0xf7e3b42d

(gdb) xenv
0xffffd52b: "XDG_VTNR=7"
0xffffd536: "XDG_SESSION_ID=c2"
0xffffd5b2: "SHELL=/bin/bash"

gdb scriptの利用

打ち込みたいコマンドをメモしておいて,gdb起動と併せて実行できる。

$ gdb –q –x scriptfile ./binary

アセンブラプログラムのデバックの方法

http://www.hpcs.cs.tsukuba.ac.jp/~msato/lecture-note/kikaigo2008/gdb.pdf

アセンブラプログラムのデバックは、gdb(gnu debugger)を使って行うことができます。

ブレークポイントの設定と実行開始
課題のプログラムは main から始まるので、まず、ここで停止するように、break コマンドでmain にブレークポイントを設定します。(gdb)とプロンプトがでるので、ここで、

(gdb) break main

と入力します。次に、run コマンドmain まで実行します。

(gdb) run

すると、実行が始まり、main で停止するはずです。
プログラムのdisassembleここで、プログラムがどのようなコードになっているかについて、確認してみましょう。メモリ上の機械語になったプログラムをアセンブリプログラムで表示するのがdisassemble コマンドです。
disassemble とは、アセンブルの反対、つまり、機械語からアセンブラに直すことです。main から始まるプログラムをdisassemble してみましょう。

(gdb) disassemble main

main のところに、任意のラベル名を書くことでそのプログラムをdisassemble することができます。
プログラムのステップ実行1命令づつ実行するコマンドが、stepi です。

(gdb) stepi

ここで、stepi コマンドを実行するごとに1命令づつ実行されているのがわかるはずです。
レジスタの表示step 実行している途中で、レジスタの表示をして見ましょう。表示には2つの方法があります。

(gdb) info registers

では、すべてのレジスタの表示を行います。個別のレジスタを表示する場合には、

(gdb) print $レジスタ名

で表示させることができます。
実行の再開、ブレークポイントの設定continue コマンドは実行を次のブレークポイントまで(もしくは終わりまで)、実行を再開するコマン
ドです。

(gdb) continue

さて、main にブレークポイントを設定しましたが、main の代わりにラベル名を書くことで、そのラベルの前で実行を止めることができます。また、アドレスを指定したい場合には

(gdb) break *アドレス

で任意のアドレスで実行を中断することができます。

データの表示
データの表示を行うコマンドが x コマンドです。

(gdb) x アドレス

で、アドレスの内容をプリントすることができます。x のあとには、データ表示のフォーマットができて、例えば、x/のあとに、表示するデータの数、10 進(d)、16進(x)、8進(o)とそのあとに、b(byte), h(half), w(word)と指定します。たとえば、

(gdb) x/10dw 0x10000

では、0x10000 番地から、32 ビットごと(w)に10進(d)で、10ワード表示するという意味になります。詳しくは、help x としてみてください。他のコマンドについても、help コマンドで調べることができます。

(gdb) x/1s $esi
0x804c757:       "visilooksgoodinhotpants"

で、レジスタの指し先が出力されます。

gdb参考

ももいろテクノロジー - gdbの使い方のメモ
http://inaz2.hatenablog.com/entry/2014/05/03/044943

gdbについて
http://tech-hack-maswag.blogspot.jp/2013/03/gdb.html?m=1

オンラインgdb
https://www.onlinegdb.com/

epasveer/seer
https://github.com/epasveer/seer

Qt実装のgdbのGUIフロントエンド

最低限これだけ覚えておけばきっと解析できる命令

よく使うASM命令ベスト100位に説明つけてみた
http://wiki.onakasuita.org/pukiwiki/?%E3%82%88%E3%81%8F%E4%BD%BF%E3%81%86ASM%E5%91%BD%E4%BB%A4%E3%83%99%E3%82%B9%E3%83%88100%E4%BD%8D%E3%81%AB%E8%AA%AC%E6%98%8E%E3%81%A4%E3%81%91%E3%81%A6%E3%81%BF%E3%81%9F

CPU architecture

x86

ハンド (逆) アセンブルを補助するための PDF リスト!
http://d.hatena.ne.jp/a4lg/20120225/1330180431 http://dl.dropbox.com/u/2476414/TechResources/x86_opcodemap_1_a4.pdf
コンピュータアーキテクチャ
http://ist.ksc.kwansei.ac.jp/~ishiura/arc/ http://ist.ksc.kwansei.ac.jp/~ishiura/arc/n4.pdf
0F拡張チートシート
http://shiho-elliptic.tumblr.com/post/108012619924/0f http://elliptic-shiho.xyz/0F%20Opcode.pdf

ARM

[組み込み]ARMの場合、アセンブラが解れば機械語も解るCommentsAdd Star
http://d.hatena.ne.jp/kmt-t/20091105/1257380555 http://re-eject.gbadev.org/files/armref.pdf

機械語命令が ?? ?? ?? e? (リトルエンディアンなので、本当は 0xe? が先頭)になっているので、判別しやすい。

SPARC

AWKによるSPARC V8逆アセンブラ
http://keisanki.at.webry.info/201001/article_2.html

PowerPC

玄箱でアセンブリ 1 - はじめに
http://www.mztn.org/ppcasm/ppcasm01.html http://www.freescale.com/files/32bit/doc/ref_manual/MPC603EUM.pdf http://www.freescale.com/files/32bit/doc/ref_manual/G2CORERM.pdf
Cell Broadband Engine アーキテクチャ
http://cell.scei.co.jp/pdf/CBE_Architecture_v102_j.pdf
アセンブリ言語、はじめの一歩
http://www.comp.tmu.ac.jp/morbier/comparch/assem1new.html http://www.comp.tmu.ac.jp/morbier/comparch/6xx_pemchap8.pdf

MIPS

コンピュータアーキテクチャ
http://ist.ksc.kwansei.ac.jp/~ishiura/arc/ http://ist.ksc.kwansei.ac.jp/~ishiura/arc/n3.pdf
はじめて読むMIPS(リローデッド)
http://www.cqpub.co.jp/interface/TechI/Vol39/app/mips_asm.pdf
MIPS I の命令形式
http://www.weblio.jp/wkpja/content/MIPS%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3_MIPS+I+%E3%81%AE%E5%91%BD%E4%BB%A4%E5%BD%A2%E5%BC%8F

MMX

0から作るソフトウェア開発(をgoogle先生の検索で調べる)
https://www.google.co.jp/search?hl=ja&as_qdr=y15&lr=lang_ja&num=100&q=site:softwaretechnique.jp%200x0F&gws_rd=ssl

Z80

8ビット CPU Z80命令セット
http://www.yamamo10.jp/yamamoto/comp/Z80/instructions/index.php

x86

x86 - 解説

神解説

x86-64機械語入門
https://zenn.dev/mod_poppo/articles/x86-64-machine-code

トリコロールな猫 - OllyDbgを使ってx86アセンブラを学ぶシリーズ
https://note.mu/nekotricolor

GNU/Linux (x86/x86-64) のシステムコールをアセンブラから呼んでみる
https://blog.amedama.jp/entry/linux-system-call-assembler

Linux システムコール 徹底入門
https://www.kimullaa.com/entry/2020/01/05/191221


神無料サンプル

31バイトでつくるアセンブラプログラミング: アセンブラ短歌の世界
https://play.google.com/store/books/details/%E5%9D%82%E4%BA%95%E5%BC%98%E4%BA%AE_31%E3%83%90%E3%82%A4%E3%83%88%E3%81%A7%E3%81%A4%E3%81%8F%E3%82%8B%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0?id=6aqYAgAAQBAJ&hl=ja

Google Play の無料サンプルが、ちょうどいい感じの所まで読める。


神チートシート

d.sunnyone.org - x86/x86_64関数呼び出しチートシートを書いた
http://d.sunnyone.org/2012/09/x86x8664.html

Windows X86 System Call Table (NT/2000/XP/2003/Vista/2008/7/8/10)
http://j00ru.vexillium.org/syscalls/nt/32/

解答略 @kaitou_ryaku x86の機械語をざっと見渡すには、このpdfが世界で一番整理されてると思う。
https://twitter.com/kaitou_ryaku/status/1067424249814540288

ハンド (逆) アセンブルのための x86 ニーモニックの覚え方
http://d.hatena.ne.jp/a4lg/20120225/1330180431

X86 Opcode and Instruction Reference
http://ref.x86asm.net/coder64.html

レジスタ一覧

X86アセンブラ/x86アーキテクチャ
http://ja.wikibooks.org/wiki/X86%E3%82%A2%E3%82%BB%E3%83%B3%E3%83%96%E3%83%A9/x86%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3

X86_64のレジスタ
http://www.mztn.org/lxasm64/amd04.html

レジスタ

レジスタ ビット
eax 000
ecx 001
edx 010
ebx 011
esp 100
ebp 101
esi 110
edi 111

基本の命令の形

http://ist.ksc.kwansei.ac.jp/~ishiura/arc/n4.pdf

複雑

レジスタ=レジスタ+即値

8 2 3 3 8
命令 reg or 即値フラグ(11) レジスタ 000 即値
8 2 3 3 32
命令 reg or 即値フラグ(11) レジスタ 000 即値
8 32
命令 即値

レジスタ=レジスタ+レジスタ

8 2 3 3
命令 reg or 即値フラグ(11) レジスタ レジスタ

レジスタ=レジスタ+主記憶

ややこしいので略(pdf参照)

よく使う命令

https://dl.dropboxusercontent.com/u/2476414/TechResources/x86_opcodemap_1_a4.pdf

命令 OP Note
mov b or 8
push 5[0-7] or 68 or 6A
pop 5[8-F]
add 0[0-5]
xor 3[0-5]
nop 90
int cd
ret c3

システムコール

%EAXにシステムコール番号を入れて int 0x80 する。必要な引数は、%EBX %ECX %EDX に入れたりする。
writeシステムコールの戻り値は、%EAXに入る(文字数が入る)

関数復帰

ABIで決められているが、%EBX %ESP は、関数呼び出し前の値に戻して置かなければいけない。
ret前に%EAXには関数の復帰値を入れる必要がある

様々な代入法

movで即値(5byte)

mov $0x1 %eax

xorで初期化後に、レジスタ下位バイト(8bit)代入(2Byte+2Byte)

xor %eax %eax
mov %al

スタックにpushしてpop(2byte+1byte)

push $8
pop %eax

アセンブラ短歌

簡単なのは、ここで試せる(JavaScriptエミュレーション方式)
http://07c00.com/asmtanka_on_js/

SECCON - Assembly Tanka on Web
ちょと込み入ってても、こっちでも試せる(SandBox方式)
http://x86.seccon.jp/99.html

x86でwriteシステムコールにより、文字を出力する方法

  • %EAXに4(writeシステムコールの意味)を設定
  • %EBXに1(標準出力の意味)を設定
  • %ECXに表示する文字の先頭アドレスを設定
  • %EDXに出力する文字の長さを設定
  • int 0x80(システムコール)を実行

その後

  • %EAXにはwriteした文字数が設定される
  • retする前に%EAXには関数復帰値を設定する
  • %EBXは関数呼び出し前の値を保証するようABIに定められている。つまり、%EBXの値は元に戻す必要がある。

クロスコンパイル/実行環境

Article

七誌の開発日記 - 全部入りbinutils
http://7shi.hateblo.jp/entry/2013/07/30/011348

ももいろテクノロジー - x86/x86-64/ARM/AArch64/PowerPC/PowerPC64のアセンブリコードを読んでみる
http://inaz2.hatenablog.com/entry/2015/11/21/182410

gotbolt - C → 様々なASMのリアルタイムオンラインコンパイラー。アセンブリ・REを勉強している方におすすめ
https://godbolt.org/

GitHub - shutingrz/busybox-static-binaries-fat
https://github.com/shutingrz/busybox-static-binaries-fat

gdb

kozosより

cross-gcc4-20130826.zip をインストール済みのCentOS6.5イメージ (OVAフォーマット)
FreeBSDのVirtualBox用イメージを,OVAフォーマットにしたもの

Memo

ももいろテクノロジー - 各種アーキテクチャのクロスコンパイラ環境を構築する
http://inaz2.hatenablog.com/entry/2015/12/01/204201

QEMU

Memo

組み込みの人 - Aarch64で遊ぶ最も手軽な方法
http://d.hatena.ne.jp/embedded/20140819/p1

dockerからのqemu

katagaitai CTF勉強会|hard
https://atnd.org/events/71808

fon.tar.gzが、QEMU環境

動的解析できる別の ARM環境このリンク先に手順を用意しています

ももいろテクノロジー - qemu-debootstrapを使ってユーザモードQEMUで動くDockerイメージを作ってみる
http://inaz2.hatenablog.com/entry/2015/11/26/220948

Androidアプリの逆コンパイル

メモ

  • dex2jar デコンパイラ
  • jd-gui ソースを読む
  • apktool リバースエンジニアリングツール

BYTECODE VIEWER (AN ADVANCED YET USER FRIENDLY JAVA REVERSE ENGINEERING SUITE.)
http://bytecodeviewer.com/

改造apk(MOD)の作り方 & その対策 - Qiita
https://qiita.com/yukiarrr/items/764adb88f5a485f714d8

1,000行で作るオペレーティングシステム
https://seiya.me/blog/operating-system-in-1000-lines

.NETの逆コンパイル

メモ

ILSpy
http://ilspy.net/

dnSpy
https://github.com/0xd4d/dnSpy/releases/tag/v5.0.0 凄すぎて大草原不可避な.NET デコンパイラdnSpyを使ってみる

Reflexil
http://reflexil.net/

Javaバイトコード

知らなくても困らない Javaクラスのバイトコードの読み方
http://etc9.hatenablog.com/entry/2017/11/02/231509

Misc

コンピュータアーキテクチャ
http://ist.ksc.kwansei.ac.jp/~ishiura/arc/

Hexinator というCTFのために生まれてきたようなバイナリエディタ
https://hexinator.com/

POSTD - システムコールを経由する生のLinuxスレッド
http://postd.cc/raw-linux-threads-via-system-calls/

Programming Field - スタック
http://pf-j.sakura.ne.jp/program/stack.htm

POSTD - Linuxシステムコール徹底ガイド
http://postd.cc/the-definitive-guide-to-linux-system-calls/

組み込みの人。 - gdbで標準ライブラリの中を探検する
http://d.hatena.ne.jp/embedded/20130120/p1

ニコナレ - 機械学習を支えるx86-64の拡張命令セットを読む会
http://niconare.nicovideo.jp/watch/kn2333

C言語の文字列はどこに?-ELFバイナリに見る実行プログラムの挙動-
https://drumato.hatenablog.com/entry/2019/05/03/111608

オブジェクトファイルのシンボルテーブルを最低限理解する。
https://drumato.hatenablog.com/entry/2019/05/16/201234

strace コマンドの使い方をまとめてみた
http://blog.livedoor.jp/sonots/archives/18193659.html

定番のデバッグ・調査ツールであるstraceでエラーインジェクション
https://gihyo.jp/admin/serial/01/ubuntu-recipe/0762?utm_source=feed

【CTF入門】ELFバイナリのリバースエンジニアリングに入門してみよう
https://yukituna.com/3711/

6502 アセンブラ プログラミング入門
https://euske.github.io/slides/asm6502/index.html

ふつうのLinuxプログラミング-プロセスとハードウェア
https://speakerdeck.com/sksat/hutuufalselinuxpuroguramingu-purosesutohadouea

Linux システムコール 徹底入門
https://www.kimullaa.com/posts/202001051012/

eBPFのリバースエンジニアリング入門
https://engineering.mercari.com/blog/entry/20240228-b47712375d/

クリップボードから画像を追加 (サイズの上限: 100 MB)