CAN Bus Reverse Engineering – Door Status: Part 2

By | May 12, 2021

In a previous post, I found and reverse engineered the door status message on the HS-CAN bus on my vehicle. For reference, the HS-CAN bus on my vehicle is on Pins 6 & 14 of the OBD Port (J1962 Connector) and it is a High Speed CAN network operating at 500Kbit/s which is true for every vehicle sold in the USA since 2008. In this post, I will I try to influence the display of my Instrument Panel Cluster (IPC). I determined, with the help of the internet, that the IPC is on a network known as MS-CAN. MS-CAN is accessible on Pins 3 & 11 of the OBD Port and it is a High Speed CAN network operating at 125Kbit/s. My gut said that there was a separate CAN message on the MS-CAN network which also indicates the door status so that the IPC can react accordingly and update the display.

Quick disclaimer before we continue on: All code in this article is licensed under the MIT License, and I want to stress that I am not liable for any claims, damages or other liability from executing the software in this article – I have purposefully left all the channels on vcan0 so someone would need to modify the code first before it could do anything on a real network. Please use common sense and don’t inject CAN messages on a vehicle that is driving or a vehicle that is not compatible as messages containing Engine RPM information on one manufacturers vehicle might be a blow airbags event in another.

In order to access the MS-CAN bus using my USB2CAN tool, I had to make use of the special MS-CAN harness adapter I made in another post. I then configured my tool to operate at 125Kbit/s using the following commands:

sudo ip link set can0 type can bitrate 125000
sudo ip link set up can0

The next thing I did was plug in the connector with the adapter attached into the J1962 vehicle connector and fired up cansniffer. I looked at each individual CAN message for changes as I opened the driver side font door and closed it. I quickly noticed that a message with CAN ID 0x80 changed everytime I opened and closed my driver side front door. After that, I reached over and opened the passenger side front door and it changed again. The way the data was encoded into the message was very similar to the sister message on the HS-CAN bus which made spotting the signature I was looking for in the data all the more easy.

// All Doors Closed
can0  080   [8]  77 83 06 3F D9 06 03 82
// Open Front Left Door
can0  080   [8]  77 83 06 3E D9 06 03 82
// Open Hood
can0  080   [8]  77 83 06 1E D9 06 03 82
// Open Front Right Door
can0  080   [8]  77 83 06 1C D9 06 03 82
// Open Rear Right Door
can0  080   [8]  77 83 06 14 D9 06 03 82
// Open Trunk
can0  080   [8]  77 83 06 04 D9 06 03 82
// Open Rear Left Door
can0  080   [8]  77 83 06 00 D9 06 03 82

This message with CAN ID 0x80 was transmitted onto the MS-CAN bus every 60 ms. After studying this CAN message in various vehicle operating states I was able to deduce the following:

Offset Byte[Bit] Length Byte[Bit] Value Comments
0[0] 1[0] $77 Uknown (Static)
1[0] 0[7] $3 Uknown (Static)
1[7] 0[1] 1 – Key In RUN
0 – Key Not In RUN
Key In RUN Status
2[0] 0[4] No Key – $1
Key OFF – $2
Key OFF transition from ACC – $3
Key ACC – $4
Key ACC transition from RUN – $5
Key RUN, Engine Off – $6
Key RUN, Engine On – $7
Key START – $9
Ignition Status
2[4] 0[4] $0 Unknown (Suspect Reserved)
3[0] 0[1] Closed – 1
Opened – 0
Driver Side Front Door (Front Left) Closed
3[1] 0[1] Closed – 1
Opened – 0
Passenger Side Front Door (Front Right) Closed
3[2] 0[1] Closed – 1
Opened – 0
Driver Side Rear Door (Rear Left) Closed
3[3] 0[1] Closed – 1
Opened – 0
Passenger Side Rear Door (Rear Right) Closed
3[4] 0[1] Closed – 1
Opened – 0
Hatchback (Luggage Compartment) Closed
3[5] 0[1] Closed – 1
Opened – 0
Hood/Bonnet (Engine Compartment) Closed
3[6] 0[1] $0 Suspect Either Reserved or for Sunroof/Moonroof
3[7] 0[1] $0 Unknown (Suspect Reserved)
4[0] 1[0] Usually $D9, although did see $C9 briefly Unknown
5[0] 0[4] No Key – $1
Key OFF – $2
Key OFF transition from ACC – $3
Key ACC – $4
Key ACC transition from RUN – $5
Key RUN, Engine Off – $6
Key RUN, Engine On – $7
Key START – $A
Ignition Status (Secondary)
5[4] 0[4] $0 Unknown (Suspect Reserved)
6[0] 2[0] Usually initially $0000, but after the engine runs a while this value gets set. Maybe average idle RPMs? Appears to be some 16-bit value

I then wrote the following python script to override the native door signal.

import can
import time

bustype = 'socketcan'
channel = 'vcan0' # can0 on non-virtual physical bus

bus = can.interface.Bus(channel=channel, bustype=bustype, bitrate=125000)
for i in range(6000):
    #driver door open, key in run, engine off
    msg = can.Message(
        is_extended_id=False, 
        arbitration_id=0x80, 
        data=[0x77, 0x83, 0x06, 0x00, 0xD9, 0x06, 0x00, 0x00])
    print(msg)
    bus.send(msg)
    time.sleep(0.01) # send every 10 ms

The script sends the CAN ID 0x80 message representing the key in run position with engine off and all doors opened. The vehicle natively sends this CAN ID 0x80 message every 60 ms and in order to successfully override the native message the script sends its message every 10 ms.

Next, I placed the key of the vehicle in run position with the engine off and all the doors closed so that IPC display looked like the following:

I executed the script and monitored the bus during the execution of the script. Below is the annotated output:

 (1618619305.844831)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.855390)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.865933)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.876488)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.887065)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.890145)  can0  080   [8]  77 83 06 3F D9 06 00 00 <-- vehicle message
 (1618619305.897486)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.907962)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.918437)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.928922)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.939475)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.946819)  can0  080   [8]  77 83 06 3F D9 06 00 00 <-- vehicle message
 (1618619305.949926)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.960383)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.970850)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.981342)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619305.991781)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.002259)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.007437)  can0  080   [8]  77 83 06 3F D9 06 00 00 <-- vehicle message
 (1618619306.012693)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.023212)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.033660)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.044103)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.054610)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.065080)  can0  080   [8]  77 83 06 00 D9 06 00 00 <-- script message
 (1618619306.067178)  can0  080   [8]  77 83 06 3F D9 06 00 00 <-- vehicle message

Please note that the script transmits it’s version of the message 5-6 times for every time the vehicle transmits it’s native version of the message. Immediately after starting the script, despite all my doors being closed, the IPC showed all the doors including the engine compartment and luggage compartment, as being opened. Success!

Thank you as always for reading. This was a fun exercise in CAN bus hacking with an easily verifiable result. If you have questions or comments, please let me know.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.