5209
コメント:
|
← 2016-02-12 13:56:08時点のリビジョン21 ⇥
5131
|
削除された箇所はこのように表示されます。 | 追加された箇所はこのように表示されます。 |
行 1: | 行 1: |
## page was renamed from CTF/inside/Toolkit/METASM | |
行 2: | 行 3: |
METASMはPure Rubyで記述されている、アセンブラ、逆アセンブラ、コンパイラ、リンカー、デバッガーである。 | METASMはRubyで記述されている、アセンブラ、逆アセンブラ、コンパイラ、リンカ、デバッガといった機能を持つライブラリ/アプリケーションである。 |
行 10: | 行 11: |
ドキュメントはソースコードとなっているが、それなりに綺麗に書かれている。 | <<TableOfContents>> == インストール方法 == === 事前に必要なもの === METASMを使うためにはRubyがインストールされている必要がある。 |
行 12: | 行 16: |
<<TableOfContents>> == インストール == リポジトリをクローンする。 |
=== 手動インストール(UNIX) === GITHUBからリポジトリをクローンする。 |
行 22: | 行 25: |
関連gemをインストールする(GUI逆アセンブラーを使う場合のみ) | gtk2-gemをインストールする(GUI版の逆アセンブラーを使う場合のみ) |
行 27: | 行 31: |
== Tools == samplesディレクトリに利用例としてツールが入っている。(大体はRubyから扱うためのSampleである) |
=== gemを用いたインストール === METASMは[[https://rubygems.org/gems/metasm|rubygems]]でも配布されているため、`gem`コマンドを使ってインストールすることができる。 {{{ $ gem install metasm }}} 特にライブラリとして用いる時はこちらが楽。 |
行 30: | 行 38: |
*disassemble-gui.rb *GUI版逆アセンブラ。ファイルの編集が出来たり、関数の分岐などをグラフにして表示する機能があったりする。 *disassemble.rb *逆アセンブラ *lindebug.rb *Win32/Linux用のラインデバッガー 有用性が微妙なもの *bindiff.rb *ふたつの逆アセンブルを比較する *dump_upx.rb *UPXをUnpackする *struct_offset.rb *構造体の要素の位置を調べる == 逆アセンブラ == === 基本的な利用方法 === |
== 逆アセンブラ(GUI) == samplesディレクトリに利用例として様々なツールが入っている。(大体はRubyから扱うためのSampleである) 逆アセンブラ(GUI)はdisassmble-gui.rbという名前で入っている。 === 起動方法 === disassmble-gui.rbを実行して起動する。 |
行 46: | 行 45: |
$ ruby disassmble.rb --cpu <CPU名> --exe <ファイルフォーマット> [その他オプション] 実行ファイル | ruby metasm/samples/disassmble-gui.rb --cpu <CPU名> --exe <ファイルフォーマット> [その他オプション] (実行ファイル) |
行 48: | 行 47: |
`--cpu`や`--exe`を省略しても自動的に適切なものを選んでくれる | CPU名やファイルフォーマットは基本的に自動認識してくれるので指定する必要はない。 |
行 50: | 行 49: |
=== 逆アセンブル(CUI) === デフォルトでちゃんとbacktraceしてくれる。 |
=== キーボードショートカット === ||<ROWCLASS="header"> キー || 効果 || || c || 逆アセンブル || || C || 逆アセンブル(バックトラックなし、関数呼び出し無視) || || Ctrl+C || 逆アセンブル(バックトラックなし) || || g || 特定アドレスへ移動 || || Return || callやjmpを辿る || || Esc || 元の場所に戻る || || Ctrl+Enter || 元の場所に戻るのをやりなおし || || f || 関数一覧を表示 || || x || 呼び出し元を列挙 || || K || 関数内のローカル変数に名前を付ける || || b || backtrace || || n || ラベルの名前を変更する || || Tab || 逆コンパイル || || / || 検索 || || Ctrl+f || 正規表現検索し、列挙する || |
行 53: | 行 67: |
関数の呼び出し元なども表示してくれるのが便利。 {{{ $ ruby disassemble.rb --cpu x86_64 --exe ELF a.out // ELF segment at 400000h, flags = R, X db 7fh, "ELF", 2, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; @400000h db 2, 0, 3eh, 0, 1, 0, 0, 0, 40h, 4, 40h, 0, 0, 0, 0, 0 ; @400010h db 40h, 0, 0, 0, 0, 0, 0, 0, 38h, 0bh, 0, 0, 0, 0, 0, 0 ; @400020h (中略) // Xrefs: __libc_start_main main: // function binding: r10,r11,r8,r9,rcx,rdi,rdx -> unknown, rax -> 0, rsp -> rsp+8 // function ends at 400539h push rbp ; @40050ch 55 mov rbp, rsp ; @40050dh 4889e5 sub rsp, 10h ; @400510h 4883ec10 mov [rbp-4], edi ; @400514h 897dfc cmp dword ptr [rbp-4], 1 ; @400517h 837dfc01 jnz loc_400529h ; @40051bh 750c x:loc_400529h mov edi, 4005ech ; @40051dh bfec054000 call thunk_puts ; @400522h e8b9feffff x:thunk_puts jmp loc_400533h ; @400527h eb0a x:loc_400533h // Xrefs: 40051bh loc_400529h: mov edi, 4005f2h ; @400529h bff2054000 call thunk_puts ; @40052eh e8adfeffff x:thunk_puts // Xrefs: 400527h loc_400533h: mov eax, 0 ; @400533h b800000000 leave ; @400538h c9 ret ; @400539h c3 endsub main db 90h, 90h, 90h, 90h, 90h, 90h ; @40053ah // Xrefs: __libc_start_main (以下省略) }}} 文字列を参照している場合の表示を行うことが出来る。 {{{ $ ruby disassemble.rb --post-plugin ~/local/metasm/samples/dasm-plugins/stringsxrefs.rb (FILE) (中略) push xref_406018h ; @401057h 6818604000 "password OK\n" (中略) }}} backtraceのせいで逆コンパイルが終わらない場合は、`--fast`オプションを付与すると良い。 === 逆コンパイル === Boomerangと違って64bit ELFファイルの逆コンパイルもしてくれるが実用性はほとんどない。いろいろと間違ってるし。 {{{#!highlight c $ ruby disassemble.rb --decompile --cpu x86_64 --exe ELF a.out (中略) int main __attribute__((stackoff:-8))(int rbp __attribute__((register(rbp))), int rdi __attribute__((register(rdi)))) { register int eax __attribute__((register(eax))); register int rbp_a0 __attribute__((register(rbp))); register int rsp __attribute__((register(rsp))); register int rsp_a0 __attribute__((register(rsp))); rsp_a0 = (rsp - 8); *(int*)(rsp_a0 - 8) = rbp; rbp_a0 = rsp_a0; *(int*)(rbp_a0 - 4) = rdi; *(__int32*)(rbp_a0 - 4) != 1; puts(); return eax; } }}} == シェルコード == |
== ライブラリ == === シェルコード === |
行 137: | 行 79: |
=== デバッガ === ==== プロセスを実行する ==== Metasm::OS.currentで現在のOSを取得することが出来る。(Metasm::LinOSかMetasm::WinOSのどちらか) OS.create_processにより新規プロセスをコマンドを指定して実行出来る。 {{{#!highlight ruby require 'metasm' process = Metasm::OS.current.create_process('./a.out') # 引数を渡す場合は process = Metasm::OS.current.create_process('./a.out ARGV1 ARGV2') debugger = process.debugger debugger.run_forever }}} ==== プロセスにアタッチする ==== {{{#!highlight ruby # 特定の名前またはpidを持つ最初のプロセスを返す pid = Metasm::OS.current.find_process('./a.out').pid process = Metasm::OS.current.open_process(pid) debugger = process.debugger }}} ==== 標準入出力を確保してプロセスを実行する ==== {{{#!highlight ruby io = IO.popen(['./a.out', 'aaa'], 'r+') debugger = Metasm::OS.current.open_process(io.pid).debugger }}} ==== ブレークポイント ==== ===== ソフトウェアブレークポイント ===== `Debugger.bpx(アドレス, 一度のみか, &callback)` {{{#!highlight ruby debugger.bpx(0x40051d, true) do puts "eax=#{debuger[:eax]}" end }}} ===== ハードウェアブレークポイント ===== `Debugger.hwbp(アドレス, タイプ(:r, :w, :x)のどれか, メモリサイズ, 一度のみか, &callback)` {{{#!highlight ruby debugger.hwbp(0x40051d, :x, 1, true) do puts "eax=#{debuger[:eax]}" end }}} ===== メモリアクセスブレークポイント ===== {{{#!wiki note 現在実装されていない }}} `Debugger.mbp(アドレス, タイプ(:r, :w)のどれか, メモリサイズ, 一度のみか, &callback)` {{{#!highlight ruby debugger.mbp(0x40051d, :r, 1, true) do puts "Access" end }}} ==== アンチ・アンチデバッギング ==== ===== Windows, is_debugger_present対策 ===== {{{#!highlight ruby dbg[process.peb_base + 0x02, 1] = "\0" # is_debbuger_present() => falseにする }}} |
METASM
METASMはRubyで記述されている、アセンブラ、逆アセンブラ、コンパイラ、リンカ、デバッガといった機能を持つライブラリ/アプリケーションである。
- 対応アーキテクチャ
- x86_64,ia32,mips,ppc (unstable: arc,arm,bpf,cy16,dalvik,python,sh4,z80)
- 対応フォーマット
- a.out,elf,pe,raw,Mach-O,nds,xcoffなど
目次
インストール方法
事前に必要なもの
METASMを使うためにはRubyがインストールされている必要がある。
手動インストール(UNIX)
GITHUBからリポジトリをクローンする。
$ git clone https://github.com/jjyg/metasm/ ~/local/metasm
環境変数RUBYLIBにmetasmのディレクトリを追加する。.bashrcや.zshenvなどに以下を記述。
[[ -s "$HOME/local/metasm" ]] && export RUBYLIB="$HOME/local/metasm"
gtk2-gemをインストールする(GUI版の逆アセンブラーを使う場合のみ)
$ gem install gtk2
gemを用いたインストール
METASMはrubygemsでも配布されているため、gemコマンドを使ってインストールすることができる。
$ gem install metasm
特にライブラリとして用いる時はこちらが楽。
逆アセンブラ(GUI)
samplesディレクトリに利用例として様々なツールが入っている。(大体はRubyから扱うためのSampleである) 逆アセンブラ(GUI)はdisassmble-gui.rbという名前で入っている。
起動方法
disassmble-gui.rbを実行して起動する。
ruby metasm/samples/disassmble-gui.rb --cpu <CPU名> --exe <ファイルフォーマット> [その他オプション] (実行ファイル)
CPU名やファイルフォーマットは基本的に自動認識してくれるので指定する必要はない。
キーボードショートカット
キー |
効果 |
c |
逆アセンブル |
C |
逆アセンブル(バックトラックなし、関数呼び出し無視) |
Ctrl+C |
逆アセンブル(バックトラックなし) |
g |
特定アドレスへ移動 |
Return |
callやjmpを辿る |
Esc |
元の場所に戻る |
Ctrl+Enter |
元の場所に戻るのをやりなおし |
f |
関数一覧を表示 |
x |
呼び出し元を列挙 |
K |
関数内のローカル変数に名前を付ける |
b |
backtrace |
n |
ラベルの名前を変更する |
Tab |
逆コンパイル |
/ |
検索 |
Ctrl+f |
正規表現検索し、列挙する |
ライブラリ
シェルコード
RubyのExploit上で直接Shellcodeを書くことが可能になる。
デバッガ
プロセスを実行する
Metasm::OS.currentで現在のOSを取得することが出来る。(Metasm::LinOSかMetasm::WinOSのどちらか)
OS.create_processにより新規プロセスをコマンドを指定して実行出来る。
プロセスにアタッチする
標準入出力を確保してプロセスを実行する
ブレークポイント
ソフトウェアブレークポイント
Debugger.bpx(アドレス, 一度のみか, &callback)
ハードウェアブレークポイント
Debugger.hwbp(アドレス, タイプ(:r, :w, :x)のどれか, メモリサイズ, 一度のみか, &callback)
メモリアクセスブレークポイント
現在実装されていない
Debugger.mbp(アドレス, タイプ(:r, :w)のどれか, メモリサイズ, 一度のみか, &callback)
アンチ・アンチデバッギング
Windows, is_debugger_present対策
1 dbg[process.peb_base + 0x02, 1] = "\0" # is_debbuger_present() => falseにする