pythonでバイナリダンプ

[2013/09/07 追記]
コメント欄で指摘されたバグを直しました。


暇。
バイナリファイルのダンプ。
wikipedia:車輪の再発明
黙々と車輪の再発明

#! /usr/bin/env python 
# coding: utf-8
import sys, string

def printLine(lineno, bin):
    # 2013/09/07 修正 ブログコメント欄参照
    #print "%08x " % (lineno*32),
    print "%08x " % (lineno*16),

    for i,n in enumerate(bin):
        if i % 2 == 1:
            sys.stdout.write("%02x " % ord(n))
        else:
            sys.stdout.write("%02x" % ord(n))

    sys.stdout.write(' ')
    # 最終行の場合は空白を挿入してプリティープリント
    x = bin.__len__()
    if x != 16:
        ite = ( 16 - x ) * 2
        ite += 8 - x/2
        print ' ' * ite,

    # 印字可能な文字列は印字する
    s = ""
    for n in bin:
        if n in string.printable[:-5]: # without \t,\n,\x,0b, \x, 0c, \r
            sys.stdout.write(n)
        else:
            sys.stdout.write('.')
    print


def bin_dump(fname, opt=None):
    try:
        f = open(fname, "rb")
    except:
        print "** cannot open",fname,":"
        sys.exit()

    try:
        i = 0
        while True:
            c = f.read( 16 )
            if not c: break
            printLine(i, c)
            i += 1
    except KeyboardInterrupt:
        print
        pass

def main():
    import sys
    if sys.argv.__len__() < 2:
        print "usage: bin.py file"
    else:
        map(bin_dump, sys.argv[1:])

if __name__ == '__main__':
    main()

実行結果

$ python dump.py ./a.out
00000000 7f45 4c46 0201 0100 0000 0000 0000 0000  .ELF............
00000010 0200 3e00 0100 0000 8004 4000 0000 0000  ..>.......@.....
00000020 4000 0000 0000 0000 5011 0000 0000 0000  @.......P.......
00000030 0000 0000 4000 3800 0900 4000 1e00 1b00  ....@.8...@.....
00000040 0600 0000 0500 0000 4000 0000 0000 0000  ........@.......
00000050 4000 4000 0000 0000 4000 4000 0000 0000  @.@.....@.@.....
00000060 f801 0000 0000 0000 f801 0000 0000 0000  ................
00000070 0800 0000 0000 0000 0300 0000 0400 0000  ................
00000080 3802 0000 0000 0000 3802 4000 0000 0000  8.......8.@.....
00000090 3802 4000 0000 0000 1c00 0000 0000 0000  8.@.............
000000a0 1c00 0000 0000 0000 0100 0000 0000 0000  ................
000000b0 0100 0000 0500 0000 0000 0000 0000 0000  ................
000000c0 0000 4000 0000 0000 0000 4000 0000 0000  ..@.......@.....
000000d0 7c08 0000 0000 0000 7c08 0000 0000 0000  |.......|.......
000000e0 0000 2000 0000 0000 0100 0000 0600 0000  .. .............
000000f0 280e 0000 0000 0000 280e 6000 0000 0000  (.......(.`.....
00000100 280e 6000 0000 0000 0002 0000 0000 0000  (.`.............
00000110 d0bd 1300 0000 0000 0000 2000 0000 0000  .......... .....
00000120 0200 0000 0600 0000 500e 0000 0000 0000  ........P.......
(略)

リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing)

リバースエンジニアリング ―Pythonによるバイナリ解析技法 (Art Of Reversing)