## 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にする
}}}