Newer
Older
Hardware / FaultInjection / examples / CuriousBolt / Level-1 / tidy_log.py
root on 3 May 1 KB Chall 4 extras added
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()