Skip to content

Instantly share code, notes, and snippets.

@sprout42
Forked from joshwatson/micocorruption_binary.py
Last active April 19, 2022 20:23
Show Gist options
  • Save sprout42/e4354f7646cb22724f68543e0d442df0 to your computer and use it in GitHub Desktop.
Save sprout42/e4354f7646cb22724f68543e0d442df0 to your computer and use it in GitHub Desktop.
Generate a Microcorruption Memory Dump (py3 compatible)
import os
import sys
import struct
import tempfile
import subprocess
from argparse import ArgumentParser
def decode_binary(input_file):
next_addr = 0
output = bytes()
for line in input_file:
line = line.strip()
if not line:
continue
addr,data = line.split(':')[:2]
addr = int(addr, 16)
data = ''.join(data.split(' ')[3:11])
if data == '*':
data = '00'*16
print('{:04x}: {}'.format(addr, data))
data = bytes.fromhex(data)
if next_addr == addr:
output += data
else:
difference = addr - next_addr
blank_data = b'\x00' * difference
output += blank_data + data
next_addr = addr + 16
return output
def main(input_file, output_file, fmt):
with open(input_file, 'r') as f:
data = decode_binary(f)
if fmt == 'bin':
with open(output_file, 'wb') as f:
f.write(data)
elif fmt == 'elf':
# Cheat and use objcopy
tmpfile = tempfile.NamedTemporaryFile(delete=False)
tmpfile.write(data)
args = [
'objcopy', '-I', 'binary', '-O', 'elf32-little',
'--image-base', '0x0000', '--only-section', '.data',
'--rename-section', '.data=.text',
'--set-section-flags', '.text=code',
'--strip-all',
tmpfile.name, output_file,
]
subprocess.run(args)
# the entry point address is the last 2 bytes of the binary
entry = struct.unpack_from('<H', data, 0xFFFE)[0]
# Now open up the output file and fix the ELF header
with open(output_file, 'r+b') as f:
# header.e_machine is 2 bytes at offset 18
f.seek(18)
f.write(struct.pack('<H', 105))
# header.e_entry is 4 bytes at offset 24
f.seek(24)
f.write(struct.pack('<H', entry))
# delete the temp file
os.unlink(tmpfile.name)
else:
raise Exception('Unsupported output format: %s' % fmt)
if __name__ == '__main__':
parser = ArgumentParser()
parser.add_argument('-f', '--format', default=None, choices=['bin', 'elf'],
help='output file format')
parser.add_argument('input_file')
parser.add_argument('output_file')
args = parser.parse_args()
if args.format is None:
if args.output_file.endswith('.elf'):
fmt = 'elf'
else:
fmt = 'bin'
main(args.input_file, args.output_file, fmt)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment