Download as pdf or txt
Download as pdf or txt
You are on page 1of 19

CAN BUS 101

CAN (Controller Area Network) BUS is not a new network, but unlike more popular network
names, CAN BUS is geared more for Embedded Controllers such as the ones found in modern
automobile. So when I speak of CAN BUS 'Hacking', I am refering to automotive network
reverse engineering.

The CAN BUS is now a required network on vehicles manufactured in the U.S. from 2008 and
beyond. It's popularity amoung automotive OEMs is nearly universal. But unlike most open
protocols such as TCP/IP and HTTP, CAN BUS is almost entirely implemented as a proprietary
protocol. Thus if we want to understand it, we must 'hack' it.

Understanding What's Available

One common misunderstanding about the vehicle network data is that it is limitless. The truth is
that the only data on the network is the data that is required to be there. Nothing more, nothing
less. What is required is different from vehicle to vehicle. For example some vehicles might
have adaptive cruise control and this system might require vehicle dynamic information that is
not required on vehicles that do not posses this system.

More and more data is being added to already heavily loaded networks, so automotive OEMs
are adding more networks to accommodate more data. Good news for us, now we can get
more info at higher data rates.

Diagnostics Messages vs. Normal Message

When I speak to most people about the vehicle network or CAN BUS there is a common
misconception that there is only Diagnostic Messages or OBD II Messages. So what's the
difference between Diagnostic Messages (such as OBD II) and Normal Messages on a typical
CAN BUS?

Simply put Diagnostic Messages are Command/Response Messages. So if you want to get
data from a controller, you have to send it a request. It will then respond to that request
(hopefully). This is done using a common diagnostic protocol. There are only a handful that are
used and they are typically specific to the OEM, however there is not much difference between
OEMs on how they have implemented their flavor of Diagnostic Messages. That said all OEMs
that sell vehicles in North America support the common OBD II protocol, those in Europe
support the EOBD and in China, the new China OBD (Based on EOBD).

Normal Messages are the Messages that are transmitted between controllers. This data varies
depending on the electronics systems and like the OEMs Diagnostic Protocol, this data is also
proprietary. This data does not need to be requested (is nearly 100% of cases). This data is
typically sent at a periodic rate by a controller as fast as it needs to be sent so that listening
controllers get the most recent value. If you are doing data acquisition, this is the data you
want.

Unlock/Lock - How Distributed Systems Help You

So you want to Unlock and Lock the doors using the CAN BUS? Well I've got good news for
you, you can. Well sort of...

Because most modern vehicles have distributive electronic systems, unlock/lock type
functionality is often done via a CAN BUS message by the OEM themselves. Typically if the
RFA module (controller that receives commands from the key fob) is separate from the
controller(s) that actuate the door locks themselves, then this command will occur over the CAN
BUS.
So how do you know if this RFA is separate? You will most likely have to consult a wiring
manual such as the Mitchell Guide.

So if the modules are separate, you will have to connect to the vehicle's body CAN BUS (this is
often separate from the Powertrain bus or OBDII CAN BUS). Once you've found this network,
you will have to monitor the network for the Unlock or Lock commands by using the factory key
fob and watching for a new message that shows up or data that changes at the same instant
that you press the key fob lock/unlock buttons. Do this about 3 to 4 times and you'll find the
message that controls the Unlock and Lock commands. If you don't find it, try a little bit more,
but remember it might not be there.

So once you have the message, you can test it. To do this, simply send a message with the
same Arbitration ID and Data as the one that you discovered. Then see if the doors
lock/unlock. If they do, you've found it. If not, try again, perhaps you found a message related
to a door unlock/lock procedure such as disarm or dome light status.

OBDII and Enhanced Diagnostics Again

So you want to get data from the vehicle? Good news, its there you just have to know how get
it.

You have a couple of options: Buy the data or Reverse the Data from an Existing Scantool.

So you want to buy the data, here's how that works. You have to be a member of Equipment
and Tools Institute (ETI). An ETI membership will allow you to get access to most OEMs
(Honda, Toyota, Ford). In some cases you have to get an extra license with the OEM (GM and
Chrysler). An ETI tool membership will set you back around $5,000 plus $2,500 to get the
data. You are required to use the data in a commercially available tool within one year of
joining. And of course you cannot sell the data.
ETI data is not a slam dunk. You'll have to organize the data yourself. Sometimes it in Excel
files sometimes its in PDF's and sometimes Access Databases. So you'll have to massage the
data to fit your application.

The other method is to get the data from a scantool that already has the data. To do this you
will need to connect your scantool to a device such as a neoVI or ValueCAN and Vehicle Spy
software. These devices will allow you to simulate the vehicle's network. By connecting the
scantool to these devices you can send a properly formatted diagnostic response to the
scantools request. This will allow you to change the data portion of the message. By changing
this data you can derive parameter identifier, the data position and scaling.
For example, if you want to find Enhanced ID for Engine Speed you would setup the scantool to
request Engine Speed, it will send a message with Engine Speed parameter ID (0x000D) and
by changing the data in the response message from 0x00000000 to 0xff000000 to 0x00ff00000
to 0x0000ff00 to 0x000000ff you will find that the Engine Speed is located in the first and
second bytes of the response message. Now you can set the response data to 0x0001 and you
will find the scaling for the message will equal the signal value (0.25).
You can do this for each of the parameters you are looking for. Once set up, you'll find that it
will take about 30 seconds per parameter.

Determining Network Baud Rate

So you found a CAN BUS to reverse engineer, but you don't know it's buad rate. There are a
couple to find it out.

One. Go one-by-one through a possible list. CAN BUS baud rates tend to be of only certain
baud rates. I am not positive, but this most likely has to do with the common crystal speeds
used in microprocessors. The slower the crystal, the slower the bus speed. So baud rates tend
to be one of the following: 33,333 bps, 50 Kbps, 83,333 bps, 100 Kbps, 125 Kbps, 250 Kbps,
500 Kbps (Most common), 800 Kpbs, and 1,000 Kbps. The last two being the least common as
they suffer from reduce network length issues. You will not find a baud rate that exceeds 1,000
Kbps as this violates the CAN BUS specification.

If I do not know the baud rate of the network that I wish to connect to, I will typically go through
this list and hope one works. In some cases you may effectively decapitate the network by
having the wrong baud rate set in your tool. So make sure you are not switching baud rates
while the vehicle is in motion! This could cause undesired effects.

Two. Use an osciliscope or logic analyzer. The foolproof way of measuring any serial data
network such as CAN BUS is to use tool that can measure the one bit time. Baud rate is simply
the inverse of one bit time. So if you can measure this, you simply take 1/(one bit time) in
seconds and you have your baud rate.

The best location to find a single bit on CAN BUS is to look at the last transition. This is
typically the ACK bit (acknowledge). This is where receiving nodes send back a single bit to
say that they properly received the frame. This is always a bit by itself as the bit to the left is
recessive as well as the bit to the right whereas it is dominate. So it will stand out and you
should have little trouble finding it. So look to that last transition and mesure from on transition
to the next and you should get something like 0.000002 seconds. In this case you will simply
take 1/0.000002 and you will get 500,000. Thus the baud rate will be 500,000 Kbps. Done!

Hate the VIN, Wanna Change It?


Good news you can. Well sort of. The VIN stored in controllers is writable (well
maybe). But in some cases its difficult and some impossible. So I am hear to give you
some tips to make life a little easier.

First find out if the controller stores the VIN. This can usually be done on OBD II
controllers by sending a CAN message formatted like this:
ARBID = 7E0 DATA = 02 09 02 00 00 00 00 00.
This will get the first part of the VIN if it is on the controller. So a typical response might
look like this:
ARBID = 7E8 DATA = 10 13 49 02 31 39 48 31.
You could send a Flow Control Message (7E0 30 00 00 00 00 00 00 00) to get the
remainder of the data bytes but our goal is only to see if this controller stores the VIN. If
we get a negative response (7E8 03 7F 02 12) then we know it does not and we and thus
we cannot change something that isn’t there.

So now we know the controller supports VIN, this is where things get OEM specific. So
in the interest of brevity I will give an example of setting VIN on a GM CAN BUS vehicle
(GMLAN).

GM employs the GMLAN diagnostic protocol for enhanced diagnostics. So you may
want to do some reading of the GMW 3110 spec (downloadable from IHS). So we know
how to read the VIN, but how do you write it. The VIN is stored in the controller as a Data
Identifier (DID). Service 3B is used to write DIDs. However as VIN is considered a
protected DID, you will need to “unlock” the controller using Security access first. But of
course you don’t have the security access algorithm do you? I didn’t think so. So we
must use a Brute Force technique to guess the correct Key to unlock the controller.

To brute force the Key you must send a Seed request to the controller (7E0 02 27 01 00
00 00 00). This request must be done first before you send a key. On GM the Seed is
static, it doesn’t change each time that it is requested. So this means we must increment
the Key one at a time until the controller responds back with a positive response (7E0 01
67). So let’s get cracking.

First send the Seed Request then send a Key (7E0 04 27 02 00 01; where 00 01 is the two
byte key). Most likely the first key you choose will not be the correct key for the
seed. So you will see a negative response from the controller indicating that we have an
incorrect key (7E8 03 7F 27 35). This will mean we must try again. But we know we have
the wrong key so add 1 to the previous Key (00 01 + 1 = 00 02). So send the seed request
and another Key request. Now we might get another negative response with saying
wrong key, but we might get a message stating that we have exceed the number of
attempts (7E8 03 7F 27 36). This would indicate that we cannot send any more seed or
key request until we have reset the power on the controller. So manually or
automatically, reset the power on the controller. Now we can try again. Send a seed
request, but this time check for a negative response from the request (7E8 03 7F 27
37). This means that the required time delay has not passed. Keep sending the seed
once or twice a second until the error goes away. This delay is an internal timer that acts
as a security method for brute forces the key. There is no simple way around it, so we
must endure it. When we get a positive response, then we send the key (7E0 03 27 02 00
02).

That’s it, we just loop through this until we get a positive response from the controller
after a key request.

Please not that in the worst case this could take up to 9 days! So you need to be a bit
patient. But once you have the Key it will work for this controller every time.
Unfortunately just this controller.

But now you have been able to successfully unlock the controller and you can now use
Service 3B to write the VIN. So make three messages that look like this:
7E0 10 13 3B 90 31 31 31 31
-- Wait here for flow Control frame (7E8 30 00 00) --
7E0 21 31 31 31 31 31 31 31
7E0 22 31 31 31 31 31 31 31

The 31’s are The VIN digits 1-17, the 90 is the VIN DID (On GM controllers) the 3B is the
service, the 013 is the length of the data in hexadecimal, and the 1, 21, and 22 are the ISO
15765 Diagnostic Layers.

If the VIN is written successfully then you should get a positive response:
7E8 02 7B 90

Let’s Chime In: GM 29 bit CAN Chime Control

For those of you who like to leave there car keys in the ignition while the driver door is open or
who don’t where a seat belt, you’ve heard the Chime and have probably cursed it many, many
times. Well I can help you defeat it or embrace it.

First you need to gear up. You will need to connect to the GM Single Wire CAN bus. This is on
PIN 1 of the DLC (OBD II port). SW CAN runs at 33,333 bps (standard rate). So once you
hooked up your device (see earlier posts for info on these), you should be able to communicate
with the vehicle over SW CAN.

So now you just need to know the message, but first a crash course in GMLAN 29 bit ID.

The 29 bit ID is broken into three pieces. The Priority, Parameter ID, and Source Address. The
priority is the first 3 bits of the ID. Priority allows for more important messages to get greater
access to the network in the case of high network congestion. This leaves 26 bits reaming of
the 29 bits. These are divided evenly amongst the Parameter ID and the Source Address (i.e.
13 bits each).

The Parameter ID is essentially the ID for what will be sent in the data portion of the frame. The
Source Address is the node that sent the message. So messages from the address 040 all
come from the same node. Cool huh!?

So let’s get to CHIME already…

Chime has a parameter ID of 0x0F. This means that if you want to send Chime you must put
0x0F starting at the 26th most signifigant bit. For example 0x1001E060 would be a chime
command (0xF) with priority 4 (0 is highest priority) and send from node 0x60. Its easier to
explain when we see this in binary. 0x0F is #b0:0000 0000:1111. So we put the whole ID
together by taking the priority then parameter ID then source address. This will give us
#b1:0000 0000:0001 1110:0000 0110:0000 (where the parameter ID is in bold).

Ok now that we’ve finished with the ID, let’s look at the data. The data portion is what is
defining all of the characteristics of the Chime. In other words will this be a long chime or a
short one, a click sound or a ding sound, a one-time sound or multiple times? There are 5 bytes
that define all of these characteristics. So you will see that you can do a lot.

The first four bits of the first byte (the most signifigant nible) defines the speaker that this sound
will come out of. For the front left speaker it is the most signifigant bit (or bit 7 of the byte). Next
is the passenger (bit 6), then the rear driver side (bit 5), then rear passenger side (bit 4). So if
you wanted to make the sound in only the driver speaker then you would send 0x8X in the first
byte (where X is irrelivent).

The second nibble of the first byte describes the type of sound it will be. Either a beep or a
click. Experiment to find out what these are.

The second byte describes the intonation of the chime. So you can adjust this on your own as
well.

The third byte is the amound of repetitions you would like the sound to make. So if you want
the chime to happen three times. This should be set to 3.

The fourth byte describes the duty of the chime. Experiment with this on your own.

Last byte is unknown currently. But if you know send me an email, I’ll update this entry.

So if you would like to send chimes to your car, here you go. If you want to cancel a chime, it
should be good enough to have your software wait for a chime command and simply send one
of its own with a really fast chime and a 0% duty cycle. That should end the last chime
command.

If at First You Don’t Succeed, Quit Trying

On most late-model cars, there are hundreds of messages with thousands of parameters being
transferred between controllers, this leads to the idea that EVERYTHING is being able to be
controlled by CAN BUS messages. This simply is not the case. If a controller doesn’t need to
send internal data to another controller then it won’t. Simple as that.

So why am I writing this? Because the biggest waste of time in reverse-engineering the CAN
BUS is looking for a command or a parameter that simply isn’t there. You need to have the
notion that everything is not available and sometimes you won’t find it no matter how much you
look.

So how do you determine how long to spend on looking for a parameter or command? Well the
answer, I think, depends on the importance of getting the parameter. I take the example of
trying to find Engine Speed on a CAN BUS. Engine Speed is nearly universally available on
today’s CAN BUS vehicles. It is usually simple to find and scale, so not much time is wasted,
but in contrast, Outside Air Temp may not be collected by a module on a car or may not be
broadcast by the controller that collects the data. In the first instance where it is not collected
there are ways to find this out before hand. You can look at publicly available wiring diagrams
that show (or rather do not show) that there is no Outside Air Temp sensor on any
controller. This will save you time and frustration.

In the case of commands sent over CAN BUS (i.e. Unlock from a key fob). These can be tested
by capturing all of the messages while you pressed the unlock button, then play those
messages back to the network one or two times to see if the doors unlock. Why does this
work? If the message was sent over the CAN BUS then by playing all of the messages back on
the bus you should have the same result as when you pressed the button such as any parking
light flashing, horn honking, etc. If you do then you know the message is broadcast over the
CAN BUS, if not then you can assume that it is most likely not available. If it is not available,
simply move on. You can try the process again one or two more times, but you probably did it
right the first time.

Scanning for Diagnostic Data.

Because diagnostic data is built on top of a standard Transport Protocol (ISO 15765-2), you can
use this knowledge to see which diagnostic service a particular vehicle supports and which
parameters or sub-functions it may support.

Step 1. Finding Nodes’ Diagnostic IDs.


We must first have all of the nodes enumerated with Physical IDs and their respective response
IDs (Note: sometimes there may be an ID that is a Functional ID. That means more than one
node will respond to request sent on this ID). To do this I usually send the Tester Present
Request (Service 0x3E) to each CAN BUS ID. If you are working with a 29bit system this may
be daunting simply because of how many possible IDs there are; you may have to find a
shortcut instead of request each ID. However on 11bit systems this is quite easy.

Start by sending tester present to ARB ID 0x001. This message would typically look like this:
0x001 01 3E 00 00 00 00 00 00 OR 0x001 02 3E 01 00 00 00 00 00. Try them both and see
which works. Next simply increment your arbitration ID by one: 0x001, 0x002, 0x003, …
0x7FF. You will know that a node has diagnostics on it because you will see a response from
the node after you send your request. You would typically see this: 0x7E8 01 7E 00 00 00 00
00 00. The 0x7E is the positive response to your 0x3E request (tester present). Write down (or
log) the request ID AND the response ID and save them for later. Essentially the request ID is
how you query the controller and the response ID is data you will get back from that specific
controller. Keep in mind that you may get some CAN BUS errors. This is to be expected, but
should not cause concern. You may also have some strange affects on the car such as a
windshield wiper move or blinker kick in. This is because you are sending data on the bus that
is interpreted by other controllers and you may have inadvertently activated another command.
Cool, huh?

Step 2. Finding Supported Services.


This can be a bit tricky only because some services may require a certain message length (i.e.
you may have to have 0x04 in the first data byte in order to get a positive response from the
controller), but this is usually not the case. In order to do this you must remember that the
service ID for a diagnostic command is found in the second byte (ARBID, B1, B2, B3, etc). So
your first request might look like this: 0x7E0 01 01 00 00 00 00 00 00, where byte 2 contains the
service. In this case we are not sending any protocol data. Diagnostic services are broken into
ranges. This is because the request IDs and positive response IDs don’t over-lap, and since we
are not interested sending the responses, we can remove the positive response IDs from the
services we will request. Service request IDs are as follows: 0x01-0x3E, 0x80-0xBE. (0x3F is
reserved, 0x7F is for negative responses and 0x40-0x7E and 0xC0-0xFE are reserved for
positive responses coming back from the ECU).

Now that we know what our range is, we can simply send a request and based on its response
we will know if this is a service that is supported. We send 0x7E0 01 01 00 00 00 00 00 00 and
we get back 0x7E8 03 7F 01 12 00 00 00 00. The response is a negative response because
there is a 0x7F in the second data byte. This tells us that there was a problem with our request,
but does NOT mean that the service is not supported. We have to look at byte 4 to see why our
request failed. In this case we got a 0x12 Negative Response Code (NRC). 0x12 means Sub-
Function not supported (please see list below for other NRCs). So it’s telling that the service IS
support but the sub-function (which we didn’t send one in this case) is not supported. In fact we
can ignore all NRCs except 0x11 and 0x78. NRC 0x11 means that the Service is Not
Supported. This gives us a definitive NO that we cannot use this service on this
controller. NRC 0x78 doesn’t tell us anything, yet. In fact it means Response Pending. It may
response later with another NRC or with a positive response. Other than a NRC 0x11, a simple
No-Response will tell you that the controller does not support your service. Simply waiting
around 100 milliseconds (ms) will be sufficient proof that the particular service is not supported
on your controller.

Step 3. Finding Parameters.


This is the most dynamic of steps. It requires some understanding of the service that you are
working with. For example, you may be using a service that has a sub-function or a service that
has a parameter and this parameter may be 1 byte, two bytes, three, etc. So you will have to
prepare yourself for a lot of negative responses (I hope you don’t fear rejection).
So here is what we do now, send our request but increment the bytes,
0x7E0 02 01 00 00 00 00 00 00,
0x7E0 02 01 01 00 00 00 00 00,
0x7E0 02 01 02 00 00 00 00 00, etc..

If you are getting positive responses back from the controller, then you have won. However if
the controller is sending back negative responses then you’ll have to adapt. For instance you
may get a NRC 0x22, this means “Conditions Not Correct, Sequence Error”. This NRC is
particularly vague. It typically means that you must send a Start Diagnostic command first or
that the key must be in the ignition, or that Venus and Mars must be in alignments. So you will
just have to work with what you have. But if you get a NRC 0x12, you will know right away that
this sub-function or this parameter ID is not supported by this controller and you can move on to
the next one.

As you can see the trick is to automate this process. To write each message and handle each
repsonse can be difficult.

NRC Long Name

$11 Service Not Supported

$12 Sub Function Not Supported - Invalid Format

$22 Conditions Not Correct Or Request Sequence Error

$31 Request Out Of Range

$35 Invalid Key

$36 Exceed Number Of Attempts

$37 Required Time Delay Not Expired

$78 Request Correctly Received-Response Pending

Network Management - Part 1: GMLAN

Most vehicles employ some sort of network management. This is typically for the Low Speed or
Body Network. The High Speed or Powertrain network will come alive when the key is in the
start position. But if you need to send an unlock command using your key fob and this is done
via a CAN Bus, then there will need to be a network management system to wakeup nodes and
allow them to go back to sleep.
The problem is that there are sooooo many ways of accomplishing this task. There is GMLAN,
OSEK, and many others. In general they may have nothing to do with each other, you will just
have to learn them all! So here is a start:

GMLAN Network Management:

GM uses network management on their Single Wire or Low Speed network in order to wake up
nodes that are in a low-current or sleep mode. There are essentially two events that must take
place to communicate with a sleeping node.
First you must wake it up by sending a High Voltage Wake-Up. On single wire CAN the
physical layer is typically an active high, 0-5V line. This means that if you were to watch normal
traffic on an oscilloscope, you would see 0 Volts for low values and 5 Volts for high values; but
when a node is sending a high voltage wake-up now the high values will be at 12 volts (rather
Vbatt which may be as low as 9 Volts or as High as 16 Volts). Although it doesn’t matter what
format this message is, it is typically the message with Arbitration ID 0x100 and has NO
data. This lets the sleeping nodes know that they need to wake-up. An awake node may or
may not be listening to command information just yet. Most nodes require another “Wake-Up”
to send data to them.
Second you must send the Virtual Network Management Frame (VNMF). This message is
designed to wake-up particular virtual networks or groups of nodes that are associated through
common systems such as lighting control or entry systems (i.e. doors). So if I wanted to talk to
door module to unlock the doors I would wake up the virtual network for doors. The problem is
of course, I have no way of knowing the networks without a proprietary list which I don’t
have. So instead of worrying about which virtual network to wake-up I will show you how to
wake them ALL up. To wake up ALL virtual network it’s as simple as sending the following
message: 0x621 01 FF FF FF FF 00 00 00.

So why does this work? ALL VNMFs have a range of 11 bit IDs (even on 29-bit networks).
0x620-0x63F are reserved IDs for VNMFs. So you can use ANY ID within that range and it will
be interpreted as a VNMF by all nodes. The ID is the source node. In this case $621 is from
the Body Control Module. The First byte of a VNMF is either 0x00 or 0x01. 0x01 means Initiate
the following Virtual Network(s) (VN) and 0x00 means Continue the following VNs. The next
three or four data bytes contain a bit encoded list of each VN where 1 means wake-up and 0
means nothing. So if you send 0xFF this is essentially saying wake-up to the eight VNs that are
encoded in that byte.
This method is like using a blow horn to wake-up the nodes. Each node will hear it and wake-
up. If you want to be more subtle and only wake-up the VN your are interested in, then you can
go bit-by-bit and find your VN it should take too much time either as there may only be around
20 VNs at most on any particular vehicle.

A VN will stay awake for up to 3 seconds after the first message was called. So if you want to
keep the network awake you must constantly send the Continue frame $621 00 FF FF FF FF 00
00 00.

To summaryize here is the VNMF format:

Format: ArbID, B1, B2, B3, B4, B5, B6, B7, B8


As Seen: $620-$63F, 01 or 00, XX, XX, XX, XX, 00, 00, 00 (Where XX = Some bit-encoded
value where each bit represents a single VN).

oh and ALL VNMFs MUST BE 8 BYTES IN LEGTH!


Network Management - Part 2: OSEK

Let me start out with this statement: my OSEK skills are decent, but I’m not the foremost expert
here. I will tell you what I know and leave it up to you to belittle me in the comment
section. Thank you.

The OSEK standard is a large section of documents that cover many, many aspects of CAN
BUS communication, Network Management is a small section of this entire cadre. The entire
document can be purchased publicly, I just don’t remember how. The Network Management
section (2.5.3; available for free download here) is 130+ pages and is a riveting tale of bits and
bytes. So let me tell you about some of the highlights…

OSEK Network Management (NM) primarily works by passing a ‘token’ around a logical
‘ring’. This token is simply like passing a one byte message to your neighbor and then your
neighbor passes it to his neighbor and so on until it comes back to you and you start the
process all over again. The key here is what does the message token mean? At first the
message token just broadcasts your network management ID. For example if your CAN BUS
Arbitration ID is 0x420 your NM ID would be 0x20 (the lower byte of your Arb. ID). Each node
on the bus would have its own NM message. So if you have five nodes you would have five NM
messages all of them within a particular range (this range is specified by the OEM not OSEK).

Once the node has sent out its ID, it starts listening for other NM messages (it knows of other
NM messages because these messages will be in a particular range of Arbitration IDs). Once a
certain time has elapsed it will send a token to its neighbor. This might look like this: 0x420 21
12 00 00 00 00 00 00 00 00. Where the 0x21 is its neighbor’s ID and 0x12 is the token. Once
the neighbor has received his message, he will in turn send his own NM message with his own
token: 0x421 26 32 00 00 00 00 00 00. Where 0x26 is the next node ID in the ring and 0x32 is
the token. And then the cycle would continue, where each node passed their token to the next
node and so on.

The token is encoded data that indicates the node’s desired state for the network. For instant if
the network should go to sleep, nodes that wish for sleep will turn on an “enable sleep” bit in the
token. If all of the nodes enable this bit, then the final node to elect for sleep will then send the
“sleep network” bit and the network will go to sleep. This sleep is only temporary until another
message is sent, this will initial a network wakeup and NM messages will start broadcasting with
a token that indicates this message is an Initialization message.

So the key to a NM message is how the token is decoded and this is not specified by the OSEK
layer but rather by the OEMs themselves.

Oh no, Odometer: Reading and Righting… er, Writing.

A legal requirement in most countries, including the U.S., odometer is the measure of the
distance your vehicle has traveled. Possibly, this is to aid sellers of the car in appraising the true
market value of the vehicle.
Many people have requested if there was a way to modify this value so that they could increase
the value of their vehicle correct their miscalculated Odometer and as you can imagine, this is a
very difficult task. Similarly I have had request on how to simply read this parameter from the
CAN Bus.

First off let me just note that changing or rolling back your odometer is technically not illegal. If
you wish you can modify this number without penalty (Don’t listen to me I’m not a lawyer).
However when it comes time to sell the vehicle you must properly report the true odometer
reading by placing a tag on the inside driver’s door along the side. This is because device that
displays the odometer could go bad and could need to be replaced. In some cases, this means
that the odometer value is reset back to zero. When this happens the installer will typically add
this tag with the old odometer value and legitimize the install.

So how do you modify an existing odometer? The answer depends firmly on the vehicle that
you are attempting to use. This means that some vehicles are moderately difficult and others
unbelievably impossible. There are a handful of tools available for technician. If your engine is
replaced, in some cases you may be able to reset the odometer. So for this event a technician
will have a specialized tool designed to connect to the controller or controllers that may store
the odometer’s value. This tool, through some secure method, will modify the odometer data
that is stored on the controller(s). Of course these tools are difficult to find, cost upwards of
$2,000 for one unit, and typically only work for one manufacturer. So they are not very
accessible.

So what if you only want to read the odometer from the network? There are a handful of
applications that could use the odometer’s value as an input. For instance, automotive
insurance companies around the globe would like to create a more equitable method for
charging rates. In some cases they can install a data logging device into your vehicle and
measure the distance that you typically travel. Like your electrical bill, these devices would allow
you to pay for only what you use. In the case if you drive a shorter distance you will pay less
than another person who drives more than you. This pay-per-mile or pay-per-kilometer idea
could give a particular auto insurance agency a competitive advantage for those who commute
less and could prove it.

Sadly odometer is not an OBDII legislated PID. This means the federal government does not
require OEMs to have this information available to the general public via vehicle diagnostics. So
you if you wanted odometer you would have to find it. Like other similar data, odometer may or
may not be available via an enhanced diagnostic command and if it is available its ID and
request method is not required to be publicly available. So if you want to find it you’re going to
have to roll up your sleeves, get out your CAN Bus Hacking tool and start reverse engineering.

So what are you looking for? If it is available, odometer could be obtained in one or two different
ways: Enhanced Diagnostics or Normal Messages (data that is sent without a request). This
means we have two vectors (cool buzz word I learned at defcon) (I’m probably using it wrong)
that we need to explore.

Getting Odo via Diagnostics:

As stated in some of my previous blog entries, Enhanced Diagnostics is a Command/Response


protocol that allows you to “ask” the controllers for data. This is the preferred method as we can
control when the data is broadcast on the network simply by asking. So let’s assume we know
nothing about how this request is going to look, Enhanced Diagnostics must follow a very
specific format for it to be effective. This message format is based on the ISO 15765-2
specification (CANBUSHACK.com: ISO-15765 ). We must also have made a list of command
Request IDs (a.k.a. Node IDs) and Response IDs (CANBUSHACK.com: Scan for Diagnostic
Data). Once we have the IDs for each node we must now find a list of valid PIDs (Parameter
IDs). PIDs are typically a representation of a single parameter for example PID 0x0C in OBDII
diagnostics is the Engine Speed data request. So we are looking for the PID that belongs to
Odometer…
So let’s take a big step back and narrow down the list of possible Services that may be used to
request a parameter like odometer. This list is essentially vehicle specific and is not necessarily
published anywhere so you will have to have some experience with this to narrow the list. If you
don’t then your effort will take a bit more time, but it isn’t impossible. Typically PIDs are
requested using the following services: 0x1A, 0x22, and 0x21. Now it’s important to know one
thing before we continue: what is the PID size (in bytes) that the controller is expecting. This is
typically one or two bytes. For example service 0x1A on GMLAN requires the PID (actually they
call it a DID) to be 1 byte in length whereas, the service 0x22 on GMLAN requires two byte
PIDs.

Now that we have a small list of possible services, let’s start with them (Tip: Services are
essentially functions that you are requesting the controller to perform). Let’s assume that we
have a controller that has a Diagnostic Request ID of 0x734 and a response ID of 0x744, I want
to send 0x734 03 1A 01 00 00 00 00 00 to the controller. Translation: Function 0x1A, PID 0x01.
Now we are hoping for the following positive response from the controller: 0x744 06 5A 01 00
02 03 04 00 where the 0x5A is the positive response to our 0x1A request (Recall: Service ID
plus 0x40 = positive response) and 0x06 lets us know that the data coming back is going to be 4
bytes (why not 6? Because 0x06 includes the service ID response and the PID Echo). 4 bytes is
very promising when looking for odometer because chances are we will need this size to be
large enough to store all potential values of odometer including possibly scaling it to the 10ths
or 100ths of a Mile or Kilometer. 0x01 is the PID that we requested and 0x00020304 is the four
byte response data we received.

Odds are that odometer will likely be stored in a large number of bytes because typically the
odometer will need to be an overly large number just in case. 4 bytes = 8 bits * 4 = 32 bits;
Upper Limit is 2^32 = 4,294,967,296. Why so big? I don’t know, maybe it’s scaled so the upper
limit will be smaller.. But in this case if we rescaled 4,294,967,296 to X/100, this would allow us
more granularity of the odometer value itself. Now let’s look at our vehicle’s odometer value on
the dash display. We’ll assume it reads 824 Miles. The first thing we that must do is change this
value to Kilometers. The metric system is an absolute when dealing with data on the CAN
Bus (mostly :). So this is approximately 1,318.4 KM. Now let’s convert the data we got back
from our controller from hexadecimal to decimal. 0x00020304 = 131,844. So now we simply
take the observed data from the CAN Bus and see if there is some correlation to what we saw
on the dash and of course we can see this one is quite easily: 131,844/100 = 1,318.4 KM. Now
we must hope this isn’t some strange, strange coincidence and we’ll mark this one down in our
book as solved. If we have a chance to validate this on another vehicle this may be ideal.

But what would happen if the controller didn’t send a positive response? Nearly 90% of the time
the controller is going to say that you have requested a non-existent PID these responses can
take many forms but they will always have 0x7F in the second data byte. A typical negative
response would look like this 0x744 03 7F 1A 30 00 00 00 00. This follows the ISO 15765
protocol for negative responses and in this example 0x30 is the NRC (negative response code).
This code is a clue as to why the data was rejected. Be careful, because sometimes the NRC
may be telling to send another message before you request a PID and NOT that you have a
bad PID. So pay close attention to the NRC and again take a look at my ISO 15765 post to view
a list of NRCs.

Now that we have the Odometer we should be able to read it any time we want. This allows us
full control of when we get the data, but there is a possibility that we won’t be able to find it
using this method. We may want to find a factory scan tool (not an easy task at all!) and see if it
can request odometer from the vehicle. If it can, then we need only monitor the request and
simulated it by connecting our CAN Bus tool at the same time as the scan tool (OBDII Y-splitter
is recommended, obdiicables.com).

Getting Odo via Normal Messages:

Like in our previous example, we are going to be looking for a parameter; the difference is we
are essentially looking for a needle in a needle stack. The needle is the odometer and the stack
is a lot of other data parameters that are being broadcast by a handful of controllers.
So let’s take a second to figure out how we might narrow the list of possible candidates. First,
since we are probably in a stationary car, the data should not be changing. So filter out any
changing data. Second, the data should be a non-zero value about two to four bytes in length.
Third, the data will have to have some type of correlation with odometer value that we see on
the dash. The smaller the width (in bytes) of the odometer parameter that we find the more
likely that there is some type of scalar associated with it. These scalars may be something like:
x/10 or even x*10 or more likely x*2^y (where y could is typically between -4 and 4) or simply
x*1. Try to run each possible hit through each possible scalar; this should yield the best results.

Simulate THIS!

With thousands of data parameters flowing continuously along one or more CAN Buses in any
particular vehicle, there is no doubt that finding out what these parameters mean can be very
benificial, but, in having the data, you can also use it to simulate what is there.

So why would you want to simulate what is ALREADY there? One, because you want to get rid
of what is there and add something of your own. Removing the engine and engine controller?
No problem just simulate it, the other modules probably wont care. Removing the driver or
passenger seat, no problem just simulate it, the other modules probably wont care.

Or two, you want to enhance the functionality of existing controllers. Want the doors to auto-lock
at 2mph not 5mph? No problem simulate the lock message, the doors won't mind. Want to have
the vehicle chime all the time while the seat belts aren't buckled, no problem simulate the
chime.

So how does simulation work? Typically, you will need to look at the message(s) that you want
to simulate. What is there Arbitration ID? What is there data length? Is the data static or
dynamic? Is it sent periodically, on event, or both? If you send the message and do not remove
the original controller that is sending the message are the desired results nullified by the original
controller (i.e. if you are sending head lights ON and the original controller is sending head
lights OFF, do the headlight turn ON, OFF or flicker?) ?

Once you've answered these questions, then you are ready to begin. So what was the
Arbitration ID? Let's say it was 0x555. Ok now what's the data length? 8 bytes with static data,
sent periodically at 100ms update rate.

Let's assume this message is a command that moves the driver mirror up when we change the
first byte from 0x00 to 0x01. So the message on the Bus looks something like this: 0x555 00 00
00 00 00 00 00 00. But if we send our simulated message of 0x555 01 00 00 00 00 00 00 00 the
mirror will move up just a smidge and if we send it at 100ms it will continue to move up until we
stop sending or we change the first data byte from 0x01 back to 0x00. However we may notice
that the upward movement of the mirror is not as smooth as when I press the up button of the
mirror control switch. This is because you are simulating a message that is already present on
the CAN Bus. This means that the receiving controller is receiving your message 0x01 and the
original controller's message 0x00 and interpreting an Up command when your message arrives
and a Stop command when the original controller's message arrives. Depending on how well or
bad the software for the mirror control module is written, this may cause havoc on the system
you plan to implement, and will most definitely be the source of many CAN Bus Error frames
(don't worry there not too bad, in general it is almost impossible to cause any issue when
simulating an existing CAN Arbitration ID).

So, in this instants, if we want to make the control as smooth as the original switch, we must
stop the existing controller from sending the message. There are a couple of ways to do this,
the first is obvious, disconnect or power-down the original controller. Remove a fuse, disconnect
the CAN Bus or power from the controller. Now of course this will most definitely have other
symptoms, but if your application can tolerate this, then its the easiest and simplest solution.
Next to physically disconnecting the module is using diagnostic messaging to ask the module
the stop sending. Often called Disable Normal Communications. If supported, this service will
make the module stop sending its data. The problem is that the message format and rules are
typically quite different from vehicle manufacture to manufacture, so unless you know what this
message is, it is difficult to make this work. Plus this method suffers similar draw-backs as the
power-down method mentioned above.

Last, you can gateway the message. Gatewaying the message is done by disconnecting the
sending OR receiving module (typically easier when it is the receiver). Once disconnected, you
can gateway all of the message to the receiving module EXECPT the one that you want to
simulate. This allows you to have complete control over the data in that message while
maintaining the messages and data from other modules. As you can imagine this solution
requires the most work because you must have a device that is fast, support at least two
identical CAN Bus channels, and is quickly programmable. But if you can get these three things
together, you will can simulate nearly any message with nearly zero issues.
Extended IDs in CAN Frames.. What will they think of next?

Every CAN message has an Identifier. This is referred to as the Arbitration ID or ArbID. It
serves two functions. First, it is to help identify the payload or data of the frame. Second,
because no two modules are allowed to send a frame with the same ID, it serves as an
arbitration method on which frame gets priority on the bus when two or more messages are sent
at the SAME TIME (in other words if a low priority ArbID frame is half-way through sending, a
higher priority ArbID will not stop that frame from sending).

So if the ArbID is the identifier of the message, what are Extended IDs? The concept is simple,
take the ArbID and add data bytes from the frame as the ID as well. For instance, say you have
to messages you want to send: Engine Speed and Engine Coolant Temp. A lot of the time you
will see them sent in the same message with the same ID and always in their same respective
location in that message. However what if you wanted all of your parameters to occupy byte 5
of every frame, and instead you change out the ID to denote the parameter, but because of
application rules you are only allowed to broadcast on a single ID? In this case you would use
Extended IDs.

For example your only ID you are allowed to send is ID 0x444 (again this is because of rules
imposed by a network design committee not by CAN Bus itself). And you have more data than
one frame can possibly hold or you want all of your parameters to be in the 5th byte? In this
case you may set byte 1 as your Extended ID and for each parameter you would assign a new
ID. So Engine Speed would be 0x0C and Coolant Temp would be 0x05 and Engine
Parameter X = 0x06, Y=0x07, etc.

Your Engine Speed Frame would look like this: 0x444 0C 03 00 FF 22 00 00 00 00; where
0x22 Is the engine speed. And for Engine Coolant Temp it may look like this 0x444 05 04 00
FF 10 00 00 00 00; where 0x10 is the Engine Coolant value. So you can see that if you have
certain limitations on network IDs, Extended IDs can give you more versatility.

Extended IDs can also be seen in Diagnostics messages as well. For instance Toyota vehicles
often use Extended IDs for Diagnostic Requests and Responses. A typical Enhanced
Diagnostic Request on Toyota vehicles starts with 0x750 and the first data byte is the
Destination Controller Address. Compare this with an OEM that does not use Extended IDs,
but rather assigns each ECU Destination address its own Arbitration ID (Ford, GM, Chysler,
etc.) The more controllers you have the fewer available Arbitration IDs would be available
because they would be taken by Diagnostic Identifiers.

Now you know what some applications are for extended IDs and know that you know, it should
be easier for you to identify them when reverse engineering data on the CAN Bus.

Service(s) Please
In diagnostic messaging, services are the functions. Think of each command as a
sentence. The service is the verb. In standard OBDII services are often referred to as
Modes. You can also think of them as functions to be performed by the controller(s) that you
are commanding.
With diagnostic messages, there is always a command and almost always a response from the
controller(s) you are commanding.
When looking at raw CAN Bus data the service is often the second, third, or in very few cases
the fourth data byte of the message. In nearly all cases, OEMs will implement ISO 15765-2
(Click Here to read about this protocol). So the service will be the first byte after the Transport
Protocol information.

Here is an example of and OBDII message to get Engine Speed using the CAN Bus ($01 is the
Service):
$7DF 02 01 0D 00 00 00 00 00

Will hopefully return the following:


$7E8 04 41 0D 01 FE 00 00 00

Here is a simple list of some common Services that you might find:

OBDII Services (a.k.a. Modes):


$01 - Request Current Powertrain Diagnostic Data
$02 - Request Powertrain Freeze Frame Data
$03 - Request Emission-Related Diagnostic Trouble Codes
$04 - Clear/Reset Emission-Related Diagnostic Information
$05 - Request Oxygen Sensor Monitoring Test Results
$06 - Request On-Board Monitoring Test Results for Specific Monitored Systems
$07 - Request Emission-Related Diagnostic Trouble Codes Detected During Current or Last
Completed Driving Cycle
$08 - Request Control of On-Board System, Test or Component
$09 - Request Vehicle Information
$0A - Request Emission-Related Diagnostic Trouble Codes with Permanent Status

Services $10 and higher are non-OBDII services also known as Enhanced Diagnostics. This is
because, unlike OBDII Diagnostics, these services are not government mandated thus each
OEM will use their own specification. For Example GM vehicles use the GMLAN diagnostic
protocol. Ford used ISO-14230 but now use ISO-14229 (UDS). Each OEM is can decidedly
use their own enhanced diagnostic protocol.

GMLAN Enhanced Services:


$10 - Initiate Diagnostics
$12 - Read Failure Record
$1A - Read Diagnostic ID (DID)
$20 - Return To Normal
$22 - Read Data By Parameter ID (PID)
$23 - Read Memory Address
$27 - Security Access
$28 - Disable Normal Communications
$2C - Define Dynamic Data Packet ID (DPID)
$2D - Define PID by Memory Address
$34 - Request Download
$36 - Transfer Data
$3B - Write DID
$3E - Tester Present
$A2 - Report Programming State
$A5 - Enter Programming Mode
$A9 - Check Codes
$AA - Read DPID
$AE - Device Control
Here is an example of a CAN Bus message to get the Engine Speed using Enhanced
Diagnostics (where $22 is the service):
$7E0 03 22 00 0D 00 00 00 00

And this will hopefully return:


$7E8 04 62 00 0D 01 7E 00 00

ISO - 14229:
$10 - Diagnostic Session Control
$11 - ECU Reset
$14 - Clear Diagnostic Information
$19 - Read Diagnostic Trouble Codes (DTC)
$22 - Read Data by ID
$23 - Read Memory by Address
$24 - Read Scaling Data by ID
$27 - Security Access
$28 - Communications Control
$2A - Read Data by Periodic ID
$2C - Dynamically Define Data ID
$2E - Write Data by ID
$2F - Input/Output Control
$31 - Routine Control
$34 - Request Download
$35 - Request Upload
$36 - Transfer Data
$37 - Request Transfer Exit
$3D - Write Memory by Address
$3E - Tester Present
$83 - Access Timing Parameter
$84 - Secured Data Transmission
$85 - Control DTC Setting
$86 - Response on Event
$87 - Link Control

Now that you have a list of Services, hopefully this will make reading the raw can data a bit
more manageable. Soon I will post more information about specific services themselves. If any
are more interesting to you, please post in the comments below.

Common Diagnostic Services

Because diagnostics is really just a simple way to interact with an ECU, there are a few very
common diagnostic services that you’ll find in nearly every permutation of diagnostics.

Tester Present:
Definitely the most common service you’ll find, tester present (typically 0x3E) is used to let the
controller(s) know that there is a.. wait for it.. Tester present. I know it was a bit obvious, but the
idea is that some services keep the controller in an augmented state or a diagnostic
state. When this happens there needs to be some way of maintaining that state while the tool
that initiated the state is still connected to the diagnostic connector.

So Tester Present is designed to be a heart beet of the diagnostic tool and in the event that the
device stops working or is disconnected from the network, the ECU whose state has been
altered will stop seeing the tester present message and thus transition out of its altered state.

So if you want to maintain a diagnostic state you should send the tester present message. A
typical timeout for Tester Present is 3 Seconds. So as long as you send the message between
1 and 2.5 seconds, you will be able to maintain the diagnostic state of a controller.

Read Data by PID:


Reading data from a controller is pretty much the reason for diagnostics in the first place. So
there is no surprise that there are at least two ways to accomplish this task on nearly every new
vehicle on the market today. Services 0x01 and 0x22 are used for this purpose.

Service 0x01 is the OBDII Read data by PID (Parameter ID) where the PID is a one byte
number representing the data you want to read. Service 0x22 is the Enhanced diagnostic
method for reading data. Service 0x22 is typically a two byte PID that represent the parameter
you want to read. In some cases this two byte parameter may also be used in conjunction with
another Enhanced diagnostic service to write the data as well (however exactly how this is done
varies).

Security Access:
Controllers contain data that manufactures do not want just anyone having access to. This is
typically to stop strange people such as yourself writing data to the controller to modify how it
performs. So in nearly every controller there is a method to “unlock” the data. To perform this,
it is done with service 0x27, the security access service.

In order to “unlock” the controller you must first ask it for a Seed. This seed will be used in
conjunction with a proprietary algorithm to generate a Key. Then the key will be sent back to
the controller. If the calculation that the controller did is the same as the key that you sent, then
the controller will send a positive response indicating that the controller is now unlocked.

There may be several levels of Security Access. This is due because they may want certain
features available to one group of people such as locksmiths who may need to add a new key
to the vehicle while still keeping the other levels secure. So a typically Security Access
transaction will have sub-functions that will essentially be the level that you wish to access,
these sub-functions operation in Odd/Even Pairs. So sub-function 0x01 will be the seed request
and 0x02 will be the key response. Then it’s 0x03/0x04, 0x05/0x06, … 0x21/0x22, etc.

That’s pretty much all that is very similar across all of the diagnostic protocols. Once you’ve
learned these three services, you find that they very similar.

Fun Diagnostic Services!

Some services are boring.. like really, really, really, boring.. but others can make the car move
gauges or make the car’s warning lights light up. Here is a bit more about these types of
services.

Stop Normal Communications (GMLAN and Others):


This service is fun because you can make the Normal Communications (the ECU to ECU
communications that occurs normally on the network) stop. Why would such a service exist,
mostly to clear the bus for large amounts of data such as when a controller is going to be
reflashed over the CAN Bus. On GMLAN this service is 0x28. It does not require any sub-
function so an example of this might be: 0x7E0 01 28 00 00 00 00 00 00. This will command the
engine controller to stop sending normal communications. Of course you don’t ever want to do
this while the car is being driven, but it’s pretty fun to see what happens when you do it!

You will see the Engine Controllers Normal messages virtually disappear. I say virtually
because not all messages will go away, some that are mission critical will stay, but a lot of them
will not.

This service can also be useful if you want to simulate the messages the ECU would send
without removing the power to the controller or cutting the CAN Bus itself.

This service requires that you continually send a Tester Present (0x3E) message periodically (2
seconds is good) in order to maintain this. If you want to return the communications send a
Return to Normal message (0x20): 0x7E0 01 20 00 00 00 00 00 00. This will restore
communications. Or simply stop sending the Tester Present message and it will automatically
restore communications after 3 seconds. Oh what fun you’ll have.

Input/Output Control (ISO 14229 – UDS):


This is pretty much the coolest services ever made. I/O Control is exactly as it sounds, you can
command Outputs on the Module to do your bidding. Of course software control will limit your
bidding to a safe and secure bidding, but it’s still cool.

I/O Control (Service 0x2F) requires 3 parameters: a DID (Data ID), Control Record, and Control
Mask. The DID is a two byte ID for the output (or input) you want to modify. Control Record is
what you want the output to do (On/Off, Up/Down, etc.). Control Mask is a bitwise mask of one
or more parameters that will be modified. An Example of a I/O Control is something like this:
0x7E0 06 2F 11 22 07 01 00 00 00. Where 0x1122 is the DID, 0x07 is the Control Record, and
0x0100 is the mask. This is not a real function, but you could potentially iterate through all
possibilities and wait for the controller to give you a positive response. It would take a while, but
it’d be interesting to see what happened…. Right!?

It’s likely that you will get a negative response from the controller 0x7E8 03 7F 2F 13 00 00 00
00, where 0x13 is the Negative Response Code (NRC).

Here are a few possible NRCs you may receive:

• 0x13 – Incorrect Message Length or Invalid Format.


• 0x22 – Condition Not Correct.
• 0x31 – Request Out of Range.
• 0x33 – Security Access Denied.
• 0x80-0xFF – OEM Specific.

Security Access or 0x27 Ways to Have Fun

So vehicle manufacturers don’t like you… why? Because they know you want to modify your
car in ways they never intended. They know you want to break your car and make them fix it
under a warrantee claim. They know you want to Hack your car and make it do fun things. So
they put in place a service that will deter you from accessing privileged functions on your
vehicle.

What are these functions? Things like reflashing a controller. Not just anyone should be able to
do this. Resetting the Odometer. Accessing control commands that would potentially stop a
vehicle from functioning properly.

How do they stop you? Security Access a.k.a. Mode 0x27. This is the service that validates an
application is authorized to do one or more of the privileged functions.
So how does it work? Well it varies a bit from OEM to OEM, but they all typically work the
same. First you must be in a diagnostic mode (not all OEMs require this, but many do). So you
have to use Service 0x10 – Start Diagnostics.

Start Diagnostics will typically take a Subfunction. This Subfuction tells the ECU which Level of
Diagnostics it needs to go into. Some OEMs have two or three levels of Diagnostics:
OBDII/Standard Diagnostics, Reflashing, and Enhanced Diagnostics. These subfunctions vary
widely depending on the OEM so you’ll have to poke around to find out which your vehicle
supports. Some good ones to try are 0x01, 0x02, 0x03, 0x80, 0x81, 0x82, 0x90). I’ve found
these to be common. So an example is this: 0x7E0 02 10 82 00 00 00 00 00. If done correctly
you will get back this: 0x7E8 02 50 82 00 00 00 00 00. If not you will likely get this 0x7E8 03 7F
10 12 00 00 00 00 00 meaning that the Subfunction is not supported, so you’ll need to try
another. You might just want to increment through the entire range of 256 possible subfunction
levels. Once you’ve found one that works, you can move on.
So Security Access is a Seed/Key authentication method. First you request a Seed from the
ECU then you calculate the appropriate Key response then send it back to the ECU. Of course
you likely don’t have the appropriate algorithm to successfully calculate the Key. So you may
need to brute force it. (I’ve spoke about this in an early post, but I’m going to reiterate it here
with some more general examples).

Brute forcing the key will take a while. How long? Well that depends on how wide the Key is (is
it 2 bytes wide, 3 bytes, etc.). How do you know how wide it is? You have to make an
educated guess. You do this by seeing how wide the Seed is. You know this by requesting the
Seed from the controller (I’ll go into how to do this in a bit). So if the Seed is 2 bytes, likely the
Key is too. If the Seed is 4 bytes or larger, the odds that you’ll be able to brute force it in any
reasonable time is unlikely as manufactures add some simple steps to slow down the brute
forcing method.

So how do you request a Seed? Send this 0x7E0 02 27 01 00 00 00 00 00 (do this within 3
seconds of the Start Diagnostics command). You should get back a Seed in the response:
0x7E8 04 67 01 XX XX 00 00 00 or 0x7E8 05 67 01 XX XX XX 00 00. Remember that the 0x04
indicates that the Seed will be two bytes wide (two bytes for the control information and two
bytes for the seed) and 0x05 means the Seed will be three bytes wide. Also, you don’t have to
send 0x01 as the subfunciton, but all Seed request have odd numbers (except 0xFF) as the
subfunction. This is how you differentiate from a Seed Request from a Key (Key requests are
even numbers and must be x+1 where the Seed request subfunction is x).
Now you have a Seed, that’s nice. But you have no way of calculating the Key so why even
bother asking for one? Why not just send the Key? Because you can’t, you must ask for a
Seed before you can send a Key. The system requires it.

Now you need to send the Key.. but wait not yet. Because there is one thing you need to
determine first. Is the Seed static or dynamic? You want to know this because this will let you
know if you are going to increment your key or not. If the Seed is static, then you’ll need to
change the Key when you are brute forcing the system. If the Seed is dynamic, then you’ll want
to keep the Key Static. So send another Seed Request. Did the Seed change? If so it’s a
dynamic Seed. If not it’s static.
Now we need to send a Key. To do this we send 0x7E0 04 27 02 XX XX 00 00 00, where XX
XX is the Key (remember 0x02 subfunction is x+1 of the Seed request). Likely we will get a
negative response because the odds of us guessing the exact Key for the Seed we received is
1/(2^key width). So if key width = 65536 then we have a 1/65536 chance of getting it
right. Now if we increment through all possible Keys then our odds of getting the response
approach 100% quickly (see the birthday problem). But if the Seed is dynamic we don’t want to
increment the Key. So this is a much different problem.

However those pesky engineers at the auto manufactures thought of this brute force method
and took some steps to slow us down. How? By making it so that we after 3 or 4 attempts we
get locked out. How do we know that we’ve reached this condition? They let us know by
sending this: 0x7E8 03 7F 27 36 00 00 00 00. Which means “Exceeded Number of Attempts.”
This means we have to someone reset the controller so we can try again. This can be achieved
by either cycling the power. You can do this by finding the fuse for the controller and simply
pulling it. Now this could be cumbersome so you may want to automate it using your favorite
open source embedded controller. Or we may be able to reset it using the ECU Reset Service
a.k.a. Mode 11.

ECU Reset is the funnest service ever… because it allows you to tell a controller to cycle its
power. (Don’t try it while you are actually driving bad things may happen……). The problem
with ECU Reset is there are so many different permutations of it, it’s hard to describe
universally. So you’ll have to do some experimenting on how your vehicle has it
implemented. But here is an example of how it may work: 0x7E0 02 11 01 00 00 00 00
00. Because you did a reset, you may not get a response from the controller at all if you did it
correctly. However if it didn’t like the request, it will give you a negative response 0x7E8 03 7F
11 XX 00 00 00 00, where XX is the negative response code. You’ll have to parse the code
know how to handle the exception. If the NRC is 0x12 just keep trying all subfunctions until one
of them works.

Once you’ve reset the controller, send another Seed request. If you still get “Exceeded Number
of Attempts” as a response. Then the reset didn’t work. Keep trying more subfunction of the
reset command until you’ve exhausted them all. If still no luck, you’ll have to do a hard reset of
the power to the ECU (pulling the fuse). Now try to send another Seed request. Likely if you do
this quickly (within 10 or so seconds of the ECU powering up), you’ll get another negative
response, 0x7E8 03 7F 27 37 00 00 00 00, “Required Time Delay Not Expired.” Meaning that
you have to wait a few seconds longer. Keep trying until this error goes away. This is just
another way that the manufacturer has made it difficult for you to brute force the
system. Because of this delay, the brute force will take much longer. But if you’re motivated
you’ll eventually get there.

How will you know you’ve got it? You’ll see this: 0x7E8 02 67 02 00 00 00 00 00. Then you can
be sure. And if you missed that message you can always send another Seed request. If you
get Seed of Zero that means that the ECU security is bypassed.

Don’t let the window close. If you want to keep the ECU “unlocked” then you’ll need to maintain
this state. To do this simply keep sending a Seed request or better, send a Tester Present
message: 0x7E0 02 3E XX 00 00 00 00 00, where XX is the subfunction (you’ll have to test this
first to see what works) or 0x7E0 01 3E 00 00 00 00 00 00.

You might also like