Improve binbase_find.py

Signed-off-by: Markus Birth <markus@birth-online.de>
This commit is contained in:
2025-06-23 00:16:02 +01:00
parent fd00453ad5
commit f292058c90
+20 -2
View File
@@ -10,6 +10,7 @@ import sys
from operator import itemgetter from operator import itemgetter
chars = "A-Za-z0-9/\\-:.,_$%'\"()[\]<> " chars = "A-Za-z0-9/\\-:.,_$%'\"()[\]<> "
known_strings = [b"POSIX", b"ASCII", b"Foretrex", b" V3.50", b"0:/Garmin", b"Garmin International", b"<?xml version"]
min_length = 10 min_length = 10
scores = [] scores = []
top_score = 0 top_score = 0
@@ -31,20 +32,33 @@ def get_strings(filename, size):
data = f.read(10) data = f.read(10)
except: except:
break break
for ks in known_strings:
i = data.find(ks)
if i >= 0:
print("matched known string: {}".format(ks))
table.add(offset + i)
offset += i + len(ks)
continue
match = pattern.match(data) match = pattern.match(data)
if match: if match:
print(repr(match))
f.seek(offset - 1) f.seek(offset - 1)
try: try:
char = f.read(1) char = f.read(1)
except: except:
continue continue
if not patternc.match(char): if not patternc.match(char):
table.add(offset) #table.add(offset)
offset += len(match.group(0)) offset += len(match.group(0))
offset += 1 offset += 1
table.add(0xbb0e4)
return table return table
def get_pointers(filename): def get_pointers(filename):
"""
Read file in DWORD chunks and assume everything is a pointer.
"""
table = {} table = {}
with open(filename, "rb") as f: with open(filename, "rb") as f:
while True: while True:
@@ -90,19 +104,23 @@ if __name__ == "__main__":
for base in range(args.min_addr, args.max_addr, args.page_size): for base in range(args.min_addr, args.max_addr, args.page_size):
if base % ( args.page_size * 1000 ) == 0: if base % ( args.page_size * 1000 ) == 0:
print("Trying base address 0x{:x}".format(base)) print("Trying base address 0x{:x}/0x{:x}".format(base, args.max_addr))
print("\u001b[F\u001b[K", end="") print("\u001b[F\u001b[K", end="")
score = 0 score = 0
ptrs = list(ptr_table.keys()) ptrs = list(ptr_table.keys())
for ptr in ptrs: for ptr in ptrs:
if ptr < base: if ptr < base:
# Pointer points to before base address --> invalid and remove from future queries
#print("Removing pointer 0x{:x} from table".format(ptr)) #print("Removing pointer 0x{:x} from table".format(ptr))
del ptr_table[ptr] del ptr_table[ptr]
continue continue
if ptr >= (base + size): if ptr >= (base + size):
# Pointer points to after firmware area --> invalid, but might become valid when checking higher base addrs
continue continue
# Pointer points somewhere inside firmware, calculate offset
offset = ptr - base offset = ptr - base
if offset in str_table: if offset in str_table:
# Wow, pointer points directly to one of the found strings --> we have a winner
score += ptr_table[ptr] score += ptr_table[ptr]
if score: if score:
scores.append((base, score)) scores.append((base, score))