
I recently got a CAN bus filter from AliExpress MB_CAN_FIlter. The existing firmware is used to bypass the Odometer of the premium cars like Mercedes, BMW by modifying the CAN signal that are passed through it. But we can utilize this for better endeavors like resetting the BMS signals of EVs to expand the lifetime of the battery and replacing batteries of higher capacity.
So it is essential to understand how this Circuit works, and learn the Basics of dumping the existing firmware and flashing new firmware to the Chip it is using.
The board here uses a STM32F105C8T6 Microcontroller and the CAN Transceivers ICs are some TJA1057. There is a similar board that uses the MCP2551.
There are multiple reasons why this board is wonderful as well as has many issues related to the PCB in which I will be going through maybe will opensource the designs in the future.
Dumping STM32F105 Firmware on Ubuntu using ST-LINK
This guide details how to install the required tools and dump the firmware from an STM32F105 microcontroller using an ST-LINK programmer on an Ubuntu system. We will cover two common tools: STM32CubeProgrammer (the official ST tool) and OpenOCD (an open-source alternative).
1. Prerequisites
-
Hardware:
- STM32F105-based board (See Section 3 for a specific example).
- ST-LINK V2 or V3 programmer/debugger.
- USB cables for the ST-LINK and potentially the target board (if it needs separate power).
- Jumper wires for SWD connection.
-
Software:
- Ubuntu Linux (instructions tested on recent LTS versions like 20.04/22.04).
- Internet connection for downloads.
2. Tool Installation
a) STM32CubeProgrammer
STM32CubeProgrammer is STMicroelectronics' official tool for programming STM32 devices. It replaces older tools like ST-LINK Utility and STM Flasher.
- Download: Go to the STMicroelectronics STM32CubeProgrammer page. Download the Linux version (usually a .zip file). You might need an ST account.
-
Install Java: CubeProgrammer requires Java. Check if it's installed and install it if necessary:
java -version # If not installed or version is too old: sudo apt update sudo apt install default-jre -y
-
Extract: Unzip the downloaded file:
unzip en.stm32cubeprg-lin_*.zip -d stm32cubeprogrammer cd stm32cubeprogrammer
-
Run Installer: Execute the Linux installer script. You might need to make it executable first.
Follow the on-screen installation steps. The default installation location is oftenchmod +x SetupSTM32CubeProgrammer*.linux sudo ./SetupSTM32CubeProgrammer*.linux # Or run without sudo for user-local installation if preferred # ./SetupSTM32CubeProgrammer*.linux
/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/
. -
Add to PATH (Optional): To run the command-line interface (CLI) easily, add its directory to your PATH. Find the
bin
directory within your installation path (e.g.,/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin
) and add it to your~/.bashrc
or~/.zshrc
:
Verify by running:echo 'export PATH="$PATH:/usr/local/STMicroelectronics/STM32Cube/STM32CubeProgrammer/bin"' >> ~/.bashrc source ~/.bashrc
STM32_Programmer_CLI --version
b) OpenOCD
Open On-Chip Debugger (OpenOCD) is a versatile open-source tool.
-
Install: Use the package manager:
sudo apt update sudo apt install openocd -y
-
Verify: Check the installation:
openocd --version
c) ST-LINK Udev Rules
To allow access to the ST-LINK device without needing sudo
for every command:
-
Create Rules File: Create a new udev rules file:
sudo nano /etc/udev/rules.d/99-stlink.rules
-
Add Rules: Paste the following content into the file. These rules cover various versions of ST-LINK.
# ST-Link v1 ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3744", MODE="0666" # ST-Link v2 ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3748", MODE="0666" # ST-Link v2-1 ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374b", MODE="0666" # ST-Link v3 ATTRS{idVendor}=="0483", ATTRS{idProduct}=="374f", MODE="0666" ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3752", MODE="0666" ATTRS{idVendor}=="0483", ATTRS{idProduct}=="3753", MODE="0666"
- Save and Close: Press Ctrl+X, then Y, then Enter.
-
Reload Rules: Apply the new rules:
sudo udevadm control --reload-rules sudo udevadm trigger
- Reconnect: Unplug and replug your ST-LINK programmer.
3. Hardware Overview (User's Board Example)
This section describes the specific hardware components mentioned for the target board being used in this example.
-
Microcontroller:
STM32F105C8T6
- Rationale: This MCU from the STM32F1 series (Connectivity Line) is chosen primarily for its dual CAN interfaces (bxCAN), which is essential for applications requiring communication on two separate CAN buses (e.g., bridging, gateway). Additionally, many of its GPIO pins are 5V tolerant, which simplifies interfacing with 5V peripherals like some CAN transceivers, although direct connection still requires careful consideration of signal levels.
-
CAN Transceiver:
TJA1057
- Rationale: This is a high-speed CAN transceiver. Compared to other common options in the TJA10xx family (like the TJA1050), the TJA1057 often provides improved ElectroMagnetic Compatibility (EMC) and ElectroStatic Discharge (ESD) performance. It might also offer features like specific low-power modes or better behavior under bus fault conditions, making it a robust choice for CAN communication.
-
Voltage Regulators:
AMS1117-3.3
(3.3V LDO) andAMS1117-5.0
(5V LDO)- Function: These are Linear Low-Dropout regulators used to provide stable 3.3V (for the MCU and potentially other logic) and 5V (likely for the CAN transceiver VCC or other peripherals) from a higher input voltage.
Potential Board Design Considerations/Issues:
- LDO Inefficiency: Using AMS1117 LDOs, especially for significant voltage drops (e.g., 12V input down to 5V or 3.3V) or higher current demands, leads to power loss as heat. This can reduce overall efficiency and potentially require heatsinking. Switch-mode buck converters are generally more efficient but add complexity and potential noise. LDOs like the AMS1117 also require specific types and values of input/output capacitors for stability, which must be correctly implemented.
- Non-Automotive Grade MCU: The
STM32F105C8T6
is typically a commercial or industrial grade component. If the application is intended for automotive environments, using a non-automotive qualified MCU might pose risks regarding temperature range limitations, long-term reliability, and lack of specific automotive certifications (AEC-Q100). - Lack of Feedback LEDs: The absence of status LEDs (e.g., Power OK, CAN TX/RX activity, Heartbeat) makes visual debugging and diagnostics difficult. It's hard to tell if the board is powered correctly or if communication is active without external measurement tools.
- Noise Reduction and EMI Protection: For reliable CAN communication, especially at high speeds or in noisy environments, careful PCB layout, proper CAN bus termination (e.g., 120-ohm resistors), common-mode chokes, and potentially transient voltage suppression (TVS) diodes are crucial. Lacking these can lead to communication errors or susceptibility to electromagnetic interference.
4. Connecting Hardware (ST-LINK SWD)
Connect the ST-LINK programmer to your STM32F105 board using the SWD interface:
- ST-LINK SWDIO <--> Target SWDIO (often PA13)
- ST-LINK SWCLK <--> Target SWCLK (often PA14)
- ST-LINK GND <--> Target GND
- ST-LINK VCC/VDD <--> Target VDD (usually 3.3V, ensure voltage matches the MCU's VDD)
- (Optional but Recommended) ST-LINK NRST <--> Target NRST (Reset pin)
Ensure the target board is powered on (using its own power supply, likely regulated by the onboard AMS1117s).
5. Dumping Firmware
The STM32F105 typically has Flash memory starting at address 0x08000000
. The size varies; the C8
variant usually has 64KB (0x10000
bytes), but the F105 line goes up to 256KB (0x40000
bytes). Verify the exact flash size for your STM32F105C8T6 (it's 64KB) and adjust the size parameter accordingly.
a) Using STM32CubeProgrammer CLI
-
Connect and Verify:
This command attempts to connect via SWD at 4MHz and read a device ID register. It should output some information about the connected device if successful.# Read device ID register STM32_Programmer_CLI -c port=SWD freq=4000 mode=NORMAL -r32 0xE0042000 1
-
Read Flash to Binary File (for STM32F105C8T6 - 64KB):
This reads 64KB (0x10000 bytes) starting from address 0x08000000 and saves it to# Use 0x10000 for 64KB Flash size STM32_Programmer_CLI -c port=SWD freq=4000 mode=NORMAL -r 0x08000000 0x10000 firmware_dump.bin
firmware_dump.bin
. -
Read Flash to Hex File (for STM32F105C8T6 - 64KB):
This saves the firmware in Intel HEX format instead of raw binary.STM32_Programmer_CLI -c port=SWD freq=4000 mode=NORMAL -r 0x08000000 0x10000 firmware_dump.hex
b) Using OpenOCD
-
Start OpenOCD: Open a terminal and run:
# Use stlink-v2.cfg for ST-LINK V2, stlink.cfg often works for V2/V3 # stm32f1x.cfg is the target configuration for the STM32F1 series openocd -f interface/stlink.cfg -f target/stm32f1x.cfg
OpenOCD connection output example -
Connect via Telnet: Open another terminal window and connect to the OpenOCD server (which listens on port 4444 by default):
telnet localhost 4444
Telnet connection output -
Halt CPU (if not already halted):
> halt
-
Dump Firmware (for STM32F105C8T6 - 64KB): Use the
dump_image
command:
This command reads 64KB from flash address# dump_image <filename> <address> <size> # Use 0x10000 for 64KB flash size > dump_image firmware_dump_openocd.bin 0x08000000 0x10000
0x08000000
and saves it tofirmware_dump_openocd.bin
in the directory where you launched OpenOCD. -
Exit Telnet: Type
exit
and press Enter. - Shutdown OpenOCD: Go back to the first terminal (where OpenOCD is running) and press Ctrl+C to stop it.
6. Troubleshooting
-
Permission Denied / Cannot Open Device: Ensure udev rules are correctly set up and applied, or run the command using
sudo
(not recommended for regular use). -
Cannot Connect / Target Not Found:
- Double-check SWD wiring (SWDIO, SWCLK, GND, VDD).
- Ensure the target board is powered correctly via its regulators.
- Try lowering the SWD frequency (
freq=1000
in CubeProgrammer,adapter speed 1000
in OpenOCD telnet session). - Try connecting under reset: Use
mode=UR
(Under Reset) in CubeProgrammer, or addconnect_assert_srst
to the OpenOCD command line before-f target/...
. Ensure the NRST line is connected. - Check if the debug pins (SWDIO/SWCLK) have been disabled by the firmware. If so, connecting under reset might be the only option.
- OpenOCD Errors: Pay attention to the specific error messages. Sometimes the wrong interface or target script is used. Ensure the detected flash size matches your expectation (64k for C8T6).
You now have the firmware dumped as a .bin
or .hex
file, which you can analyze or use as a backup.



From each step it is possible to Dump the Firmware.
Using OpenOCD we can also reset the fuses that are used in the MCU, if you look at the code, I reset the fuses that had set the STM32 to read only mode. Doing so can reduce the effects of corruption of the firmware.
References
- https://tbruno25.medium.com/car-hacking-faster-reverse-engineering-using-canopy-be1955843d57
- https://dangerouspayload.com/2020/03/10/hacking-a-mileage-manipulator-can-bus-filter-device/
- https://github.com/manupawickramasinghe/Esp32LeafInverterBridge/...
- https://github.com/dalathegreat/Nissan-LEAF-Battery-Upgrade
- https://hackaday.com/2019/12/16/dashboard-dongle-teardown-reveals-hardware-needed-to-bust-miles/
- https://hackaday.com/2013/10/21/can-hacking-introductions/
2 Comments
Amazing !
ReplyDeleteThank you 🙏
Delete