## page was renamed from CTF/inside/Toolkit/METASM = 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など http://metasm.cr0.org/ <<TableOfContents>> == インストール方法 == === 事前に必要なもの === 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は[[https://rubygems.org/gems/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名やファイルフォーマットは基本的に自動認識してくれるので指定する必要はない。 === キーボードショートカット === ||<ROWCLASS="header"> キー || 効果 || || c || 逆アセンブル || || C || 逆アセンブル(バックトラックなし、関数呼び出し無視) || || Ctrl+C || 逆アセンブル(バックトラックなし) || || g || 特定アドレスへ移動 || || Return || callやjmpを辿る || || Esc || 元の場所に戻る || || Ctrl+Enter || 元の場所に戻るのをやりなおし || || f || 関数一覧を表示 || || x || 呼び出し元を列挙 || || K || 関数内のローカル変数に名前を付ける || || b || backtrace || || n || ラベルの名前を変更する || || Tab || 逆コンパイル || || / || 検索 || || Ctrl+f || 正規表現検索し、列挙する || == ライブラリ == === シェルコード === RubyのExploit上で直接Shellcodeを書くことが可能になる。 {{{#!highlight ruby require 'metasm' print Metasm::Shellcode.assemble(Metasm::Ia32.new, <<SOURCE).encode_string mov eax, 1 mov ebx, 42 int 80h // exit SOURCE }}} === デバッガ === ==== プロセスを実行する ==== 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にする }}}