Skip to content
AutoST by Zyberum GmbH
Menu
ODXDiagnostics

ODX-driven testing: turn your diagnostic data into tests

How ODX and PDX files drive a sharper ECU security test: what a DIAG-LAYER names, how DIDs and routines come from the data, and why that beats brute force.

Tom Zaubermann · Published · 8 min read

ODX-driven testing means using the diagnostic description you already have to name what a scan finds and to call exactly the services an ECU defines, instead of guessing. ODX (Open Diagnostic Data Exchange, ISO 22901-1) is the standard format for that description, and feeding it into a security test turns a raw hex dump into something that reads like your own diagnostic spec. Here is what the data contains and how it sharpens a test.

What ODX actually is

ODX is an XML data model, standardised as ISO 22901-1, that describes an ECU’s diagnostic communication: the services it supports, the data identifiers it exposes, the routines it runs, and how each request and response is structured. It is usually shipped as a PDX (Packed ODX), a container, essentially a ZIP, that bundles the ODX files for one or more ECUs so the whole description travels as a single artifact.

The practical point is that an ODX file is the ground truth for what an ECU offers, written by the people who built it. A security test that ignores it is working blind; one that reads it starts from the real map.

The DIAG-LAYER, and how it names things

ODX organises diagnostics into layers. The one that matters for testing is the DIAG-LAYER (the diagnostic layer for a given ECU variant). Inside it, the data defines:

  • Data identifiers. A DID like 0xF190 is described with a short name, a long name and a structure: DID 0xF190 = "VIN", 17 bytes, ASCII. The scan no longer shows a bare number, it shows the name.
  • Routines. A routine identifier (RID) used by RoutineControl (0x31) is defined with its sub-functions (start, stop, request results) and the parameters each one takes. The data tells you the routine exists and how to call it correctly.
  • Request and response structure. Each service’s parameters, their positions, lengths and encodings, so a response can be decoded into fields instead of bytes.
  • Negative-response handling. The expected NRCs for a service, which helps distinguish a real finding from normal behaviour.

A concrete before and after. Without ODX, enumeration finds:

22 F1 A0 -> 62 F1 A0 03 1F 00 ...   DID 0xF1A0 readable, value unknown

With the DIAG-LAYER loaded, the same result reads:

DID 0xF1A0 "Calibration dataset version" readable, value 3.31.0

The value just became meaningful, which is the difference between a list of readable addresses and an understanding of what each one exposes.

Why routines come from the data, not from brute force

DIDs can be swept, because the identifier space is finite and a read is cheap. Routines cannot be sensibly brute-forced: a RoutineControl 0x31 start with the wrong parameters can move an actuator, start a flash erase or put the ECU in a strange state. You do not fire random routines at an ECU and see what happens.

ODX solves this. Because the DIAG-LAYER defines each routine and its parameters, a scan can call exactly the routines the ECU declares, with the right payload, and read the results the ECU returns. That is both safer and more thorough than guessing, because it covers the routines that matter without touching ones that were never defined.

RID 0xFF00 "Check programming preconditions"
tx 31 01 FF 00        startRoutine, no extra parameters per the DIAG-LAYER
rx 71 01 FF 00 00     routine started, result byte 0x00

What this does for security testing

Loading ODX changes a test in four ways:

  1. Readable results. Findings name the DID and routine, so the report reads like your spec and a developer knows immediately what is affected.
  2. Targeted routine coverage. The scan runs the routines the ECU actually defines, not a random subset, and records request and response for each.
  3. Safer write probing. When write probing (0x2E) is enabled, the structure from ODX means the test writes correctly shaped data and can check length and write-back behaviour, rather than firing malformed payloads blindly. Write probing stays destructive, off by default and confirmed before it runs.
  4. Faster, cleaner scans. Starting from the real map skips the dead ends of pure brute force.

How AutoST uses it

AutoST imports ODX, ODX-D and PDX (the ASAM standard) and Vector CDD (Candela XML), normalising both into a list of DIDs and routines per ECU. The DID names enrich the enumeration results so a discovered identifier shows its real name, and the routine definitions drive the routine (0x31) scan: AutoST calls only the routines defined in your file, with a payload you can override, and stores every request and response. You attach the file to the ECU once and every scan uses it. Confidential diagnostic files stay on your own instance, which matters because an ODX or CDD is often as sensitive as the ECU it describes.

FAQ

Frequently asked questions

What is ODX and what is a PDX file?

ODX (Open Diagnostic Data Exchange, ISO 22901-1) is an XML format that describes an ECU's diagnostic services. A PDX is a packaged container, essentially a ZIP of the ODX files for one or more ECUs, which is how ODX is usually shipped.

Why use ODX instead of brute-forcing DIDs and routines?

Routines (0x31) cannot be sensibly brute-forced, and brute-forcing DIDs gives you numbers without meaning. ODX names each identifier and defines each routine's parameters, so a scan reads like your diagnostic spec and calls exactly what the ECU defines.

Does AutoST support Vector CDD as well as ODX?

Yes. AutoST imports ODX, ODX-D and PDX (the ASAM standard) and Vector CDD (Candela XML). It normalises both into a list of DIDs and routines that enrich enumeration and drive the routine scan.

Call usBook a demo

Pick a time that suits you

Open in a new tab