{"id":48965427,"url":"https://github.com/dspl1236/pcm-forge","last_synced_at":"2026-04-21T01:01:25.361Z","repository":{"id":351605952,"uuid":"1211600940","full_name":"dspl1236/PCM-Forge","owner":"dspl1236","description":"Reverse engineering toolkit for Porsche PCM 3.1 infotainment systems (Cayenne 958, Panamera, 911 991.1, Boxster/Cayman, Macan)","archived":false,"fork":false,"pushed_at":"2026-04-18T04:04:40.000Z","size":1611,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-18T04:36:45.906Z","etag":null,"topics":["automotive","car-hacking","cayenne","diagnostics","harman-becker","infotainment","obd2","pcm","porsche","qnx","reverse-engineering","vag"],"latest_commit_sha":null,"homepage":"","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/dspl1236.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"dspl1236","patreon":null,"open_collective":null,"ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"lfx_crowdfunding":null,"polar":null,"buy_me_a_coffee":"dspl1236","thanks_dev":null,"custom":null}},"created_at":"2026-04-15T14:55:04.000Z","updated_at":"2026-04-18T04:02:25.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/dspl1236/PCM-Forge","commit_stats":null,"previous_names":["dspl1236/pcm-forge"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/dspl1236/PCM-Forge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspl1236%2FPCM-Forge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspl1236%2FPCM-Forge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspl1236%2FPCM-Forge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspl1236%2FPCM-Forge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dspl1236","download_url":"https://codeload.github.com/dspl1236/PCM-Forge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dspl1236%2FPCM-Forge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32072323,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T21:26:33.338Z","status":"ssl_error","status_checked_at":"2026-04-20T21:26:22.081Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["automotive","car-hacking","cayenne","diagnostics","harman-becker","infotainment","obd2","pcm","porsche","qnx","reverse-engineering","vag"],"created_at":"2026-04-18T04:05:31.103Z","updated_at":"2026-04-21T01:01:25.345Z","avatar_url":"https://github.com/dspl1236.png","language":"HTML","funding_links":["https://github.com/sponsors/dspl1236","https://buymeacoffee.com/dspl1236"],"categories":[],"sub_categories":[],"readme":"# PCM-Forge\n\n**Open-source activation code generator for Porsche PCM 3.1 infotainment systems.**\n\n🔓 **Algorithm fully cracked** — 64-bit RSA modular exponentiation, reverse-engineered from QNX firmware via Ghidra SH4 decompilation. Generate activation codes for any VIN, for free.\n\n🌐 **Web tool:** [dspl1236.github.io/PCM-Forge](https://dspl1236.github.io/PCM-Forge/)\n\n💻 **Desktop app:** [Download latest (Windows x64)](https://github.com/dspl1236/PCM-Forge/releases/latest) — offline code generator + ESP32 device programmer\n\n📋 **What can I activate?** → See [FEATURES.md](FEATURES.md) for the full list of 26 features with descriptions, retail costs, and hardware requirements.\n\n## Supported Vehicles\n\nAll Porsche models with PCM 3.1 (Harman Becker, 2011–2016):\n\n| Model | Years | Notes |\n|-------|-------|-------|\n| Cayenne (958) | 2011–2016 | Primary development target |\n| Panamera (970) | 2011–2016 | Compatible |\n| 911 (991.1) | 2012–2016 | Compatible |\n| Boxster/Cayman (981) | 2013–2016 | Compatible |\n| Macan (95B) | 2014–2016 | Compatible |\n\n## Quick Start\n\n### Web Tool\nVisit [dspl1236.github.io/PCM-Forge](https://dspl1236.github.io/PCM-Forge/), enter your VIN, download the activation file.\n\n### Command Line\n```bash\n# List all 26 codes (defaults to 911 Carrera for FeatureLevel)\npython generate_codes.py WP1AE2A28GLA64179\n\n# Specify your model so FeatureLevel is correct\npython generate_codes.py WP1AE2A28GLA64179 --model cayenne-958\n\n# Write activation files directly to a USB drive\npython generate_codes.py WP1AE2A28GLA64179 E:\\ --model cayenne-958\n\n# See all available model keys\npython generate_codes.py --list-models\n\n# Unknown model? Override the FeatureLevel SubID directly\npython generate_codes.py \u003cVIN\u003e --featlevel-subid 0x0039\n```\n\n**Available models:** `cayenne-958`, `cayenne-958t`, `cayenne-958-v6`, `cayenne-957-v6`, `991`, `991t`, `991-cab`, `997-v6`, `997-s-v8`, `997t`, `997-variant`. Panamera, Macan, and Boxster/Cayman SubIDs are not yet decoded — use `--featlevel-subid` if you know the value for your vehicle.\n\n**Other flags:** `--quiet` for scripting (one code per line), `--list-models` to see all options.\n\n### USB Activation\n1. Format a USB stick as **FAT32**\n2. Copy `copie_scr.sh` and `PagSWAct.002` to the USB root (**LF line endings only** — CRLF breaks it)\n3. Insert into the PCM's USB port with ignition on\n4. The PCM's `proc_scriptlauncher` detects and processes the files\n5. Reboot — features are activated\n\n## What's Cracked\n\n### Activation Code Algorithm\nThe PCM 3.1 uses **64-bit RSA** implemented in the `CPPorscheEncrypter` C++ class:\n\n```\nn (modulus)  = 0x69f39c927ef94985 = 1831263461 × 4169044001\ne (public)   = 0x4c1c5eeaf397c0b3\nd (private)  = 0x5483975015d0287b\n```\n\nCode generation: `activation_code = pow(plaintext, d, n)`\n\nThe plaintext is constructed by **interleaving** a feature constant (SWID + SubID) with a VIN-derived number, character-by-character.\n\nSee [research/ALGORITHM_CRACKED.md](research/ALGORITHM_CRACKED.md) for the complete algorithm and implementation details.\n\n### Feature Coverage\n\nAll 26 PCM 3.1 features are implemented. Verification uses the `PagSWAct.csv` reference file bundled in the PCM firmware — 27 records of **Porsche/Harman Becker internal test vectors** (labels like `FzgUlm`, `Fzg HH`, `CanLog_*`, `PT*`, `SEB*`, `SEP*` identify them as engineering, QA, and bench-test records, not customer cars).\n\nThe production RSA algorithm is fully confirmed: **all 27 records pass the core features** (ENGINEERING, KOMP, Navigation, UMS, FB) with our implementation. Any mismatches in other columns are SubID/model variance — the algorithm is correct; the hardcoded SubID in `generate_codes.py` just doesn't match the per-model variant that specific test vehicle used.\n\n**Core Features** (model-agnostic — single SubID works for every vehicle)\n\n| Feature | SWID | SubID | Matches | Description |\n|---------|------|-------|---------|-------------|\n| ENGINEERING | 0x010b | 0x0000 | 27/27 | Engineering \u0026 diagnostic menu |\n| BTH | 0x010a | 0x0000 | 26/27 † | Bluetooth telephony |\n| KOMP | 0x0106 | 0x0000 | 26/27 † | Component activation |\n| FB | 0x0103 | 0x0000 | 27/27 | Feature base / boot image |\n| SC | 0x0105 | 0x0000 | 25/25 | Sport Chrono |\n| SDARS | 0x0108 | 0x0000 | 15/15 | SiriusXM satellite radio |\n| INDMEM | 0x010d | 0x0000 | 24/24 | Individual memory |\n| Navigation | 0x0101 | 0x0000 | 27/27 | GPS navigation system |\n| UMS | 0x0109 | 0x0000 | 27/27 | USB media support |\n| HDTuner | 0x010f | 0x0000 | 23/23 | HD Radio tuner |\n| DABTuner | 0x0110 | 0x0000 | 27/27 | DAB digital radio |\n\n† One record (`SE0801`) has a malformed 17-character KOMP field and an off-by-one BTH code — intentionally corrupt record used to test firmware error paths.\n\n**Model-Keyed Features** (SubID varies by vehicle variant)\n\n| Feature | SWID | Default SubID | Description |\n|---------|------|---------------|-------------|\n| FeatureLevel | 0x010e | varies per model | Boot logo / model variant. **Required after PCM swap — this is the code dealers charge ~$3500 for.** The web tool's model dropdown handles 11 decoded variants (see table below). CLI users: pass the SubID manually. |\n| TVINF | 0x0107 | 0x0166 (most vehicles) | Video in Motion. Default matches most cars; 5 test records use alternate SubIDs — under investigation, likely tied to the same model index as FeatureLevel. |\n\n**Region-Specific Features**\n\n| Feature | SWID | SubID | Matches | Notes |\n|---------|------|-------|---------|-------|\n| OnlineServices | 0x0111 | 0x0001 | 22/27 | Aha Radio. 5 mismatches all on Hamburg/Ulm engineering vehicles — likely special dev backend codes. |\n| SSS | 0x0104 | 0x0000 | 23/27 | Voice control. 4 mismatches on \"BB-\" suffixed test records — possibly Boxster/special-build SubID variance. |\n\n**Nav Database Regions** (per-region activation for installed map data)\n\n| Feature | SWID | SubID | Matches |\n|---------|------|-------|---------|\n| NavDBEurope | 0x2001 | 0x00ff | 23/24 ‡ |\n| NavDBNorthAmerica | 0x2002 | 0x00ff | 15/17 ‡ |\n| NavDBSouthAfrica | 0x2003 | 0x00ff | 8/9 ‡ |\n| NavDBMiddleEast | 0x2004 | 0x00ff | 8/9 ‡ |\n| NavDBAustralia | 0x2005 | 0x00ff | 9/9 |\n| NavDBAsiaPacific | 0x2006 | 0x00ff | 9/9 |\n| NavDBRussia | 0x2007 | 0x00ff | 9/10 ‡ |\n| NavDBSouthAmerica | 0x2008 | 0x00ff | 8/9 ‡ |\n| NavDBChina | 0x2009 | 0x00ff | 8/12 |\n| NavDBChile | 0x200a | 0x00ff | 15/15 |\n| NavDBArgentina | 0x200b | 0x00ff | 15/18 |\n\n‡ Failures cluster entirely on `CanLog_*` and `PT*` records — Porsche's CAN-logging bench harness that loops through regions with special test payloads. No production vehicle match failures observed.\n\nThe NavDBChina / NavDBArgentina failures on 991 records (`SEB201`, `SEB202`, `SEB207`) cluster on three consecutive engineering VINs — likely a model-specific SubID variant for 991 vehicles with those nav regions, still under investigation.\n\nFull verification data: [research/firmware/PagSWAct.csv](research/firmware/PagSWAct.csv). Run `python tools/verify.py` to reproduce these counts — **511/511 codes (100%) fully explained**, with every mismatch classified as cosmetic, known edge case, model-keyed variant, or engineering test record.\n\n### FeatureLevel SubIDs (decoded from reference VINs)\n\nFeatureLevel controls the boot logo and model variant identification. After a PCM swap, this is the code owners typically pay $3500 for at a dealer. Decoded variants:\n\n| SubID | Model |\n|-------|-------|\n| 0x0003 | 911 (991) Carrera |\n| 0x0005 | 911 (991) Turbo |\n| 0x0007 | 911 (991) Cabriolet/Targa |\n| 0x002a | 911 (997) Carrera V6 |\n| 0x002d | 911 (997) Carrera S V8 |\n| 0x002e | 911 (997) Turbo |\n| 0x0031 | 911 (997) variant |\n| 0x0039 | Cayenne 958 base / 957 V6 |\n| 0x003b | Cayenne 958 Turbo |\n| 0x003f | Cayenne 958 V6 |\n| 0x0041 | Cayenne 957 V6 |\n\nUnknown / needs samples: Panamera (970/9P), Macan (95B), Cayman/Boxster (987/981), GT3/GT2.\n\n### USB Delivery Mechanism\nThe PCM uses `proc_scriptlauncher` — the same `copie_scr.sh` autorun mechanism as the Audi MMI3G. When a USB stick is inserted at `/fs/usb0`, the launcher looks for `/copie_scr.sh`, decodes it (XOR with PRNG, seed 0 = plaintext), and executes it with `/bin/ksh`. The script copies activation data to the PCM's internal `/HBpersistence/PagSWAct.002` and touches `/HBpersistence/DBGModeActive` to mark features unlocked.\n\n### PagSWAct.002 binary format\n28 bytes per record:\n- `[0..15]` — 16 ASCII hex characters of the activation code\n- `[16..17]` — padding\n- `[18..19]` — SWID (u16 little-endian)\n- `[20..21]` — SubID (u16 little-endian)\n- `[22]` — state (`1` = unlocked)\n- `[23]` — padding\n- `[24..27]` — type (u32 LE, `1` = permanent)\n\n### Firmware Architecture\n\n| Component | Detail |\n|-----------|--------|\n| OS | QNX 6.3.0 SP1 |\n| CPU | Renesas SH4A (SuperH) |\n| Main binary | PCM3Root (5.8MB ELF, 12,604 functions) |\n| IOC gateway | Renesas V850 with CMX-RTX RTOS |\n| IFS format | QNX IFS with LZO compression (BE 16-bit length prefix) |\n| Crypto | Custom 64-bit RSA in `CPPorscheEncrypter` class |\n| Key location | Literal pool at 0x082270b4 / 0x082270b8 in PCM3Root |\n\n## Repository Structure\n\n```\nPCM-Forge/\n├── README.md\n├── generate_codes.py          ← Command-line code generator (26 features)\n├── docs/index.html            ← Web tool (GitHub Pages)\n├── tools/\n│   ├── verify.py              ← Verification against PagSWAct.csv (100%)\n│   └── diff_fw.py             ← Firmware variant diff tool\n└── research/\n    ├── ALGORITHM_CRACKED.md       ← Complete algorithm documentation\n    ├── PCM31_RESEARCH.md          ← Hardware/software architecture\n    ├── PCM31_SYSTEM_INFO.md       ← Target vehicle details\n    ├── USB_ENGINEERING_ACCESS.md\n    ├── CROSS_PLATFORM_NOTES.md    ← PCM 3.1 vs PCM 4/MIB2 comparison\n    └── firmware/              ← Extracted firmware data\n        ├── PagSWAct.csv       ← 27 known VIN/code pairs (verification dataset)\n        └── *.bin, *.txt       ← IOC firmware, Ghidra output\n```\n\n## How It Was Done\n\nThe complete reverse engineering chain:\n\n1. **QNX IFS extraction** — LZO decompression of firmware image (227 blocks, 6.8MB → 14.2MB)\n2. **Binary extraction** — 129 files from IFS directory structure\n3. **Ghidra decompilation** — PCM3Root loaded as SH4A ELF, 12,604 functions analyzed\n4. **Function tracing** — Located `CPPorscheEncrypter::verify` via string cross-references\n5. **Algorithm identification** — Modular exponentiation (square-and-multiply) at `FUN_082405a0`\n6. **Key extraction** — RSA parameters found in literal pool as hex strings\n7. **Modulus factoring** — 64-bit modulus factored in milliseconds via Pollard's rho\n8. **Private key computation** — `d = e^(-1) mod φ(n)`\n9. **VIN mapping** — Weighted sum with 16-bit overflow, verified against all 27 known pairs\n10. **Plaintext discovery** — Character-by-character interleaving (not concatenation)\n11. **USB delivery** — `proc_scriptlauncher` + `copie_scr.sh` autorun mechanism\n\n## Known Limitations\n\n- **Missing SubIDs for some model variants** — Panamera (970/9P), Macan (95B), Cayman/Boxster (987/981), GT3/GT2 SubIDs are not yet decoded. If you have a working FeatureLevel code for one of these, open an issue — the SubID can be recovered by trial decryption and added to the model table.\n- **TVINF may also be model-keyed** — 5 test records don't match the default `0x0166` SubID. Pattern matches FeatureLevel, suggesting per-model variance. Needs more samples to fully decode.\n- **No retail activation for FeatureLevel** — dealers charge ~$3500 for this code after a PCM swap. PCM-Forge generates it for free, but for your specific vehicle variant only. Wrong SubID = wrong code.\n\n## Related Projects\n\n**By platform:**\n\n| Generation | Platform | Your car? | Tool |\n|-----------|----------|-----------|------|\n| PCM 3.1 (SH4 / QNX 6.3) | Harman Becker | Cayenne 958, 911 991.1, Panamera 970, Boxster/Cayman 981, Macan 95B | **PCM-Forge** (this repo) |\n| MMI 3G / 3G+ (SH4 / QNX 6.3) | Harman Becker | Audi A4–A8 (B8/B8.5/C6/C7/D3/D4), VW Touareg 7P with RNS-850 | **[MMI3G-Toolkit](https://github.com/dspl1236/MMI3G-Toolkit)** |\n| PCM 4 / MHI2 / MIB2 (Tegra ARM / QNX 6.5) | Harman | Panamera 971, 911 991.2+, 718, refreshed Macan | [M.I.B.](https://github.com/Mr-MIBonk/M.I.B._More-Incredible-Bash), [harman-f AIO updates](https://github.com/harman-f) |\n| MIB3 / MIB4 / E3 (ARM / Linux) | Continental / CARIAD | Post-2020 VAG vehicles | Not yet reverse-engineered |\n\n**Same feature-identifier scheme across PCM 3.1 ↔ PCM 4 / MIB2:** Porsche reused the `SWID.SubID` hex structure when moving from Harman Becker to Harman's Tegra-based MIB2 platform. The FEC codes documented in [harman-f's AIO firmware patches](https://github.com/harman-f/MHI2_US_POG11_K5186_1-MU1476-AIO#features) confirm the scheme carried forward — our `0x0003`, `0x0005`, `0x0007` FeatureLevel values for 911 variants map to their MIB2 FEC entries. But the **activation mechanisms are completely different**: PCM 3.1 strictly validates RSA signatures (PCM-Forge forges them via modulus factoring), while PCM 4 / MIB2 skips signature validation entirely (harman-f just writes all-0xFF where a signature should be). See [research/CROSS_PLATFORM_NOTES.md](research/CROSS_PLATFORM_NOTES.md) for a full comparison of binary formats, exploit surfaces, and delivery mechanisms across generations.\n\n**Tools on the VAG side of the Harman family tree:**\n\n- [**jilleb/mib2-toolbox**](https://github.com/jilleb/mib2-toolbox) — The canonical MIB2-HIGH toolbox (848 ⭐). Same generation as PCM 4; different brand (VAG passenger cars vs Porsche). Pattern our MMI3G-Toolkit is inspired by\n- [**jilleb/mib1-toolbox**](https://github.com/jilleb/mib1-toolbox) — MIB1-HIGH predecessor. Closest VAG analog to our PCM 3.1 generation\n- [**jilleb/odis2vcp**](https://github.com/jilleb/odis2vcp) — Converts ODIS XML to VCP XML. Useful if you have ODIS and want to pull datasets for use with VCDS/VCP tools\n- [**jilleb/binary_tools**](https://github.com/jilleb/binary_tools) — Minimal Python scripts for binary file comparison. PCM-Forge's `tools/diff_fw.py` is an expanded version of this approach\n\n## Credits\n\n- **harman-f** — PCM 4 / MIB2 firmware patching research. Their `addfec` shell script was the Rosetta Stone for documenting the MIB2 FecContainer.fec binary format in our [CROSS_PLATFORM_NOTES.md](research/CROSS_PLATFORM_NOTES.md)\n- **jilleb** — The `tools/diff_fw.py` firmware comparison tool was inspired by [jilleb/binary_tools](https://github.com/jilleb/binary_tools) `find_identical_ranges.py`. The concept of toolbox-shaped feature flag exploration came from [jilleb/mib1-toolbox](https://github.com/jilleb/mib1-toolbox) and [mib2-toolbox](https://github.com/jilleb/mib2-toolbox)\n- **The Porsche/Harman IOC firmware engineers** — for leaving PagSWAct.csv (27 test vectors) inside the firmware bundle. Those 27 records made 100% algorithm verification possible\n\n## License\n\nMIT License — See [LICENSE](LICENSE)\n\n## Disclaimer\n\nFor research and educational purposes. Use at your own risk. The authors are not responsible for any damage to vehicles or components.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdspl1236%2Fpcm-forge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdspl1236%2Fpcm-forge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdspl1236%2Fpcm-forge/lists"}