Skip to content

Instantly share code, notes, and snippets.

Last active Feb 15, 2021
What would you like to do?
avr-gdb python script to get flag from a debug build of
import gdb
import sys
# Uses avr-gdb's built-in `target sim` simulator
# Requires avr-gdb to be built with Python support
# Run `source` inside GDB to run
# firmware.elf must be built with debug symbols (a .hex file could be used if you memory addresses were manually specified)
def onI2CReceive():
gdb.execute("set var 'twi.cpp'::rxHead = 1")
gdb.execute("set var 'twi.cpp'::rxTail = -1")
gdb.execute("set var 'twi.cpp'::rxByteNum = 1")
gdb.execute("set var 'twi.cpp'::rxBuf = {*flag, 0 }")
gdb.execute('call onI2CReceive(0)')
class TinyTwiSend(gdb.Breakpoint):
def __init__(self, spec):
gdb.Breakpoint.__init__(self, spec)
self.silent = True
self._dataReady = False
def stop(self):
# Only return every other value (skip target)
if self._dataReady:
gdb.execute('printf "%c", data')
self._dataReady = not self._dataReady
return False
class Loop(gdb.Breakpoint):
def __init__(self, spec):
gdb.Breakpoint.__init__(self, spec)
self.silent = True
def stop(self):
print("[+] sending flag address to onI2CReceive")
print("[+] Advancing target 0x8000")
for _ in range(0x8000):
gdb.execute('call onI2CRequest()')
print("[+] Getting flag via onI2CRequest()")
bp_send = TinyTwiSend("TinyTwi::send(uint8_t)")
for _ in range(int(gdb.parse_and_eval("sizeof(flag)"))):
gdb.execute('call onI2CRequest()')
bp_loop.enabled = False
return True
gdb.execute('target sim')
gdb.execute('load firmware.elf')
gdb.execute('symbol-file firmware.elf')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment