Serial EEPROM & Immo
The 512-byte immo EEPROM, page by page, with a working checksum fixer.
The 512-byte immo EEPROM, page by page, with a working checksum fixer.
While calibration maps, operating system code, and diagnostic tables reside inside the 1024 KB external parallel flash memory (AM29F800BB), all dynamic vehicle-specific adaptation parameters, anti-theft immobilizer security keys, vehicle identification (VIN), softcoding, and flash programming counters reside in a dedicated 8-pin SPI serial EEPROM located on the ECU PCB adjacent to the C167CR microcontroller.
On standard transverse 06A platforms, this chip is an STMicroelectronics 95040 (512 Bytes / 4 Kbit). On newer longitudinal platforms (such as Audi A4 B6 8E0 909 518 xx), this chip is an STMicroelectronics 95080 (1024 Bytes / 8 Kbit).
BOSCH ME7.5 95040 EEPROM 512-BYTE (32-PAGE) MEMORY LAYOUT
| Offset | Page Index & Descriptor | Functional Subsystem | Data Content & Role |
|---|---|---|---|
| 0x000–0x00F | Page 0 (Desc: 0xFF18) | Header & Hardware Sync | Startup state, bus flags |
| 0x010–0x01F | Page 1 (Desc: 0x0017) | Immobilizer Bank 1 | Immo Status Byte (0x12) |
| 0x020–0x02F | Page 2 (Desc: 0x0117) | Immobilizer Bank 2 (Mirror) | Immo Status Byte (0x22) |
| 0x030–0x03F | Page 3 (Desc: 0x0207) | Secret Key Code (SKC/PIN) 1 | 4-digit/5-digit Login PIN |
| 0x040–0x04F | Page 4 (Desc: 0x0307) | Secret Key Code (SKC/PIN) 2 | Redundant PIN & Key RFID |
| 0x050–0x05F | Page 5 (Desc: 0x0437) | Immo Status & Lockout Timer | Learned key count, lock |
| 0x060–0x06F | Page 6 (Desc: 0x0533) | VIN Characters 1–14 (Bk 1) | Chassis VIN (ASCII) |
| 0x070–0x07F | Page 7 (Desc: 0x06B7) | VIN 15–17 & Immo ID (Bk 1) | VIN tail & 14-char Immo ID |
| 0x080–0x08F | Page 8 (Desc: 0x06F7) | Immo ID Tail & Crypto Seed | Immo ID tail & Seed bytes |
| 0x090–0x09F | Page 9 (Desc: 0x07B3) | VIN Characters 1–14 (Bk 2) | Redundant VIN Bank 2 |
| 0x0A0–0x0AF | Page 10 (Desc: 0x07F3) | VIN 15–17 & Immo ID (Bk 2) | Redundant Immo ID Bank 2 |
| 0x0B0–0x0BF | Page 11 (Desc: 0x08B7) | Immo ID Tail (Bk 2) | Redundant Immo ID Tail |
| 0x0C0–0x0CF | Page 12 (Desc: 0x08F7) | Softcoding & WSC (Bank 1) | Trans/ABS Coding, WSC |
| 0x0D0–0x0DF | Page 13 (Desc: 0x09B3) | Softcoding & WSC (Bank 2) | Redundant Coding Mirror |
| 0x0E0–0x0EF | Page 14 (Desc: 0x09F3) | Flash Programming Counter 1 | Flash attempts & successes |
| 0x0F0–0x0FF | Page 15 (Desc: 0x0AB3) | Flash Programming Counter 2 | Redundant Flash Counter |
| 0x100–0x14F | Pages 16–20 (0x0AF3..0B10) | Throttle Body Adaptation | Min, Max, Limp endstops |
| 0x150–0x18F | Pages 21–24 (0x0C37..0F33) | Fuel Trim & Knock Offsets | LTFT Add/Mult, Knock dwkrz |
| 0x190–0x1BF | Pages 25–27 (0x1033..1233) | Readiness & DTC Freeze | OBD bitmask & fault buffer |
| 0x1C0–0x1CF | Page 28 (Desc: 0x1235) | VAG Part Number (ASCII) | Checksum-Exempt ASCII |
| 0x1D0–0x1DF | Page 29 (Desc: 0x1235) | Bosch HW/SW Version (ASCII) | Checksum-Exempt ASCII |
| 0x1E0–0x1FF | Pages 30–31 (0x13B7..13F7) | End Markers & Trailing CRC | Final factory block sync |
10.1. Detailed Memory Map: Reverse-Engineering All 32 Pages#
Every page consists of 16 bytes. In all checksummed pages, Bytes 0 through 13 hold data payload, while Bytes 14 and 15 hold the 16-bit little-endian page checksum.
1. Pages 1 & 2: Immobilizer Control Banks (0x010–0x02F)#
- Memory Offsets: Bank 1 at
0x010–0x01F; Bank 2 (Mirror) at0x020–0x02F. - Key Offset
0x0012&0x0022— The Immobilizer Status Byte: - Editing Rule: Both Bank 1 (
0x0012) and Bank 2 (0x0022) must be set to identical values. If one is set to0x02and the other remains0x01, the ECU detects a memory corruption, restores the locked state from the backup bank, and sets P1603.
2. Pages 3 & 4: Secret Key Code (SKC / Login PIN) & RFID Key Store (0x030–0x04F)#
- Memory Offsets: Bank 1 at
0x030–0x03F; Bank 2 at0x040–0x04F.- Holds 32-bit unique IDs of RFID transponders (Megamos Crypto 48 chips) matched to the vehicle.
- Offsets
0x0032–0x0033&0x0042–0x0043— The 16-Bit Login PIN: - Offsets
0x0034–0x003B— Learned Transponder Key Identifiers:
3. Pages 6, 7 & 8: Vehicle Identification Number (VIN) & Immo ID (0x060–0x08F)#
- Memory Offsets: Bank 1 at
0x060–0x08F; Bank 2 at0x090–0x0BF.- Stored in clear ASCII text (e.g.,
VWZ7Z0C1234567orAUX7Z0D9876543). - Stamped by the cluster during pairing.
- Stored in clear ASCII text (e.g.,
- Offsets
0x0060–0x006D&0x0070–0x0072— 17-Digit Chassis VIN: - Offsets
0x0073–0x007D&0x0080–0x0082— 14-Digit Immobilizer Serial Number (Immo ID):
4. Pages 12 & 13: ECU Softcoding & Workshop Identification (0x0C0–0x0DF)#
- Memory Offsets: Bank 1 at
0x0C0–0x0CF; Bank 2 at0x0D0–0x0DF.- Dealership equipment number stamping from the last VAS 5051 tool that coded the module.
- Offsets
0x00C0–0x00C1— 5-Digit VAG Softcoding: - Offsets
0x00C4–0x00C8— Workshop Code (WSC) & Importer ID:
5. Pages 14 & 15: Flash Programming Attempt Counters (0x0E0–0x0FF)#
- Offsets
0x00E0–0x00E1: Number of flash programming attempts (Programmierversuche). Increments by 1 every time an OBD flash session begins (KWP2000 Service 0x34 Request Download). - Offsets
0x00E2–0x00E3: Number of successful flash programming completions (Erfolgreiche Programmierungen). - Editing Rule: To reset flash history to factory virgin (
0 / 0), write0x00 0x00to0x00E0–0x00E3and mirror into Bank 2 (0x00F0–0x00F3).
6. Pages 16–20: Electronic Throttle (E-Gas) Learned Adaptations (0x100–0x14F)#
- Stores voltage bounds learned during VCDS Basic Settings Group 060:
G187/G188minimum lower mechanical stop voltage.G187/G188maximum wide-open throttle stop voltage.- Emergency limp-home spring rest position (~7.5% plate angle).
- When adapting a new throttle body, ME7.5 writes updated ADC counts directly into these pages.
7. Pages 21–24: Long-Term Fuel Trims (LTFT) & Cylinder Knock Offsets (0x150–0x18F)#
- Offsets
0x0150–0x0153: Additive idle fuel trim (rkadd_w/ measuring block 032 field 1). - Offsets
0x0154–0x0157: Multiplicative load fuel trim (fra_w/ measuring block 032 field 2). - Offsets
0x0160–0x0167: Learned ignition retard offsets per cylinder (dwkrz_0throughdwkrz_3). - Offsets
0x0170–0x0173: Camshaft phase adaptation offset (wngwg_w/ correlation between crankG28and camG40).
8. Pages 28 & 29: VAG Hardware & Software Part Number Strings (0x1C0–0x1DF)#
- Page 28 (
0x1C0–0x1CF): VAG Part Number string in ASCII (e.g.,06A906032LP). - Page 29 (
0x1D0–0x1DF): Bosch Software Version in ASCII (e.g.,0005 0261207955). - CRITICAL CHECKSUM EXEMPTION: Although the internal firmware descriptor word for Pages 28 and 29 (
0x1235) has the checksum present bit set, Bosch ME7.5 operating systems exempt these two pages from mathematical checksum verification. They store ASCII strings and must never have their last two bytes altered to formula values.
10.2. The Master Bosch ME7.5 EEPROM Checksum Algorithm#
Whenever any byte in Pages 0–27 or 30–31 is edited, the 16-bit complement checksum in Bytes 14 and 15 of that specific page must be recalculated. Failing to update the checksum causes the ECU to flag P1603 / 18011 (Internal Control Module: EEPROM Defective) on the next key cycle and lock adaptation storage.
1. Per-Page Firmware Descriptor Table#
Inside the C167 firmware ROM, Bosch maintains a lookup table containing a 16-bit descriptor word for each of the 32 pages:
Page 00: 0xFF18 Page 08: 0x06F7 Page 16: 0x0AF3 Page 24: 0x0F33
Page 01: 0x0017 Page 09: 0x07B3 Page 17: 0x0B32 Page 25: 0x1033
Page 02: 0x0117 Page 10: 0x07F3 Page 18: 0x0B10 Page 26: 0x1133
Page 03: 0x0207 Page 11: 0x08B7 Page 19: 0x0B10 Page 27: 0x1233
Page 04: 0x0307 Page 12: 0x08F7 Page 20: 0x0B10 Page 28: 0x1235 (EXEMPT)
Page 05: 0x0437 Page 13: 0x09B3 Page 21: 0x0C37 Page 29: 0x1235 (EXEMPT)
Page 06: 0x0533 Page 14: 0x09F3 Page 22: 0x0D33 Page 30: 0x13B7
Page 07: 0x06B7 Page 15: 0x0AB3 Page 23: 0x0E33 Page 31: 0x13F7
2. Bitmask Flags#
ChecksumPresentMask = 0x0001: If(descriptor & 0x0001) != 0, this page is protected by a checksum.ChecksumBitMask = 0x0040: If(descriptor & 0x0040) != 0, subtract 1 from the running sum before complementation.
3. Mathematical Checksum Formulation#
For page P \in [0, 31] starting at byte offset \text{offset} = P \times 16:
- Sum the 14 data payload bytes (Bytes 0 through 13): \text{Sum} = \sum_{i=0}^{13} \text{EEPROM}[\text{offset} + i]
- Add the page index number: \text{Sum} = \text{Sum} + P
- If bit 6 of the page descriptor is active: $$\text{If } (\text{Descriptor}[P] \land \text{0x0040})
eq 0 \implies \text{Sum} = \text{Sum} - 1$$
- Compute the 16-bit two's complement negation: \text{Checksum} = (-\text{Sum}) \pmod{2^{16}}
- Store the 16-bit word in little-endian format at Bytes 14 and 15: \text{EEPROM}[\text{offset} + 14] = \text{Checksum} \land \text{0xFF} \text{EEPROM}[\text{offset} + 15] = (\text{Checksum} \gg 8) \land \text{0xFF}
10.3. Standalone Python Checksum Fixer & Immo Defeater (me7_eeprom_fixer.py)#
The following self-contained Python script automatically defeats the immobilizer, validates all 32 pages, and recalculates all Bosch page checksums for any 512-byte (95040) or 1024-byte (95080) EEPROM image:
#!/usr/bin/env python3
import sys
PAGE_DESCRIPTORS = [
0xFF18, 0x0017, 0x0117, 0x0207, 0x0307, 0x0437, 0x0533, 0x06B7,
0x06F7, 0x07B3, 0x07F3, 0x08B7, 0x08F7, 0x09B3, 0x09F3, 0x0AB3,
0x0AF3, 0x0B32, 0x0B10, 0x0B10, 0x0B10, 0x0C37, 0x0D33, 0x0E33,
0x0F33, 0x1033, 0x1133, 0x1233, 0x1235, 0x1235, 0x13B7, 0x13F7,
]
EXEMPT_PAGES = {28, 29}
def calc_page_checksum(data, page_offset, page_num, desc):
s = sum(data[page_offset + i] for i in range(14)) + page_num
if desc & 0x0040:
s -= 1
return (-s) & 0xFFFF
def fix_eeprom_bank(data, bank_offset=0):
updated = 0
for page in range(32):
if page in EXEMPT_PAGES:
continue
desc = PAGE_DESCRIPTORS[page]
if not (desc & 0x0001):
continue
p_off = bank_offset + (page * 16)
expected = calc_page_checksum(data, p_off, page, desc)
stored = data[p_off + 14] | (data[p_off + 15] << 8)
if stored != expected:
data[p_off + 14] = expected & 0xFF
data[p_off + 15] = (expected >> 8) & 0xFF
updated += 1
return updated
def process_eeprom(in_path, out_path, immo_off=True):
with open(in_path, "rb") as f:
buf = bytearray(f.read())
if len(buf) not in (512, 1024):
raise ValueError(f"Invalid EEPROM size: {len(buf)} bytes (expected 512 or 1024)")
if immo_off:
# Patch Bank 1 and Bank 2 Immobilizer bytes
buf[0x0012] = 0x02
buf[0x0022] = 0x02
if len(buf) == 1024:
buf[0x0212] = 0x02
buf[0x0222] = 0x02
print("[+] Immobilizer flags patched to 0x02 (Immo Defeated)")
fixes = fix_eeprom_bank(buf, 0)
if len(buf) == 1024:
fixes += fix_eeprom_bank(buf, 512)
with open(out_path, "wb") as f:
f.write(buf)
print(f"[+] Corrected {fixes} page checksums. Output saved to: {out_path}")
if __name__ == "__main__":
if len(sys.argv) < 3:
print("Usage: python3 me7_eeprom_fixer.py <input.bin> <output.bin> [--immo-off]")
sys.exit(1)
process_eeprom(sys.argv[1], sys.argv[2], "--immo-off" in sys.argv)
10.4. Step-by-Step Hex Editing Instructions: Performing Common Tasks#
Task 1: Complete Immobilizer Defeat (Immo Off)#
- Open your 512-byte EEPROM dump in a hex editor (e.g. HxD, Hex Fiend, or 010 Editor).
- Go to byte
0x0012: Change value from0x01to0x02. - Go to byte
0x0022: Change value from0x01to0x02. - Run
me7_eeprom_fixer.py(orme7eeprom --fixchecksums) to recalculate the row checksums at0x001E–0x001Fand0x002E–0x002F.
Task 2: Extracting the 5-Digit Login PIN / SKC#
- Locate bytes
0x0032and0x0033. - Read the values as a little-endian 16-bit unsigned integer:
- Verify against backup bank at
0x0042and0x0043(must match).
Task 3: Changing the Chassis VIN#
- Go to address
0x0060. - Type the first 14 characters of the new VIN in ASCII (e.g.
WVWZZZ1JZ3W1234). - Go to address
0x0070. - Type the remaining 3 characters of the VIN in ASCII (e.g.
567). - Mirror the exact same string to Bank 2: characters 1–14 at
0x0090, characters 15–17 at0x00A0. - Recalculate checksums for Pages 6, 7, 9, and 10.
Task 4: Converting a 512-Byte Dump to Run on an 8E0 95080 Chip#
- Take your 512-byte transverse 06A EEPROM dump (
512_bytes.bin). - Create a duplicate 1024-byte file by appending the 512-byte image to itself:
cat 512_bytes.bin 512_bytes.bin > 1024_padded_8e0.bin
- Run the checksum fixer on both 512-byte banks:
python3 me7_eeprom_fixer.py 1024_padded_8e0.bin 1024_padded_8e0_fixed.bin --immo-off
- Flash
1024_padded_8e0_fixed.bininto the 8E095080chip using an external programmer or bench tool.
10.5. VCDS Diagnostic Adaptation Channels & Direct EEPROM Physical Mapping#
When an automotive technician alters operating parameters via Ross-Tech VCDS / VAS-5054A diagnostic software, the ECU writes the newly calibrated scalar offsets directly into non-volatile SPI EEPROM cells. Understanding this mapping enables an engineer to inspect, preset, or clone adaptation values directly in a hex editor:
VCDS ADAPTATION CHANNELS TO 95040 EEPROM PHYSICAL OFFSET MAPPING
| Channel | Functional Parameter | EEPROM Page | Physical Byte | Format & Resolution |
|---|---|---|---|---|
| Ch 00 | Factory Adaptations Reset | Pages 16–27 | 0x100–0x1BF | Bulk wipe to 0x00/FF |
| Ch 01 | Idle Speed Adjustment (NMIN) | Page 12 & 13 | 0x0C2 / 0x0D2 | u8: 10 rpm / step |
| Ch 02 | Fuel Enrichment / Transient | Page 12 & 13 | 0x0C3 / 0x0D3 | u8: 0.78% / step |
| Ch 03 | Ignition Angle Global Offset | Page 12 & 13 | 0x0C6 / 0x0D6 | s8: 0.75 deg / step |
| Ch 50 | Immobilizer Learning Routine | Pages 3,4,7,8 | 0x030–0x08F | VIN, PIN, Crypto Key |
| Ch 60 | Throttle Body Basic Settings | Pages 16–20 | 0x100–0x14F | G187/G188 ADC Limits |
| Ch 99 | VVT Exhaust/Intake Diagnostics | Page 25 | 0x192 | 1-byte status bitmask |
Detailed Subsystem Mechanics#
- Channel 00 (Clear All Learned Values): Executing
Save [0]on Channel 00 triggers the C167 CPU to zero out the learned throttle body ADC endpoints (Pages 16–20), wipe the short-term and long-term fuel trim correctionsrkaddandfra(Pages 21–24), and clear cylinder-selective knock adaptation tables.- Completely closed mechanical lower stop.
- Emergency limp-home spring rest position.
- Wide-open throttle mechanical upper stop. The resulting potentiometer voltages from
G187andG188are stored across Pages 16 through 20. If these values are corrupted, the ECU flags DTCP1559orP1545and refuses throttle input.
- Channel 01 (Idle Speed Trimming): Allows the idle RPM to be raised or lowered by up to \pm 150\text{ rpm}. Modifies byte
0x00C2in Bank 1 and byte0x00D2in Bank 2. Value128represents factory baseline (800\text{ rpm}). Setting138raises idle to 900\text{ rpm} (vital for smoothing high-lift aftermarket camshafts or solid engine mounts). - Channel 60 (Electronic Throttle Body Adaptation — Basic Settings 060): The ECU commands the throttle motor (
G186) through its mechanical range:
10.6. Immobilizer Generation 2 (WFS2) vs. Generation 3 (WFS3) Cryptographic Architecture#
Between 1999 and 2005, VAG phased out early Immobilizer II (WFS2) in favor of the much more sophisticated Immobilizer III (WFS3) system:
1. Immobilizer II (WFS2 — Early Transverse ME7.5, e.g. 06A906032J / 21D)#
- Structure: 17-digit VIN only. Does not utilize a separate 14-character cluster serial number.
- Transponder: Megamos Crypto ID48 with fixed pre-programmed transponder serials.
- Handshake: Unidirectional. The cluster verifies the transponder key and sends an authorization telegram to the ECU over K-Line (Pin 43).
- Immo Defeat: Setting byte
0x0012to0x02is sufficient; no secondary cluster pairing or rolling crypto seed is maintained in EEPROM.
2. Immobilizer III (WFS3 — Mature Transverse ME7.5, e.g. 06A906032LP / JJ / SK / 24B)#
- Structure: Dual identification:
- Mutual Authentication Handshake: At power-on, the instrument cluster (
J285) and ECU (J220) engage in a mutual 128-bit challenge-response authentication over the 500 kbps Drivetrain CAN bus (CAN IDs0x280and0x480): - Immo Defeat Mechanics in WFS3: Setting byte
0x0012 = 0x02and0x0022 = 0x02forces the C167 operating system to bypass the CAN authentication listener entirely, assertingB_stend = 1unconditionally upon hardware reset.
Related#
Cross-referenced on shared calibration symbols, not on subject matter — these are the chapters that touch the same maps.
- Chapter 12 — RAM Logging & .ecu Files —
RKADD_W,DWKRZ_3,DWKRZ_0,FRA_W - Chapter 2 — Bosch Project Taxonomy —
G40,J285,ASR,G28 - Chapter 25 — Troubleshooting & Failsafes —
G40,FRA_W,G28 - Chapter 13 — 121-Pin Harness —
J285,ASR,G28 - Chapter 37 — Knock Sensor Recalibration —
DWKRZ_3,DWKRZ_0 - Chapter 55 — Flash Map & Task Tree —
ASR,G186,G28
← Previous chapter · Contents · Next chapter →
Related
Cross-referenced on shared calibration symbols, not on subject matter — these are the chapters that touch the same maps.