From: Bert Vermeulen Date: Mon, 18 Jun 2012 01:14:11 +0000 (+0200) Subject: add parsepe tool X-Git-Url: https://sigrok.org/gitweb/?p=sigrok-util.git;a=commitdiff_plain;h=04c170001e80162b658b538d65a96a94c5baeac7 add parsepe tool --- diff --git a/firmware/README.parsepe b/firmware/README.parsepe new file mode 100644 index 0000000..8a69b6f --- /dev/null +++ b/firmware/README.parsepe @@ -0,0 +1,11 @@ +The parsepe.py tool can list all sections and symbols from a PE (portable +executable) binary file, and extract the contents of a symbol. + +usage: +parsepe.py -l list all sections and symbols in file +parsepe.py -s -x extract symbol from file + +TODO: +- currently only handles COFF symbol tables +- can only extract external (global) symbols + diff --git a/firmware/parsepe.py b/firmware/parsepe.py new file mode 100755 index 0000000..74d639f --- /dev/null +++ b/firmware/parsepe.py @@ -0,0 +1,183 @@ +#!/usr/bin/python3 +## +## This file is part of the sigrok 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)) + +