Reverse engineering mouse firmware

Hey, I have been reverse engeneering the protocol from my SteelSeries Rival 310. You can find my work here. I would also like to reverse engineer the firmware of the mouse because there are still things I don’t understand. I have the firmware files that I have extracted from the official driver (they’re in the repo too). I’ve ran binwalk on them but as I expected it didn’t match anything because the files are probably binaries for the microcontroller. I am not really familiar with the ARM Thumb binary structure so I can’t identify anything inside the file. I tried to open it in IDA Pro and radare2 but I didn’t get anything, probably because there might be some kind of padding or a signature in the .bin file. So, I am here to ask if anyone can have a look at the files and point me where to start. If anyone want’s to help, it might be helpful to give some more details. The mouse has a STM32F103, which has a Cortex-M3 core, so the architecture should be ARMv7-M (this architecture only supports Thumb mode). In the repo there are 2 files, the main firmware and the secondary firmware. The secondary firmware works as a fallback, the mouse only blinks orange (FF 52 00) and waits for a firmware update.

1 Like

I managed to open the 1.33 firmware file just fine in IDA Pro after reading the data-sheet and knowing where certain addresses should be mapped to.
Here’s the datasheet for the STM32F103
Check out the memory map of Section 4 to give you some insight on the address space so you’ll know where to map the segments in IDA pro. From the looks of things flash memory is mapped to 0x8000000 so I had IDA pro map the firmware.bin file there and to map RAM to 0x20000000 and guessed the size to be 64kb(0xFFFF bytes) and from there you’ll have to manually dive around and press C to get ida pro to start analyzing and recursively finding more and more functions and data xrefs. ARM(and Thumb) assembly trends to have these pools of constant values and data right after the functions and just from experience you can intuitively find them just from looking at the entropy of the byte data. Given the spec sheet and knowing that RAM is going to be in the 0x20000000 range I naturally expected to see a lot of 0x20000000-like integers in these pools and being a Thumb/ARM machine I knew that instructions would be aligned to 2-byte or 4-byte addresses depending on the execution mode that it was in. And from there I can go in and press “C” bit by bit until I reach full coverage. You could also of course just know the bytes for stuff like push and pop to find the beginning and end of subroutines so you know where to get IDA to start declaring bytes as code but this is just a quick poke into your project.

Check it out:

Based on the data sheet writes to the 0x40000000 region are writes to peripherals:

so that 0x40010800 constant there means that that subroutine is interfacing with some peripheral.


Which seems to be Port A. It’s up to the designer and manufacturer to wire whatever peripheral they want to Port A though so you might not be able to make much sense to some of those exact reads and writes are doing but you’ll know for sure that it is reaching out to a peripheral.

Hope this little offhand lunch break writeup gets you in the right general direction.

10 Likes

Thanks! That was definitely helpful! Do you know some good books (or other resources) on ARM, more particularly, Thumb? I have messed a bit with x86 binaries and those are easy to understand because you have an entry point. I am interested in reverse engineering more physical devices like this but I don’t have the knowledge yet to dive into more complex binaries. Again, thank you so much! That was really helpful!

1 Like

Thumb code is just one of the facets of the ARM arch so it might be hard to find a book or discipline around just Thumb code in particular. Thumb is just a subset of sorts for an ARM processor so once you learn the ARM side of things, you’ll find that Thumb code is just one particular feature of most ARM processors. Outside of just being an instruction set, your ARM/Thumb code does not exist in a vacuum and will instead find itself in the atmosphere of an SoC or much larger architecture where your firmware exists on a flash chip, which is mapped to a certain portion of memory such that when the CPU reads from a range of addresses it is actually interfacing with a peripheral.
When you’re at the embedded level you won’t have the benefit of having ELF files or a Linux operating system running on your chip that trends to lend you things like entry points but instead will have a lot of its abstractions made via read and writes to memory and will have to read up data sheets such as above for the specific SoC(such as the STM32F103, which arranges its memory space in a particular way so that certain memory operations interface with an underlying harder) rather than just the processor or ARM/Thumb instruction set on its own(which all pretty much only know how to do mathematical arithmetic and move memory around).

Here’s some links related to the ARM atmosphere.
GodBolt - A web tool where you can type in C or C++ code, and see the compiled assembly on the right. That way you can experiment and see how certain algorithms look like when emitted to assembly and gain an intuition as to what a chunk of assembly is doing. (ex. how strlen looks like under the hood or finding a good attack surface for a rop chain)
GBATEK - This page documents everything that makes up the Gameboy Advance, The Nintendo DS, and the Nintendo DSi. Just a very verbose unofficial “datasheet” of a console that you are probably already familiar with. Jump around the headers and you’ll see how all these peripherals are all linked together and how they are interfaced and mapped in memory. Especially the ARM7TDMI section. You’ll find that the ARM7TDMI was very popular around this time. Also check out the Memory Map sections for some of them.
Tonc: A Whirlwind Tour of ARM assembly - Another expansive tutorial on writing assembly for the Gameboy Advanced. Compliments the GBATEK document into more practical examples.
azeria-labs, ARM Assembly - Goes over a lot of the atmosphere of developing for ARM and how these environments tend to look like
OakSim - A little web tool I made where you can type in arm or thumb assembly and see the resulting binary data on the right, and also step through your instructions.
ARMSim - An “ide” for arm assembly. This is what a lot of schools use. I personally hate it and it was my motivation for writing OakSim.

I think something that would be cool was if 0x00sec had an ARM based “crackme”.

4 Likes

There’s an ARM legend staying quiet in between us. I summon you, @Leeky.

1 Like

@_py I’m not that good with ARM actually.
@Wunkolo seems to know a lot more than me.
(I can also really recommend GPATEK and Tonc for learning ARM as the GBA kinda forces you to use normal ARM and THUMBS as the different memory regions have different IO sizes, I’ve just experimented with it a little though and mainly in C. And of course azeria-labs is an amazing place for learning ARM!)
I personally never used ARMSim before, I just assembled ARM Code for a qemu Linux box and tested it there (and on my NDS of course :smiley: ) but @Wunkolo’s OakSim looks pretty good (and actually easy to interact with compared to the keystone/unicorn web wrapper I use).

@Wunkolo Maybe we could work together on some crackme’s or something similar? Only if you want to and have time for it obviously.

1 Like

Sounds like an idea. I haven’t been able to join the irc at all lately though for some reason but I’m up for making some little challenges based in ARM.

2 Likes

Thanks! I actually knew about Azeria Labs but totally forgot. I was also watching this videos on the Cortex-M architecture https://www.youtube.com/channel/UCB_pO4oDYxxbsRPZ-5RluAA.

This topic was automatically closed 3 days after the last reply. New replies are no longer allowed.