Tesla Model 3 Rear Drive Unit Hacking

Topics concerning the Tesla front and rear drive unit drop-in board
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Will do and test tomorrow. Thanks Dave.
I'm going to need a hacksaw
User avatar
johu
Site Admin
Posts: 6969
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 455 times
Been thanked: 1771 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by johu »

Hmm, this should be handled in code, I had it in mind when coding. All code is unified to 1k pages. The only difference is the erase command. On 1k pages it is called once for canmap, once for params. On 2k pages it is only called once and then canmap and params are written in one go.
At least that's how it should be

Likewise in bootloader erase is only called when the next 1k to be written contains something else than 0xff
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
davefiddes
Posts: 375
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 149 times
Been thanked: 195 times

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by davefiddes »

I am remembering you explaining that now and why it had to be as complex as it is. Apologies. I think I need to go through the code again with a clear head tomorrow. I wonder if some more recent changes have broken the logic.
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

One thing that did seem to help yesterday was changing the page and can block sizes to 2k in hwdefs.h

Although it didnt fix the can mapping it did stop the processor hanging and rebooting. What seemd to take place then was akin to a memory leak where the can map kept growing until it reached the maximum number of allowed messages. All I can assume here is the code is looking for the canmap in the wrong place? Perhaps program space.
Attachments
Screenshot from 2025-08-24 08-24-23.png
I'm going to need a hacksaw
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Little bit more diagnostics. Starting from a fresh firmware and no canmap I try adding opmode to be sent on id 400 (0x190). It displays as 477(0x1DD) and indeed sends on 0x1DD. If I now add a second parameter UDC to be sent on 400 (0x190) it displays as id 400 and indeed sends on id 400 (0x190). Now if I ht save canmap all hell breaks loose and the spamming starts. This seems to occur regardless of the version of libopeninv used. Be it the master head , the version Dave fixed or the version used by the ZombieVCU master.
Attachments
Screenshot from 2025-08-24 10-28-54.png
I'm going to need a hacksaw
davefiddes
Posts: 375
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 149 times
Been thanked: 195 times

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by davefiddes »

I've checked the code again this morning and I believe it should work as johu described and automatically do the right thing irrespective of whether it is running on 1KB or 2KB flash page hardware.

The corruption of the CAN ID when adding a mapping is odd. Are you able to compare behaviour with the ESP8266/serial interface (assuming you are using the esp32-web-interface for CAN config at the moment)? Also doing the same with OpenInverter CAN Tool might be helpful. Something like:

Code: Select all

oic can add tx 0x190 opmode 0 8 1
oic can add tx 0x190 udc 8 16 10
oic can list
oic cmd save
oic can list
You need to turn off the esp32 CAN interface when using OIC as you can only have one CANopen controller operating on the same bus at the same time.

Just had a thought: I wonder if it is blowing through its stack. The parm_save() function needs a lot of stack (1KB) for a temporary buffer. You can increase the size of the stack by editing stm32_sine.ld to use all the RAM in your part:

Code: Select all

MEMORY
{
	rom (rx)    : ORIGIN = 0x08001000, LENGTH = 120K
	ram (rwx)   : ORIGIN = 0x20000000, LENGTH = 48K
}
Edit: Wait, that's not going to work. Uhi22 and johu found a bug last year with the stack initialisation that hasn't been picked up by stm32-sine yet. Try:

Code: Select all

cd libopencm3
git switch master
make TARGETS=stm32/f1 clean all
This will pull in the fix they found for Focci. There's a lot more going on with the Tesla M3 gate drivers and oil pump compared to the regular stm32-sine.
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Thanks Dave. I have been working via the esp8266 wifi driect to serial usart 3 as I have not as yet installed the inverter in the drive unit due to this problem. So I did the memory increase , reflashed and used oic to try to add mapping. Results attached.
Attachments
Screenshot from 2025-08-24 13-21-03.png
Screenshot from 2025-08-24 13-21-43.png
I'm going to need a hacksaw
davefiddes
Posts: 375
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 149 times
Been thanked: 195 times

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by davefiddes »

That's messed up. It works perfectly on my Bluepill when I do the exact same thing. Web interface (via serial) reflects the changes and works fine too.

I'm running out of ideas for how to debug without having hardware on my desk. Not having an STM32F103VCT6 makes it very difficult.

As a last ditch attempt I've taken your code and integrated it with the latest trunk of stm32-sine and libopeninv. I've focussed my testing here because johu did fix a bug related to CAN map saving. The code branch is here: https://github.com/davefiddes/stm32-sin ... perimental

Can you take the binary from https://github.com/davefiddes/stm32-sin ... 7189994309 and give it try? That'll rule out any toolchain or working directory problems at your end.
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Exact same. I even did a full chip erase via SWD just in case.
Attachments
Screenshot from 2025-08-24 16-53-16.png
I'm going to need a hacksaw
davefiddes
Posts: 375
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 149 times
Been thanked: 195 times

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by davefiddes »

Thought I had a brilliant idea: Convert a VCU to use 1KB flash page size.

No dice, apart from hosing the existing config it works fine and I can set up and save params and CAN map. Whatever is going on is stm32-sine specific.
User avatar
johu
Site Admin
Posts: 6969
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 455 times
Been thanked: 1771 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by johu »

I also reckon this is somehow a side effect of something else.
Apart from that the flash layout is somewhat flexible, only flashend-3072 (blknum 3) is hard coded as the address for the PinInit structure for the boot loader. The configuration of stm32-sine puts params in flashend-1024 (blknum 1) and canmap in flashend-2048 (blknum 2)

If any of that is changed it mustn't overlap with PinInit. On 2k pages flashend-4096 (blknum 4) thus can't be used
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

So what is CAN2 in this case? Is that on Block4?
Attachments
Screenshot from 2025-08-24 20-33-20.png
I'm going to need a hacksaw
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

In order the changes I have made over standard STM32-FOC are

1)Change timings to have 8.8KHz pwm and resolver.
2)Activate DMA2 in order to use UART4 for LIN.
3)Change FLASH_PAGE_SIZE to 2048.
I'm going to need a hacksaw
davefiddes
Posts: 375
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 149 times
Been thanked: 195 times

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by davefiddes »

Jack Bauer wrote: Sun Aug 24, 2025 7:34 pm So what is CAN2 in this case? Is that on Block4?
That symbol is not currently used. I think it's a placeholder for functionality that nobody has yet implemented.
Jack Bauer wrote: Sun Aug 24, 2025 7:36 pm 3)Change FLASH_PAGE_SIZE to 2048.
I backed that out on my branch and the binary you tested.

The changes you made are minimal and didn't look scary to me.
User avatar
johu
Site Admin
Posts: 6969
Joined: Thu Nov 08, 2018 10:52 pm
Location: Kassel/Germany
Has thanked: 455 times
Been thanked: 1771 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by johu »

Jack Bauer wrote: Sun Aug 24, 2025 7:34 pm So what is CAN2 in this case? Is that on Block4?
So for CAN:

Code: Select all

   uint32_t flashSize = desig_get_flash_size();

   return FLASH_BASE + flashSize * 1024 - FLASH_PAGE_SIZE * CAN1_BLKNUM;
You'd end up at 0x08000000 + 256*1024 - 2048 * 2 = 0x0803F000
As Dave says neither CAN1_BLKSIZE not CAN2_BLKNUM play any role and if there's any mapping saved for CAN2 it would overwrite CAN1 (but only when saving to flash!).

Parameters:

Code: Select all

   uint32_t flashSize = desig_get_flash_size();

   //Always save parameters to last flash page
   return FLASH_BASE + flashSize * 1024 - PARAM_BLKNUM * PARAM_BLKSIZE;
0x08000000 + 256*1024 - 1*2048 = 0x0803F800

So far so good but now comes PinInit:

Code: Select all

#define PINDEF_BLKNUM    3  //3rd to last flash page
#define PINDEF_BLKSIZE   1024
Fixed at 1k page size

Code: Select all

   uint32_t flashSize = desig_get_flash_size();
   uint32_t pindefAddr = FLASH_BASE + flashSize * 1024 - PINDEF_BLKNUM * PINDEF_BLKSIZE;
0x08000000 + 256*1024 - 3*1024 = 0x0803F400
And it thereby sits in the same 2nd to last 2k page as CAN1 mappings. So if you insist on using 2k for params and CAN1 then CAN1_BLKNUM would have to be 3. Even if you observe that this "fixes" something. It rather covers something up.
I'd rather suggest to leave FLASH_PAGE_SIZE at 1k because CAN1 mapping and params on the same page is handled in code.

However, none of that would result in the processor faulting out so that must be caused by something else. Currently it would check the CRC of the page invalidated by write_bootloader_pininit() and thus not load anything from flash.
Support R/D and forum on Patreon: https://patreon.com/openinverter - Subscribe on odysee: https://odysee.com/@openinverter:9
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Thanks guys. I'll setup an MG board here on the bench today (same MCU) and hunt this thing down.
I'm going to need a hacksaw
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Starting off with a basic A-B test. Setup is an MG V2 board (same mcu as M3 board) , 12v from a drill battery , CAN and wifi. Loading the unmodified code from the MG-DU branch gives Normal operation of can and can mapping. Next up am going to do a clean build of the M3_DU branch and see what happens.
Attachments
20250825_103549.jpg
Screenshot from 2025-08-25 10-40-15.png
Screenshot from 2025-08-25 10-40-29.png
I'm going to need a hacksaw
davefiddes
Posts: 375
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 149 times
Been thanked: 195 times

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by davefiddes »

Uh huh. What's to bet the MG board works fine with the latest code.

You using the latest CAN bootloader (https://github.com/jsphuebner/stm32-CAN ... s/tag/v1.3) on both boards?
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Nope. MG board with clean build of M3 software and we are back to crazy can. Ignores commands of mapping from oic as yesterday. So its unique to the M3 code. Next move I'll strip down the M3 branch. Bin lin first.
Attachments
Screenshot from 2025-08-25 11-13-58.png
I'm going to need a hacksaw
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

If this line (272) in 10ms task in stm32_sine.cpp is commented out the canmapping behaves as normal.

Now to see why...
Attachments
Screenshot from 2025-08-25 13-47-12.png
Screenshot from 2025-08-25 13-47-12.png (8.15 KiB) Viewed 1350 times
I'm going to need a hacksaw
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

Narrowing further. Any call to LinBus:: Request will mess up the can mapping.
Attachments
Screenshot from 2025-08-25 14-06-39.png
I'm going to need a hacksaw
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

More narrowing. The junk can gets its id from lines 105 and 106 in LinBus::Request. So somehow, data being sent to and from the LIN peripheral is getting to the CAN peripheral via the map and/or DMA....
Attachments
Screenshot from 2025-08-25 14-14-09.png
I'm going to need a hacksaw
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

DMA is innocent. Simply having the following in Lin request causes the problem.
Attachments
Screenshot from 2025-08-25 14-20-14.png
Screenshot from 2025-08-25 14-20-39.png
Screenshot from 2025-08-25 14-20-39.png (9.73 KiB) Viewed 1337 times
I'm going to need a hacksaw
davefiddes
Posts: 375
Joined: Mon Jan 18, 2021 12:39 pm
Location: Edinburgh, Scotland, UK
Has thanked: 149 times
Been thanked: 195 times

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by davefiddes »

First reaction was "Wut!?" but I think I can see what's gone wrong...

There's a use-after-free on your LinBus instance in stm32_sine.cpp:

Code: Select all

   if (hwRev == HW_TESLAM3)
   {
   DigIo::gate_ps_en.Set();
   uDelay(200000);
   TeslaModel3::Initialize();
   LinBus l(UART4, 19200);
   lin=&l;
   linM3.SetLinInterface(lin);
   } // <------ the instance "l" is freed when this point is reached
   Stm32Scheduler s(hwRev == HW_BLUEPILL ? TIM4 : TIM2); //We never exit main so it's ok to put it on stack
If you shuffle the code to initialise the LinBus outside of the HW_TESLAM3 block it'll start working. I was going to move it anyway into the TeslaModel3 class (I think, implications need further thought) but no need to do that now.

Edit: The reason you see the data in CAN is because the memory that the LinBus pointer points to ends up being used by the Stm32Scheduler, Stm32Can, CanMap and maybe CanSdo class instances. When the 10ms handler runs is scribbles all over the internals of the CanMap class in an unpleasant way.
User avatar
Jack Bauer
Posts: 3831
Joined: Wed Dec 12, 2018 5:24 pm
Location: Ireland
Has thanked: 75 times
Been thanked: 696 times
Contact:

Re: Tesla Model 3 Rear Drive Unit Hacking

Post by Jack Bauer »

I reckon someone (probably Johannes) Has injected a buffer overrun exploit.
I'm going to need a hacksaw
Post Reply