kivantium活動日記

プログラムを使っていろいろやります

Vimでバイナリファイルを開く 〜vinarise.vimの紹介〜

バイナリ解析をするときにはバイナリエディタが必須ですが、よく使われるBZやStirlingはWindows版しかありません。僕の調べた範囲だとLinuxで動くバイナリエディタは機能が貧弱なものばかりであまりいいものがありませんでした。

しかし、我々には最高のエディタVimがあるではないか!バイナリだってVimで扱いたい!というわけでVimバイナリエディタとして使う方法のメモです。

普通の方法

.vimrcに

" vim -b : edit binary using xxd-format!
augroup BinaryXXD
  autocmd!
  autocmd BufReadPre  *.bin let &binary =1
  autocmd BufReadPost * if &binary | silent %!xxd -g 1
  autocmd BufReadPost * set ft=xxd | endif
  autocmd BufWritePre * if &binary | %!xxd -r | endif
  autocmd BufWritePost * if &binary | silent %!xxd -g 1
  autocmd BufWritePost * set nomod | endif
augroup END

と書けばbinファイルを開いた時、または-bオプションをつけて開いた時に自動的にバイナリモードで開いてくれます。vimでバイナリを表示し、値を変更したい - rderaログ


しかし、これではかの有名な目grepをすることができません。やはりテキストエディタであるVimにビットマップ表示を求めるのは酷ですね。残念。

「クックック……」



「貴様!まさか!?」



「そう、そのまさかだ!!フハハハハ…」

Vim上でも目grepしたい!

そう、かの有名な暗黒美夢王さんがバイナリエディタプラグインを作っていたのです。しかもビットマップ機能付きで。というわけでありがたく使わせていただくことにします。
github.com

インストール

NeoBundle(これまた暗黒美夢王さん作)がインストールされているなら、

NeoBundle 'Shougo/vinarise'

だけでインストール終了です。
Pythonバインディングが必要ですが、Ubuntu 14.04なら標準でついていたので問題ないでしょう。

使い方

バイナリファイルを開いた状態で:Vinariseとすれば、バイナリ編集モードに入ります。標準のキーバインディングは次の通り。

キー 機能
V Vimで開き直す
q ファイルを隠す
Q Vinarizeを終了する
l 次の列へ移動
h 次の列へ移動
gh 行頭のアドレスへ移動
0 行頭のアドレスへ移動
^ 行末のアドレスへ移動
gl 行末のアドレスへ移動
$ 行末のアドレスへ移動
j 次の行へ移動
k 前の行へ移動
<C-f> 一画面先へ移動
<C-b> 一画面前へ移動
<PageDown> 一画面先へ移動
<PageUp> 一画面前へ移動
<C-d> 半画面先へ移動
<C-u> 半画面前へ移動
<C-g> 現在位置の値を表示
r 現在位置の値を変更
R 現在のアドレスから続けて書き換える
gG 入力したアドレス位置へ移動
go 入力したオフセット値の分だけ移動
gg 最初のアドレスへ移動
G 最後のアドレスへ移動
/ バイナリ値を検索
? バイナリ値を逆向きに検索
g/ 文字列を検索
g? 文字列を逆向きに検索
e/ 正規表現で検索
n 次のパターンを検索
N 直前のパターンを検索
E エンコードを変更
<C-l> 再描画する
g<C-l> Vinariseの再読み込み
B ビットマップを描画
w 次の値までスキップ
b 前の値までスキップ

f:id:kivantium:20150430234559p:plain:w400
こんな感じのビットマップ表示ができるので、思う存分目grepの練習ができます。
ありがとう!暗黒美夢王!!

設定

さっきの設定のように-bオプションをつけたら自動的にvinariseで開くようにしました。

augroup BinaryXXD
	autocmd!
	autocmd BufReadPre  *.bin let &binary =1
	autocmd BufReadPost * if &binary | Vinarise
	autocmd BufWritePre * if &binary | Vinarise | endif
	autocmd BufWritePost * if &binary | Vinarise 
augroup END

vim scriptが全然分からないのでこれで正しいのか分からないのですが、今のところそれっぽい動作をしています。