DBC and CAN Signal Reverse Engineering
The file that turns eight opaque octets into named physical quantities, and what to do on the overwhelming majority of vehicles where nobody will give you one.
A DBC is the database file that says what the octets of a CAN frame mean. For each message it names the signals inside it and, for each signal, gives the start bit, the length in bits, the byte order, the signedness, a scale factor and an offset. With one, decoding a capture is a single command. Without one, you have hexadecimal.
What it is
The format comes from Vector's CANdb and has become the de facto interchange for CAN signal definitions; ARXML and Vector's own tooling cover the same ground in the OEM world. The essential content is small:
physical value = raw * factor + offset
where raw is an unsigned or two's complement integer read out of the frame at a given bit position, in a given byte order. Everything else in the file is naming and documentation.
Manufacturers treat these files as confidential, so on a vehicle you do not own the specification for, the usual state of affairs is that no DBC exists for you. What does exist is community work per platform, and the standard OBD-II PIDs, which are a tiny, legally mandated and identical-everywhere subset accessible through the diagnostic socket.
Why it matters
Everything downstream needs the layout: an intrusion detection rule that range checks a signal, an instrument cluster forensic that proves an odometer was rolled back, a reconstruction that asks how fast a vehicle was going. Reverse engineering the layout is therefore a routine skill rather than an exotic one, and the general shape of it is always the same: find some ground truth, then search the frame for a field that is an affine function of it.
How to work it
- When you do have a DBC, use it and move on.
cantools dump vehicle.dbc # what the file claims exists
cantools decode vehicle.dbc < candump.log # named signals, in physical units
- When you do not, get ground truth from outside the bus. An OBD-II app logging PIDs through the diagnostic socket, a GPS track, a dyno, or simply doing one thing at a time and diffing the capture.
- Sweep for the signal. Enumerate every candidate field of every identifier, both byte orders, fit a scale and an offset onto the ground truth, and rank by residual. If the ground truth's clock is not the capture's clock, solve for the offset between them at the same time.
- Take the narrowest field that accounts for the signal. Extending a field into a neighbouring octet that barely moves leaves the fit unchanged and is not the field.
- Where no ground truth exists at all, manufacture some. A distance counter can be identified against an integral of a speed signal you have already recovered.
Pitfalls
- Several fields can be proportional to the same physical quantity. Wheel speeds track road speed but are not it, and they betray themselves through slip under acceleration and braking rather than through correlation.
- Byte order is per signal, not per message, and mixed-endian frames are common.
- Counters and checksums are not signals. A rolling counter in a nibble and an XOR of the preceding octets in the last one is a house style, and both will correlate with anything that moves monotonically.
- A signal that is constant for the whole capture cannot be found in that capture, however good your method is.
- OBD-II PID values are coarse. Speed is a whole number of km/h, which is often not enough resolution to separate two candidates that differ by a percent.