Hi there. Welcome to my talk where I go through and brick a very expensive automobile, then I eventually make it faster. Hope you enjoy it. It was certainly the most complicated reverse engineering project I've ever worked on. So a little bit about me. My name is Patrick Kiley. I'm a member of the Penetration Testing Team at Rapid7. I've been working in the industry for about 17 years. I've done previous research that I've released on avionics security. I've done quite a bit of research specifically on internet-connected transportation platforms. I have experience in hardware hacking, internet of things, autonomous vehicles, and CAN bus. So here's a overview of all the topics that we're gonna cover. First, we're gonna go over the architecture of the Model S and specifically the battery management system. You'll find all that needs to be relevant when I explain some of the other stuff. The timeline of when the Performance Model S and Ludicrous were released. The hardware changes that have to occur in order to make a car move at Ludicrous speeds. The data stored within the diagnostic program that Tesla uses within its service center is called Toolbox. Some of the firmware changes, in fact, all of the firmware changes that have to occur to the battery management system to make it work. The process of modifying the high-current shunt. For those of you who haven't heard the term before, shunt is a method within electrical and electronics of measuring current using a known resistance value. And this is a device within the high-voltage battery that has to be modified in order to allow it to handle the power of Ludicrous. And it turns out it was a very important part of this whole process. And then we'll actually go over the upgrade process, how I failed and bricked the car, what I learned and had to have it towed across state lines, and some pretty cool things on how I was able to dig a little bit deeper on how the gateway works and some special files that it stores that determine the configuration of the car. And then next steps, can we actually take Ludicrous speed further? Should we? And what we need to do to make that happen. So a little bit about the architecture of the Model S overall. It has the central display. So if you sit in a Model S, there's a large screen to your right or to your left if you're a passenger or to your left if you're in a right-hand drive vehicle. And then there's also instrument cluster. Both of those actually run the NVIDIA Tegra up until recently where the central display switched over to Intel Atom. All this is gonna be, assuming it's an NVIDIA Tegra base because that Tegra has to be rooted for this research to work. The next component that's really critical to this is the gateway. The gateway sits between the central display, the instrument cluster and the rest of the vehicle. It acts as a firewall between the various CAN buses and between the CAN buses and the infotainment features as well as the internet connectivity and Wi-Fi connectivity, et cetera. The next component that's critical to this because that's where all the modifications in are the Powertrain CAN bus. This is a standard CAN bus running at 500 kilobits a second. It contains the battery management system, the drive units, all the charging and thermal controller set on that CAN bus. Beyond that, it's a standard vehicle CAN bus. It runs at, again, 500 kilobits a second, uses 11-bit arbitration IDs. And very importantly, it supports UDS. Many of the routines that you actually have to modify to do this require UDS to work. And having some knowledge of UDS turned out to be critical for me to do this research. I managed to learn quite a bit about it. So next we have the battery management system. Battery management system is a board that sits inside the battery pack at the rear. Primary microprocessor on is a TI TMS320C2809. There's a hardware backup for it. So in case there's some type of hardware failure, the hardware backup is an Altera CPLD. It's critical for one step of the process that we're going to do later. And then there's a current shunt and pre-charge resistor. The full reversing of these components is an ongoing project. So if you want to help reach out to me, because there's some of the skills like assembly for the TMS320 that I'm not very good with. So here's a skipped over some of the steps because it's easier to show on the screen. The high voltage contactors, you can see in the middle of those round circles with two large terminal posts on them. The high current shunt that sits, connects directly to the battery management system. It sits between one of the bus bars going from the battery to the contactors. There's a pre-charge resistor. So the way that the contactors are engaged are, when the vehicle wants to enable battery power to the rest of the vehicle, one of the contactors closes. And then the pre-charge resistor sits there as a slow, relatively slow current path for the rest of the high voltage system to come up to match the voltage of the battery. And it's only then that the BMS allows the other contactors to close. So you don't get inrush current and you don't get damaged components from the massive amount of power that's in that battery system. From there, we actually have 16 battery management boards. These contain all the bleed resistors so it can balance the voltage across all the packs. There are 96 of them, I believe six in each of the 16 modules. And then the BMDs also manage the, they monitor the temperature and of course the voltage of the individual battery modules. And then the last thing you see on the far right, voltage sense. Voltage sense is the component that actually sits on the four contactors of the battery. So not only can it actually detect when the battery contactors are open or closed, so if they're not in a state where the BMS expects them, but they're also used to measure the current voltage level coming from the battery. So a little bit of history, and this will be relevant in just a manual CY. So in 2014 of October, the performance dual motor Model S was announced. This was ridiculously fast when it was released, something like 3.4 seconds, zero to 60, but it wasn't until July of the next year that Ludicrous was announced. So when Ludicrous was announced, they announced it as a $10,000 option on new models of the new versions of the Model S. And it was $10,000 for a while. I think eventually they gave it away for free, but they keep going back and forth on it. That's really up to them. So it's always been kind of an optional item to make the car a little bit faster and have Ludicrous power on it. So $10,000 for new buyers, but as an offer for existing P85D owners, they offered it as a $5,000 upgrade. And the press release actually mentioned that the upgrade involved putting in new contactors and a pyrofuse. But after a while, of many of the performance battery packs, so the battery packs that would go into the car would already be capable of running Ludicrous mode and they just wouldn't have the feature turned on. And when I say Ludicrous capable, what I mean is that all you have to do is modify a single file on the gateway of the vehicle. So you route the vehicle, modify the single file, and it has Ludicrous mode. All the P100Ds, as far as I understand, and all the newer Model S's that are dual motor performance, all you have to do is modify this single line on the gateway. So I've got a little bit of information about that. So the gateway has this file called internal.dat. It stores the car's configuration. It has like, you know, for example, the type of wheels that are on it so that the displays actually reflect correctly, the color of the car, the version of the thermal controller, the version of the various drive units, and the version of the battery pack. Bunch of other configurations it also controls. It's also the file that is modified when I heard about how people had supercharging disabled. That's where it's disabled. It's actually disabled client side on the vehicle. But for the purposes of this talk, all you have to do is from a rooted vehicle, request this internal.dat file, make a quick file editor change of which the, you know, VI and nano are both there. So you go into internal.dat, add this line, performance add-on, and add the value of one. From there, you copy it back over to the gateway, reboot the gateway, and then boom, the vehicle's ludicrous. But that's not the case for the earlier models. The earlier models where you actually had to do quite a bit to the firmware. I'm just talking about the later ones. So the later ones that were ludicrous capable already, in other words, the battery was already capable of ludicrous speeds. This is the only thing you have to change. So, okay, kind of alluded to earlier, the earlier vehicles, you know, so some of the 90s, all of the 85s released up to that point required hardware. They required modification of the current shunt. You had to reflash the firmware in the battery management system. You had to recalibrate the current shunt. Only then could you actually add that value to the gateway file, internal.dat, and actually reconfigure it to support ludicrous speed. If you did it before that, it wouldn't show, actually give you the speed. It would show you the setting, but it wouldn't go any faster. So we did this. I actually upgraded an owner vehicle. We have a contact in Southern California. For those who don't know, I'm actually located in Las Vegas. So I threw some online forums of someone else who was actually hacking on their Tesla. Guy owned a body shop. He was willing to let me loan his lift. So a lift isn't something you can just kind of go to a guy and say, hey, can I borrow your lift for a couple of days? Because they'd be like, no, I have this thing called insurance. And no, just go away. So he let me do this, very gracious. Thank you, Bitbuster. Call you out here at the end. But another little quick anecdote, this guy who loaned me this garage, he was actually hacking on a Model S. He took the car and actually enabled autopilot version two on an autopilot one car. So he added all eight of the cameras, put in the newer computer, replaced the steering rack and a bunch of other stuff and actually got retrofitted autopilot two. So all the full self-driving stuff to an older model vehicle. Pretty cool stuff. I was pretty impressed with that. And I believe he's the first person in the world to ever do that. So here's a picture of the pack dropped. It was fairly complicated, but not too hard. You know, you remove the central bolts and then lower it down onto this big heavy rack that can support the weight of the entire vehicle. And then you remove the ones along the edges and then raise the car back up. Battery pack drops out. All the electrical connections are quick disconnects. The coolant is a quick disconnect. I believe this is because originally Tesla was toying around with this idea of having swappable battery packs for people on the road. I believe they had a pilot program at one point. It just never really seemed to go anywhere. So they make it really easy to drop the pack as long as you have access to the appropriate equipment. So here in this next picture, we have a picture of the fuse bay, which is up at the front of the vehicle on the opposite side of where the coolant tubes enter the pack. Here, the cover over the fuse is removed and the old fuse is visible, the fuse that actually has to come out. And then on the right, we have the contactor bay with it opened up, the cover plate removed and the old contactors removed. All right, here we have a close-up of the current shunt. You can see it sits right next to the BMS. And then the new contactors are installed at this point. Here's a close-up of the BMS. You can see that it just sits at the very bottom of the bay and it's just kind of on the right side or left if you're staring at the car from the front. But from my perspective, it's on the right. And you can see the TMS 320 right there, kind of in the middle, CPLD off to the right and what is that between the two? Enhance. Oh, that's interesting. That label says JTAG. Get into that later. Yeah, it actually has JTAG. The BMSs that I messed with on my bench, none of them actually had that connector. It was all covered over with conformal coating but the one in the car that I modified actually had these headers on here that say JTAG. Kind of interesting. Another thing that you have to do is you actually have to replace a second fuse. So there's older vehicles. This is underneath the rear seat. There's a fuse between the center thing called the high voltage junction box and the front drive unit. So one of the things that I kind of found by digging around in Toolbox that we'll get into later is you actually have to replace this fuse with a bus bar. Yeah, that's right. The instructions say you replace the fuse with a bus bar. So we did that. Here's the front fuse. Here's the front fuse removed and here's the front fuse replaced with the bus bar. Put it all back together, put the seat back in, connect all the high voltage interlocks, back up and that part is done. So what about front bar? This is really where the majority of my time went. The physical work was actually pretty easy to figure out. Tesla actually publicly talked about the components that were involved. The firmware was the hard part. And to do this, we need to dig into some Python. Tesla uses a diagnostic tool called Toolbox. It's a Python Windows executable. That's right. It's an executable written in Python, but it runs in Windows. So it's been compiled and then encrypted. It uses these plugins that are compiled and encrypted, it's designed to work without a connection to the internet. So all the information that you need to decrypt these indual files called scrambled, as you can kind of see in this image, are actually on the executable. So if you were able to get an image or grab the correct files, you're able to decrypt these modules. To be completely honest, this wasn't my work to figure this out. This was other people that actually figured this out. They had done some of the decompiling as well. So you can use uncompile six to actually run the PYC compiled files and get Python source code. I did a lot of that. I wrote a really, really ugly Python script to iterate through every single one of the scramble files, because the scramble files are also all kind of zipped up together. There's a bunch of separate source code files underneath each one in separate directories. So I iterated through them all, ran uncompile against them, and then did some additional work that I'll talk about in the next slides. But they also left all the source code comments in place. So thank you. That actually helped me figure this out. So this is an example of just the header of a file. This is the UDS one. You can see it actually has all of the comments here in place. Here's the headers added by uncompile, but it actually shows when it was compiled, who compiled it, who's the author, gives me his email address too. And then the copyright information on it. So here's the kind of thing that I was able to actually see by digging through all these. This is one of the specific files used to configure for Ludicrous. So this is the performance add-on config. This is the one that modifies the gateway if you don't do it manually like I did. And it tells you that you first have to verify the vehicle can be configured. For Ludicrous mode, the vehicle needs to be all wheel drive and have a battery pack config that supports the 1500 amp current discharge. So this is assuming the battery pack has already been modified. There are other routines in Toolbox that actually go through this. One of the most important things in these Toolbox files were these data structures. So you can see these two variable names, three variable names, qt-resource-data, qt-resource-name, qt-resource-struct. My really, really ugly Python script went through those and actually converted those back into binary. And then from there, I ran binwalk against those binary files and I got a ton of useful information. Things like this, this is the pointer that tells me exactly how to do it. It says that, so we already know that the donor vehicle has a pack ID of 57. I didn't say that previously, but the donor vehicle had a pack ID of 57. It says, okay, so if you're gonna change pack ID, battery pack ID 57 to 70, here are the three firmware files that you need. Okay, well, where do I get those firmware files? Turns out they were stored within those Python data structures. When I ran binwalk against it, I actually got a tar file of firmware. And when you untar that file, you get every single one of these hex files of firmware. It was all stored within the Python executable, all right there, ready to be used. So for this upgrade, pack 57 becomes pack 70. Pack 57 is a 1300 amp battery pack, pack 70 is a 1500 amp. One of the things that I kind of did that I thought was interesting, since we're still talking about the firmware, is I did some differential analysis of the bootloaders. So I have the two different bootloaders here, 57 and 70. You can see that there really weren't that many changes. On one line, it's a single bit that changes. The other one that, you know, 537 and 730 that you see here are just the R and then the actual number. One is 57, one is 70. And then we have this short little string of, you know, group of hex characters. And that was the only change between the different versions of the bootloader. But it's not the application file. Application file had a few, a bunch of different changes. It's just the bootloaders themselves were all very, very similar. So to do this upgrade, all the instructions and files that you need for this were stored in these toolbox files. There also were a bunch of other really helpful files. DBC files, for those of you who've hacked on a vehicle before, DBC is the instruction file that stores all of the various CAN bus signals so that you can interpret them. And these individual DBC files for all the various CAN buses of the vehicle were stored within toolbox. The ODX files, ODX is a XML style format that defines how to do diagnostics, how to do firmware upgrades, how to get security access. A bunch of other stuff are stored in kind of the ODX file format. So the diagnostic routines are ODX, the CAN bus interpretation routines are DBC. And then there were also files that stored the calibration data for the shunt. Those are stored also in a Python pickle. Turns out that every single vehicle that was eligible for ludicrous upgrades by upgrading the battery had the shunt calibration values stored as an array within this Python pickle file. So you have to actually look up the shunt on the vehicle that you're upgrading, compare it to this pickle file and get these shunt calibration values that I'm gonna show you in a little bit. And then of course, there are all these text comments and other data structures that kind of eventually allowed me to piece together the process. So kind of talk a little bit more about UDS. Here's what a UDS file looks like. This is the one for actually shunt calibration. It shows that there are all these parameters, HWID, CGI1, CAU1, there's also a CRC value and a serial number, a serial number. And again, CAN networks use a DVC file, UDS use ODX or GMD. So I use the commercial tool Vehicle Spy to actually do the next steps of this research. I took these DVC files and these ODX files and imported them to Vehicle Spy, plugged it into the bench, plugged it into an actual vehicle and just sat there and listened to traffic so I could try and figure it out. So it turns out that the ID's 232, the arbitration ID is 232 for the BMS, 266 and 2E5 for the two drive inverters, they identify max power, those are variables. They vary based on state of charge, temperature and power recently used. On Sunday, I'm actually gonna have an in-depth, a deep dive into these DVC files and some of the information because I wanna actually map out the entire power curve to see if I can put that back and actually figure out where the power curve is stored in the BMS firmware. But check that out if you wanna actually see a little bit further into the talk than what I'm able to cover on this. So what a DVC does, this is what raw CAN bus traffic looks like. You can see all the IDs, you know, 102 through 302 down here, and you just see a bunch of data. But once you put in a DVC file, you can actually translate it all. So you can actually see that all the values for BMS basically means that this is the BMS who's actually sending this. You can see the power available. This is power available before the drive units are engaged. So this is just the car sitting in an off mode before you press the brake pedal and engage the drive units and wake the car up all the way. So again, ODX routines for shunt calibration. Here's the actually ODX routine imported into Vehicle Spy for actually doing the shunt calibration. So what you do is you actually connect to the car, read the value of the shunt. You actually have to do some firmware stuff, but I'll go over that in a minute. And then modify these values. So these are values that are already modified. The reason thing I thought was interesting is the CGI1 and CAE1 values are all identical for a ludicrous vehicle where they weren't before. And then we have a serial number and a CRC. And then of course the hardware ID. This is actually, it shows write success with that. This is actually a read function. So the 23 is a read function. There's a separate function for actually writing the shunt. And again, I actually demonstrate the process on Sunday in the deep dive. So one of the things I found out by building this all on a bench and doing this work is the shunt also needed a hardware modification. After I did the upgrade on a bench, I kept getting this error message that would pop up on the central display. And also, you know, within the DVCs of a CAN bus, it gives you arrays of all the various error messages. And it talks about overcurrent sense. There's a particular error message that just popped up showing overcurrent sense after I modified the firmware. But the error was not there before. So digging into this, what I did is I actually made a breakout board and used a logic analyzer and analyzed all the signals coming off of this shunt. Actually, it turns out it's a very simple communications protocol that it used. But this one wire, as it turns out, eventually connects to the CPLD. So it looks like that there's a sensor within this shunt that for ludicrous power, they want disconnected. They don't want it to be able to communicate to the CPU DLD. And since the CPLD didn't change, assuming it has something to do with it, you know, the current values going through the CPLD, they didn't want to modify. Tesla didn't want them modified. So when this wire was disconnected, that error message went away. So that basically tells me that there's a wire that has to be disconnected during the process of actually doing this upgrade. So again, go to California, drop the battery pack, drain the battery as much as possible, do all the hardware stuff, modify the shunt, disconnect that wire, very scary stuff. And then there's actually these special gloves that I purchased, special gloves and special socket wrenches that are used when you're dealing with high voltage. They're a rubber glove with a leather over lining. And then you're just careful about, you know, where you're standing and proximity to the other components. And even though the fuse isolates you, there's still enough of a charge and something where you can shock yourself. And again, if you're touching the wrong things, you can actually hurt yourself. So there's quite a few precautions you actually have to do. I talked to a few Tesla techs and they told me what the gloves were that they were. So I ordered a set of those and used all possible precautions for doing that. So we dropped the pack, do all the hardware stuff, reinstall the pack. So the reinstalling the pack was probably the most pucker factor part of the whole install because I was really nervous about having a rich rebuilds moment and actually damaging one of the leads because then I'd have to leave the vehicle there for a long time and have the customer angry at me. So I used a bore scope, both back here at the battery pack, these are the main battery pack contacts, going back into the battery and then up front where the coolant lines were, I scoped those and then just very slowly lowered the vehicle onto them all. Everything went flawlessly. Reinstalled all the hardware, lifted the car back up, verified everything, dropped it completely off the lift and then had to do all the firmware stuff. So it turns out you have to actually flash the BMS with special firmware. There was those three files that actually says that to do the shunt calibration, you load this file onto the BMS. So there's a special application file just for doing the shunt calibration. Look up the shunt value, recalibrate the shunt with the value based on the serial number. I had already extracted that serial number and validated that it was in the table. So I knew I was okay there. That all went without a hitch. Flash the BMS with its new bootloader, flash the BMS with its new application firmware, updated internal.dat, changed the pack ID, and then tried to do a firmware redeploy, which is the thing that you have to do after you change any component on the vehicle and then drive away, right? No, no. This is where the fun begins. I used every known technique that I've used before. I've tried putting on new firmware. I messed with this for a day and a half. I think I aged myself quite a bit, but I didn't want to stress myself out. It failed. It would not redeploy. It would not reinstall. I was getting an error every single time. So I started logging a lot of data, tried to troubleshoot, couldn't figure it out, was stressed out. Finally just said, screw it, towed the car from Manchurian-Cucamonga back to Vegas so I can continue to work on it. But it only cost $360 or $3,600. So not great, not terrible, right? But I learned something cool. I was able to figure something else out. So flew home, started messing with my bench, trying to replicate this condition, dug through my error logs that I copiously captured and I was noticing an error mentioning something called firmware.rc. The file was generating some type of error. It turns out the gateway uses this as a validation check and the values in it are calculated during the upgrade and redeploy. So in this file stores all these CRC values. So I had seen one other reference to it. The Tencent guys had done a previous Tesla hacking presentation where they talked about how the gateway used this file. So I went to the gateway and said, instead of gwtransferinternal.dat, gwtransferfirmware.rc and boom, it gave me the file. I saw it and it had all these CRC values. So all I had to do was look up from the, there's a map of files for this specific BMS firmware that it's supposed to be running for that pack ID and that version of software, made sure that version of software or firmware was running on the BMS and then grabbed its CRC value. Replaced the CRC value in firmware.rc with the value for the new pack ID. And then if you look here at the end, you can see there's a separate one for file CRC. There's even little values for the door handles, this drfp and drrp, those are values for the various door handles. So if you upgrade the door handle, the new firmware, firmware.rc has to be changed. It turns out I had a new door handle that I actually had to change to, but it wasn't causing an error that wasn't causing the vehicle to be able to operate. So what you do is you strip off the CRC line, calculate the new CRC. It turns out it's a jammed CRC 32. Someone else figured that out while they're helping me. I didn't figure that out myself. And then put the file back on the gateway. And after I did that, the car woke up, the errors cleared, and that was the problem. And I eventually figured out the reason for the other failure. I'm not gonna talk about that, it's really embarrassing. It was something I added to the car that it didn't have, that it didn't need. But yeah, hit me up with a beer sometime and I'll talk about it. So here is the power before and after the upgrade. I grabbed the CAN bus data before. Before the upgrade, it had 1305 amps available. These are static values again. These aren't the ones that are available based on state of charge. These are a hard limit. After the upgrade, it had 1516 amps. But it actually has a separate CAN bus line 202 instead of 702, the debug one, that actually has a slightly lower value. And I have no idea why. So if someone from Tesla wants to tell me, I'll keep it to myself. I'm just really curious why the vehicle has that extra 16 plus eight, 24 amps of power missing. Actually 23.6 amps of power missing. So if you can tell me, I'm really curious about that. It doesn't look like there's any derating going on because that value right above it is there. It says derating active zero. So I'm assuming that means no, but I'm curious. Okay, so here's where we can take this project from here if you want to help. The TMS320 is supported in IDA Pro. I've actually got some stuff on that in the Car Hacking Village Deep Dive. Again, arbitrations AD72 and 202 defined max current. There's one more for the other drive inverter. I can't remember what it is. So it seems possible to increase speed behind ludicrous and actually do it safely. It has been done by others. There's a guy back East who actually has a rear wheel drive P85 that he faked the unit out and basically created a CAN bus emulator for the front drive unit and bumped the VMS beyond the limits that it can handle. So it seems that all you have to do is go into that firmware and bump the values up a bit. You can probably even recalculate the CRC value. And it looks like, since we know how to change the gateway, we can just change that as well. But it can be dangerous if you take this too far, you're gonna burn up the car. You're gonna start blowing the individual cell fuses. But there is some room in there, it looks like. The current amp drain for the Model S batteries, it's only like 6.6 C, 20 amps per cell. For those of you who worked in RC before, you know that you can actually go beyond that for short periods of time. But who knows what the IGPTs within the drive unit can handle. You blow those, you're looking at a really expensive upgrade. But again, I just wanna reverse engineer this for the personal point of reverse engineering. I wanna understand where these values are stored so that others more brave than I can actually turn their cars into true drag monsters. Put in better batteries, maybe double up on the number of batteries and just turn their Model S's into just things that annihilate everything else on the track. I'd also like to understand the shunt parameters, CAU1, CGI1, I don't know what those are, I just know they had to change. So again, come check out the Car Hacking Village Deep Dive and we'll do some more analysis of the firmware, we'll actually show where you can take a project from here. So reference materials, I had to remove the first link so we don't have a copyright, that was the first thing. But again, thank you to the Space Vessels Moving for inspiring Ludicrous Mode. And then the P85D announcement, the Ludicrous announcement. ElectroBoom, if you haven't checked out his YouTube page, pretty funny guy, he actually describes a current shunt better than I ever could. The data sheet for the TMS320 on TI's site, very helpful for the AIDA stuff that I was working on. I'd like to thank Intrepid Control Systems, they made the Vehicle Spy software. Bitbuster, thank you for letting me use your lift in your garage, it was invaluable in this work. The guys who helped me with the toolbox reversing, I know you are, thank you all, you're invaluable for all this work. And then the Tesla Security Team, thank you for actually letting me do this talk and being so supportive of this research. And then of course, all these names, the Model S, P85D, those are all registered trademarks of Tesla. We are not sponsored by or associated with Tesla in any way. And thank you for listening. We're gonna have a Q&A at some point later today, so bring your questions there, I'd be happy to answer them.