import argparse import re import struct def parse_line(line): match = re.match(r'^\[([0-9A-Fa-f]{8})\]: ((?:[0-9A-Fa-f]{8} ){7}[0-9A-Fa-f]{8})$', line.strip()) if not match: return None address_str, data_str = match.groups() address = int(address_str, 16) words = [int(w, 16) for w in data_str.strip().split()] return address, words def main(): parser = argparse.ArgumentParser(description='Convert hex dump format to raw binary for Ghidra.') parser.add_argument('-i', '--input', required=True, help='Input .hex-style file') parser.add_argument('-o', '--output', required=True, help='Output binary file') parser.add_argument('--base', type=lambda x: int(x, 16), default=None, help='Optional: base address override (hex, e.g. 0x08000000)') args = parser.parse_args() memory = {} min_address = None max_address = None with open(args.input, 'r') as infile: for line in infile: parsed = parse_line(line) if parsed is None: continue address, words = parsed for i, word in enumerate(words): addr = address + i * 4 memory[addr] = word if min_address is None or addr < min_address: min_address = addr if max_address is None or addr > max_address: max_address = addr if args.base: min_address = args.base with open(args.output, 'wb') as outfile: addr = min_address while addr <= max_address: word = memory.get(addr, 0) outfile.write(struct.pack('<I', word)) # little-endian addr += 4 if __name__ == '__main__': main()