OBD#
Protocol Basics of OBD (SAE J1979)#
On Board Diagnostic
Different communications ways, we only care about CAN based communication
OBD uses ISOTP as transport layer protocol
10 diagnostic services can be used for data gathering
OBD can only readdata from ECUs
OBD standard request ID 0x7DF (0x18DB33F1), response ID 0x7E8 (0x18DAF111)
OBD Services#
OBD in Scapy#
Load contribution layer
load_contrib("automotive.obd.obd")
Craft request
pkt = OBD()/OBD_S01(pid=0)
Create a socket
load_contrib("isotp")
socket = ISOTPSocket("can0", tx_id=0x7E8, rx_id=0x7DF, basecls=OBD)
Send request to query for supported PIDs
resp = socket.sr1(pkt)
resp.show()
###[ On-board diagnostics ]###
service = CurrentPowertrainDiagnosticDataResponse
###[ Parameter IDs ]###
\data_records\
|###[ OBD_S01_PR_Record ]###
| pid = 0x0
|###[ PID_00_PIDsSupported ]###
| supported_pids= PID20+PID1F+PID1C+PID15+PID13+PID11+PID0F+
PID0E+PID0D+PID0C+PID0B+PID07+PID06+PID05+
PID04+PID03+PID01
socket.sr1(OBD()/OBD_S01(pid=0x20)).show()
###[ On-board diagnostics ]###
service = CurrentPowertrainDiagnosticDataResponse
###[ Parameter IDs ]###
\data_records\
|###[ OBD_S01_PR_Record ]###
| pid = 0x20
|###[ PID_20_PIDsSupported ]###
| supported_pids= PID40+PID34+PID33+PID31+PID30+PID23+PID21
socket.sr1(OBD()/OBD_S01(pid=0x40)).show()
###[ On-board diagnostics ]###
service = CurrentPowertrainDiagnosticDataResponse
###[ Parameter IDs ]###
\data_records\
|###[ OBD_S01_PR_Record ]###
| pid = 0x40
|###[ PID_40_PIDsSupported ]###
| supported_pids= PID56+PID51+PID4C+PID49+PID47+PID46+PID45
Send request to query for PID data
socket.sr1(OBD()/OBD_S01(pid=0x5)).show()
###[ On-board diagnostics ]###
service = CurrentPowertrainDiagnosticDataResponse
###[ Parameter IDs ]###
\data_records\
|###[ OBD_S01_PR_Record ]###
| pid = 0x5
|###[ PID_05_EngineCoolantTemperature ]###
| data = 41.0 deg. C
Send request to query for IID data
socket.sr1(OBD()/OBD_S09(iid=0xa)).show()
###[ On-board diagnostics ]###
service = VehicleInformationResponse
###[ Infotype IDs ]###
\data_records\
|###[ OBD_S09_PR_Record ]###
| iid = 0xa
|###[ IID_0A_EcuName ]###
| count = 1
| ecu_names = ['ECM\x00-EngineControl']
OBD Scanner#
Scapy’s OBD_Scanner
allows to automatically fetch all available
information
load_contrib("automotive.obd.scanner")
s = OBD_Scanner(socket)
s.scan(timeout=10)
s.show_testcases()
==========================================
Available data in OBD service 09
------------------------------------------
9 requests were sent, 9 answered, 0 unanswered
Statistics per state
-------------------+---------+----------+
| all | session1 |
-------------------+---------+----------+
answertime_avg | 0.00086 | 0.00086 |
answertime_avg_nr | 0.00072 | 0.00072 |
answertime_avg_pr | 0.00088 | 0.00088 |
... | ... | ... |
answertime_min_pr | 0.00078 | 0.00078 |
num_answered | 9 | 9 |
num_negative_resps | 1 | 1 |
num_unanswered | 0 | 0 |
-------------------+---------+----------+
1 negative responses were received
These negative response codes were received 0x12
NRC 0x12: subFunctionNotSupported-InvalidFormat received 1 times
The following negative response codes are blacklisted: ['generalReject', 'serviceNotSupported']
----------------------------------------------+-----------------------------------------------------------------------------+
| Service 09 |
----------------------------------------------+-----------------------------------------------------------------------------+
0x00 IID_00_Service9SupportedInformationTypes | <OBD_IID00 supported_iids=IID12+IID0F+IID0A+IID08+IID06+IID04+IID02 |> |
0x02 IID_02_VehicleIdentificationNumber | <OBD_IID02 count=1 vehicle_identification_numbers=['WDD1xxxxxxxxxxx11'] |> |
0x0a IID_0A_EcuName | <OBD_IID0A count=1 ecu_names=['ECM\x00-EngineControl'] |> |
0x0f Raw | <Raw load='\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00HM0876' |> |
0x12 Raw | <Raw load='\x01\x00\\xd5' |> |
----------------------------------------------+-----------------------------------------------------------------------------+