A bootloader is typically used to update application code on a microcontroller. It receives the new program from a host, writes it to flash, verifies the program is valid, and resets the microcontroller. Perhaps the most ubiquitous example is the Arduino bootloader which allows you to load code without an AVR programmer.
The bootloader resides in a special part of memory, which is protected. On the AVR, it isn’t possible to write to the bootloader memory from the application code. This is to prevent you from accidentally breaking the bootloader and bricking the device.
However, it can be useful to write to the bootloader memory. The best example would be when you need to update the bootloader itself. To accomplish this, [Julz] found a workaround that defeats the AVR bootloader protection.
The challenge was to find a way to execute the Store Program Memory (spm) instruction, which can only be executed by the bootloader. [Julz] managed to make use of the spm instruction in the existing bootloader by counting cycles and modifying registers at the right time.
Using this technique, which [Julz] calls BootJacker, the Fignition 8 bit computer could have its bootloader updated. However, this technique would likely allow you to modify most bootloaders on AVR devices.
Bravo. A nice and simple exploit!
Amazing work. Correct me if I’m mistaken, but as this hack relies on knowing the precise time when the spm instruction is called is it really feasible with USB enabled bootloaders as it may get tricky to know when the “upload firmware” button is pressed?
Sounds like Atmel’s “protection” doesn’t depend on when that instruction was executed relative to when the boot loader started executing (e.g. first 1024 clock cycles), but *where* it is executed (within the bootstrap space range). That doesn’t sound like a good protection.
So like someone hinted below, somewhere your user code has to be running, set up a timer interrupt to go off right at the right time * before calling the part of the bootloader that has the sequence.
*: just like the old single step debugger trick they used in the old days, you set up timer interrupt to go off after an instruction of interest get executed.
No, it works differently, as far as I can see.
The user code jumps into the bootloader to re-use an existing spm instruction there.
But you do not want the instructions following that smp instruction, so you set up an interrupt to bring you back to user code.
Rinse, repeat. Smart!
Thanks!
That is indeed impressive… So simple and so elegant
Yes, this is definitely a cool hack. The smartest workaround I’ve seen in a long time.
This is sheer genious. It is so clear, once you see it.… Bravo!
This is one excellent hack!
I thought I was pretty good at programming AVR.
I bow to the master :-)
But: “If Interrupt Vectors are placed in the Application section, interrupts are disabled while executing from the Boot Loader section.” is part of most of the BLB protection settings.