diff --git a/binbase_find.py b/binbase_find.py new file mode 100644 index 0000000..d08854f --- /dev/null +++ b/binbase_find.py @@ -0,0 +1,116 @@ +#!/usr/bin/python + +# https://github.com/mncoppola/ws30/blob/master/basefind.py + +import gc +import os +import re +import signal +import struct +import sys +from operator import itemgetter + +chars = r"A-Za-z0-9/\-:.,_$%'\"()[\]<> " +min_length = 10 +scores = [] +top_score = 0 + +regexp = "[%s]{%d,}" % (chars, min_length) +pattern = re.compile(regexp) +regexpc = "[%s]{1,}" % chars +patternc = re.compile(regexpc) + +def high_scores(signal, frame): + print "\nTop 20 base address candidates:" + for score in sorted(scores, key=itemgetter(1), reverse=True)[:20]: + print "0x%x\t%d" % score + sys.exit(0) + +def get_pointers(f): + table = {} + f.seek(0) + while True: + try: + value = struct.unpack("= size: + break + f.seek(offset) + try: + data = f.read(10) + except: + break + match = pattern.match(data) + if match: + f.seek(offset - 1) + try: + char = f.read(1) + except: + continue + if not patternc.match(char): + tbladd(offset) + offset += len(match.group(0)) + offset += 1 + return table + +if __name__ == "__main__": + import argparse + parser = argparse.ArgumentParser() + def auto_int(x): + return int(x, 0) + parser.add_argument("--min_addr", type=auto_int, help="start searching at this address", default=0) + parser.add_argument("--max_addr", type=auto_int, help="stop searching at this address", default=0xf0000000) + parser.add_argument("--page_size", type=auto_int, help="search every this many byte", default=0x1000) + parser.add_argument("infile", help="file to scan") + args = parser.parse_args() + + size = os.path.getsize(args.infile) + f = open(args.infile, "rb") + scores = [] + + print "Scanning binary for strings..." + str_table = get_strings(f, size) + print "Total strings found: %d" % len(str_table) + + print "Scanning binary for pointers..." + ptr_table = get_pointers(f) + print "Total pointers found: %d" % len(ptr_table) + + f.close() + gc.disable() + signal.signal(signal.SIGINT, high_scores) + + for base in xrange(args.min_addr, args.max_addr, args.page_size): + if base % args.page_size == 0: + print u"Trying base address 0x%x\u001b[F\u001b[K" % base + score = 0 + for ptr in ptr_table.keys(): + if ptr < base: + #print "Removing pointer 0x%x from table" % ptr + del ptr_table[ptr] + continue + if ptr >= (base + size): + continue + offset = ptr - base + if offset in str_table: + score += ptr_table[ptr] + if score: + scores.append((base, score)) + if score > top_score: + top_score = score + print "New highest score, 0x%x: %d" % (base, score) + print "" + + high_scores(0, 0)