[Python] Modifying binary file

python 處理檔案,真的超級方便。下面這人個script 示範如何修改掉幾個byte. 附的這2個 sample 的重點在要用 r+b 開檔,用 wb 會出問題。

sample 1:
http://stackoverflow.com/questions/14643538/modifying-binary-file-with-python

You only need to use seek and write. Use seek to jump to the position and write to overrwite the existing data.

with file('patch1.bin', 'rb') as fh:
    patch1 = fh.read()

with file('patch2.bin', 'rb') as fh:
    patch2 = fh.read()

with file('file.bin', 'r+b') as fh:
    # apply patch1
    fh.seek(0xc0010)
    fh.write(patch1)
    fh.seek(0x7c0010)
    fh.write(patch1)
    # apply patch2
    fh.seek(0x040000)
    fh.write(patch2)

 

sample 2:
http://stackoverflow.com/questions/8478524/python-write-to-file-based-on-offset

import sys
import os

def SplitFile(fname, start, end, width):
    t_fileSize = os.path.getsize(fname)
    buffData = bytearray(t_fileSize)
    for line, offset in get_bytes(fname, int(start), int(end), int(width)): 
    combine_bytes(buffData, offset, line, width)        
        nums = ["%02x" % ord(c) for c in line]
        print " ".join(nums)

    f = open("Green_copy.jpg", "wb")
    f.write(buffData)
    f.close()


def combine_bytes(in_buff, in_offset, in_data, in_width):
    #something like memcpy would be nice
    #in_buff[in_offset:in_offset + in_width] = in_data

    #this works but it's the mother of inefficiency 
    i = in_offset
    for c in in_data:
        in_buff.insert(i, c)
        i  = i + 1


def get_bytes(fname, start, end, width):
    t_currOffset = start
    t_width = width
    f = open(fname, "r+b")

    if end != 0:
    while t_currOffset < end:
        f.seek(t_currOffset)
        if (t_currOffset + t_width) > end:
            t_width = end - t_currOffset
        t_data = f.read(t_width)
        yield t_data,t_currOffset
        t_currOffset += t_width
    else:   
    f.seek(t_currOffset)
    t_data = f.read(t_width)
    while t_data:
        yield t_data, t_currOffset
        t_currOffset += t_width
        f.seek(t_currOffset)
        t_data = f.read(t_width)

    f.close()


if __name__ == '__main__':
    try:
    SplitFile(*sys.argv[1:5])
    except:
    print "Unexpected error:", sys.exc_info()[0]

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *