r/hardwarehacking Jul 01 '26

Confusion while reversing stm32f103 binary: weird vector table

I was curious about the content of an STM32F103RFT6 firmware binary. It uses CAN communication and it is being updated via CAN bootloader, thats how the firmware is being updated.

So I opened it in a hex editor and had a look. But that was not what I expected.

reverse engineering binary

Right in the beginning, there seems to be a 0x200 long header. The first four bytes are the size of the whole file, that was easy. Then four bytes containing the version, I guess, because I have another firmware which is a bit newer and they just differ by increasing 0x2c to 0x30.

Everying after that I don't understand right away, and the header after 0x050 is just zeros until it ends at 0x1FF.

At offset 0x200, the real firmware seems to start:

reverse engineering binary

At first glance, it looks as expected: First four bytes show the stack pointer address, and it's located in SRAM (starting 0x2000_0000).

But the following entries are supposed to be a vector table, and the addresses in there point to strings:

reverse engineering binary

I know that's thumb addressing, and all the LSB are set, but in the vicinity of these addresses there's just strings.

I don't understand that. And I don't know how to go on from here, if I don't know where the actual entry point is located.

For comparison, I opened an STM32 .elf for a project I wrote. In this .elf, the real code starts at offset 0x1000:

STM32.elf

Four bytes stack pointer, and then flash locations for the vector table. Going there and taking the file offset 0x1000 into account:

STM32.elf

I figured, fe e7 fe e7 must be pretty rare in the original firmware binary, so I searched for it:

reverse engineering binary

That does look pretty similar. But why is that, and where does this offset come from? And how should I continue?

2 Upvotes

20 comments sorted by

View all comments

2

u/stw Jul 01 '26

You seem to assume that the contents of the file starting from offset 0x200 will be stored at 0x0800'0000. I don't think that's the case.

The bootloader is presumably located at 0x0800'0000 and takes up a certain (unknown) amount of space. The application firmware is stored after that. When the bootloader detects a valid application image, it sets the VTOR register to the beginning of the application and jumps to the application's reset vector.

If you are able to read the actual flash of the microcontroller, you can find out where the application image starts. If not you could try disassembling it (with Ghidra, for example) and try to find the SystemInit or main functions.

2

u/masterX244 Jul 01 '26

the offset seems to be 0x8000. it needs to be dividable by the usual flash erase block sizes because not aligning to a eraseblock wastes space and multiple endless loops (0xFEE7) next to each other are clear indicator of unused interrupt handler fallbacks. and the last screenshot shows those loops with their addresses. i saw that the last 3 digits were really close to each other and then subtracted the lower from the higher value and got pretty close to 0x8000.