#!/usr/bin/env python3 ## ## This file is part of the sigrok-util project. ## ## Copyright (C) 2012 Bert Vermeulen ## ## This program is free software; you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation; either version 3 of the License, or ## (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, see . ## import sys import os from getopt import getopt import struct def parse(filename): f = open(filename, 'rb') if f.read(2) != b'MZ': raise Exception("MZ signature not found.") sections = [] # long e_lfanew f.seek(0x3c) pe_ptr = struct.unpack(" symbols[-1][1]: symbols[-1][2] = symaddr - symbols[-1][1] symbols.append([name, symaddr, size]) addr += 18 f.close() return sections, symbols def list_all(filename): sections, symbols = parse(filename) if sections: print("Sections:\n Name Size\t Position") cnt = 0 for name, size, address in sections: print("%-3d %-8s %5d\t 0x%.8x" % (cnt, name, size, address)) cnt += 1 if symbols: print("\nSymbol table:\n Address Size Symbol") for symbol, address, size in symbols: if size is not None: sizestr = "%5d" % size else: sizestr = " " print("0x%.8x %s %-8s" % (address, sizestr, symbol)) print() def extract_symbol(filename, symbol): sections, symbols = parse(filename) if not symbols: return None data = None for symbolname, address, size in symbols: if symbolname == symbol: if size is None: raise Exception("symbol %s found, but has unknown size") f = open(filename, 'rb') f.seek(address) data = f.read(size) f.close() if len(data) != size: raise Exception("short file") break if data is None: raise Exception("symbol %s not found" % symbol) return data def usage(): print("usage: parsepe.py [-s ] <-l|-x> ") print(" -l list all sections and symbols in file") print(" -x extract symbol from file (specify symbol name with -s)") sys.exit() # # main # if __name__ == '__main__': filename = symbol = mode = None opts, args = getopt(sys.argv[1:], 's:lx') for opt, arg in opts: if opt == '-s': symbol = arg elif opt == '-l': mode = 'list' elif opt == '-x': mode = 'extract' if len(args) != 1: usage() if mode is None and symbol is None: usage() try: filename = args[0] if mode == 'list': list_all(filename) elif mode == 'extract': if symbol is None: raise Exception("specify a symbol to extract") data = extract_symbol(filename, symbol) outfile = os.path.splitext(filename)[0] + symbol open(outfile, 'wb').write(data) print("saved %d bytes to %s" % (len(data), outfile)) else: raise Exception("specify -l or -x") except Exception as e: print("Error: %s" % str(e))