Skip to content

Repository files navigation

PCM-Forge

Open-source activation code generator and toolkit for Porsche PCM 3.1 infotainment systems.

🔓 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.

🌐 Web tool: dspl1236.github.io/PCM-Forge — activation codes, USB stick builder, and modular diagnostic toolkit.

📋 What can I activate? → See FEATURES.md for the full list of 26 features with descriptions, retail costs, and hardware requirements.

Supported Vehicles

All Porsche models with PCM 3.1 (Harman Becker, SH4A QNX 6.3):

Model Years Notes
Cayenne (958) 2011–2018 Primary development target
Panamera (970) 2011–2016 Compatible
911 (991.1) 2012–2016 Compatible
Boxster/Cayman (981) 2013–2016 Compatible
Macan (95B) 2014–2018 Compatible (pre-refresh)

Not compatible with: PCM 3.0 (Cayenne 957, 997, 987 — older hardware, different activation algorithm), PCM 4 / MIB2 (991.2+, 718, Panamera 971, refreshed Macan — ARM platform, different architecture).

Hardware Revisions & Firmware

PCM 3.1 has three hardware revisions. The update disc auto-detects your hardware and installs the correct version — it will not flash the wrong firmware.

Hardware Code Max Firmware Era IOC
Gen 1 "9600" PCMG01XX v2.47 2010–2012 9600
Series 1 "9612" PCMS01XX v3.43 2012–2013 9612
Series 2 "9633" PCMS02XX v4.76 2013–2018 9612

Check your version: press INFO → Option → Show System Version.

Firmware update ISO (v4.76 / v3.43 / v2.47 — all in one): hausofdub.com/iso/PCM_NA_20150721.ISO — burn to DVD-R (Verbatim recommended, 4x speed). North America region, also confirmed working on ROW units.

Wiring diagrams: hausofdub.com/wireview — browse by model, year and system. Each sheet shows its connector pinout alongside the drawing, and prints or exports to SVG and PNG. The PCM and gateway connectors this project works against are in research/CAYENNE_958_PINOUTS.md.

PCM-Forge activation compatibility: Tested and verified on PCMS02XX (v4.76). The RSA-64 algorithm is firmware-independent, but v2.47 and v3.43 are untested — if you're on older firmware and have issues, run the diagnostic USB and open an issue.

Web App

The web app at dspl1236.github.io/PCM-Forge has four tabs:

Tab 1: Activation Codes

Enter your VIN → generates all 26 activation codes instantly. No server, no account, runs entirely in your browser.

Tab 2: USB Stick Builder

Builds a ready-to-use USB stick with activation codes and optional diagnostic probe. The USB stick uses the same copie_scr.sh autorun mechanism as Audi MMI3G — proc_scriptlauncher runs the script automatically when the USB stick is inserted.

Includes an enhanced diagnostic mode that dumps 29+ system tests to the USB stick without modifying the car.

Tab 3: Toolkit

Modular USB toolkit for PCM 3.1 diagnostics and utilities. Select modules and build a USB stick — each module is fetched from modules/ at build time, so the list stays in sync with the repo:

Module Status Description
System Info ✅ Ready Full PCM dump: version, VIN, mounts, processes, network, partitions, IPC, engineering screens
Telnet Enabler ✅ Tested Root shell — telnet (port 23) + raw ksh (2323). Session-only, re-run after reboot
USB Ethernet ✅ Tested Universal ASIX driver (AX88772 / 772A / 772B / 772C) with DHCP / static / LTE. Loads from USB, never touches flash
IOC Probe ✅ Ready Map IPC/CAN channels and discover the BAP instrument-cluster interface. Read-only
BT / AUX Fix 🧪 Experimental Stops the PCM defaulting to FM at startup — routes a connected phone to Bluetooth (A2DP). Self-locating runtime patch, reboot-reverts
Service Reset 🧪 Alpha Oil / service interval reset via UDS/BAP CAN. No PIWIS needed
LTE Setup ⚠️ Deprecated Superseded by USB Ethernet (which includes an LTE mode)

Tab 4: Backup

Upload the PagSWAct_backup.002 that Diagnostic mode pulls off the PCM to see exactly what's currently activated, then add features on top and download a merged PagSWAct.002 — so you keep every existing activation instead of overwriting them.

Data Connectivity & LTE Restoration

The PCM 3.1's built-in Cinterion AC75i modem (2G GPRS/EDGE) is dead after the 2G/3G network shutdown (US 2022, EU ongoing). Internet can be restored via USB ethernet:

USB port → AX88772 adapter → LTE router → internet
Driver: devn-asix.so (already in PCM firmware)
Interface: en5 (same as Audi MMI3G+)

Compatible chipsets: ASIX AX88772, AX88772A, AX88772B. The AX88772D is not auto-detected but works with a device ID override: io-pkt-v4-hc -d asix did=0x772D,vid=0x0B95 (QNX documentation).

See research/PCM31_CONNECTIVITY.md for the full LTE restoration guide including hardware list, network architecture, and what online services may still work.

Choosing a USB Stick

The stick itself is the most common reason nothing happens. If you insert the stick and the PCM shows no status screen and writes no pcm_ran.txt, the stick is the first thing to suspect — not your files.

What works: an ordinary USB 2.0 flash drive, FAT32, MBR partitioning. Capacity does not matter — a 2 GB drive works as well as a 64 GB one. Neither does cluster size, and you do not need to format it in any special way. Any plain stick you would put music on is fine.

What does not work: a drive that announces itself as more than one device — SanDisk's old U3 sticks are the classic example, presenting a virtual CD-ROM for their auto-start software alongside the data partition — because this generation's QNX mass-storage driver appears to stop at the first unit it finds and never mounts the one your files are on. The symptom is silence: the stick may not even show up as a media source, and nothing is written back to it. Reformatting cannot help, since the problem sits below the file system; use a plain drive instead.

Dead ends — don't waste time on these

All of the following were tested on the car and made no difference:

  • Drive capacity. A 2 GB drive triggers the autorun just fine.
  • Cluster size. 4 KB works; you do not need 32 KB.
  • MBR partition type. The PCM mounts both 0x0B and 0x0C (it names the device /dev/umass/usb…t11 and …t12 respectively).
  • Partition offset. 128 sectors and 2048 sectors both work.
  • macOS metadata. ._* AppleDouble files, .Spotlight-V100, .Trashes and System Volume Information are harmless — a drive full of them works.
  • Other files on the stick. Music, photos and unrelated folders do not interfere.

If you build the stick on macOS

Everything works out of the box, but two conveniences:

dot_clean -m /Volumes/YOUR_STICK   # removes the ._* companion files
diskutil eject /Volumes/YOUR_STICK

Insert the stick only after the PCM has finished booting (home screen visible). A drive already present at power-on is treated as plain media storage and the script never runs.

⚡ Quick Start

Important: Always use the web app to build your USB stick. Do NOT download copie_scr.sh directly from GitHub — the PCM requires a special XOR-encoded version that only the web app generates. Raw files from the repo will not trigger the autorun.

Step 1: Run Diagnostics First

  1. Open dspl1236.github.io/PCM-Forge
  2. Go to the USB Stick tab
  3. Enter your 17-digit VIN
  4. Leave Diagnostic mode checked (default)
  5. Click Save to folder → select your FAT32 USB drive
  6. Insert USB after the PCM has fully booted (wait for the home screen — do NOT insert before starting the car), wait 60–90 seconds
  7. Remove USB — check for pcm_debug.log and pcm_dump/ folder on the drive

Step 2: Activate Features

  1. Review your diagnostic results to see what's currently active
  2. Go back to the USB Stick tab
  3. Uncheck Diagnostic mode
  4. Click Select all to keep all existing features (or pick individual ones)
  5. Click Save to folder → select your FAT32 USB drive
  6. Insert USB after PCM has booted, wait 60–90 seconds, remove, hard reboot (hold INFO + CAR until screen goes black)

⚠️ The activation file (PagSWAct.002) replaces all existing activations. Only the features you select will be active — anything not selected gets deactivated. Always use Select all and then add new features on top.

Step 3: Verify

Press SOURCE + SOUND simultaneously — if the ENGINEERING feature is activated, the hidden engineering menu will appear. This confirms your activation codes are working.

Just Need Codes? (for PIWIS / manual entry)

Use the Codes tab — enter your VIN, get all 26 activation codes instantly. No USB stick needed — enter codes manually via PIWIS or the engineering menu.

Replacement / Used PCMs

If you installed a used PCM from another car, activation codes won't work because the PCM validates against its internally stored VIN (the donor car's VIN). Fix this with PCM-Forge alone — no dealer needed:

  1. Run Diagnostic Mode via USB to pull the donor VIN from the PCM
  2. Enter the donor VIN in PCM-Forge and activate ENGINEERING (GEM)
  3. In the Engineering menu, update the VIN to your car's VIN (under SW Activations)
  4. Re-run PCM-Forge with your real VIN to activate all features

Command Line

generate_codes.py does everything the web app does, from a terminal. Same algorithm, same files, same bytes — the test suite checks that byte for byte. Useful for scripting, for inspecting a stick that came back from the car, and for anything you would rather not do by clicking. Python 3 and the standard library, nothing to install.

python generate_codes.py <VIN>                              # print all 27 codes
python generate_codes.py <VIN> <USB_PATH>                   # build an activation stick
python generate_codes.py --diag <USB_PATH>                  # build a diagnostic stick
python generate_codes.py --show <PATH>                      # decode a PagSWAct.002
python generate_codes.py <USB_PATH> --from-backup           # rebuild from the car's own backup
python generate_codes.py --list-models                      # model keys for --model
python generate_codes.py --list-features                    # feature names
Flag What it does
--model KEY Sets the FeatureLevel, which is the boot logo and model identity
--featlevel-subid HEX The same thing by number, for a model the table does not list
--add, --remove Edit features in an existing PagSWAct.002; comma-separated, repeatable
--from-backup Rebuild an activation stick from what the car reported, using the <USB_PATH> the diagnostic run wrote — its backup and its VIN. Takes no argument; only when that stick holds several backups, name the one to use: --from-backup PagSWAct_backup_1234.002
--subid NAME=HEX Pick a non-default variant of a feature (map index, region)
--no-xor Write copie_scr.sh unencoded — for inspection only, the PCM will not run it
--quiet Codes only, no headings

The usual round trip, once per car:

python generate_codes.py --diag /Volumes/STICK        # 1. pull the car's current state
python generate_codes.py --show /Volumes/STICK        # 2. read what came back
python generate_codes.py /Volumes/STICK --from-backup --add SDARS,TEL          # 3. add to it

None of those three needs you to type a VIN. The diagnostic run copies the car's own VIN onto the stick, and step 3 reads it back from there — which matters with a used head unit, where the diagnostic run is how you find out what VIN it holds in the first place. Pass one explicitly if you want to override it; either way it is checked against the backup, so codes from two different cars cannot end up in one file. --from-backup keeps everything the car already had and adds to it, instead of replacing the lot.

A VIN is checked against ISO 3779/3780 before anything is generated: 17 characters, no I, O or Q, numeric tail. Anything that is merely suspicious — a non-Porsche WMI, a check digit that does not add up, a model year outside the PCM 3.1 era — is reported and then ignored, because none of those is reliable enough to refuse work over.

Running the tests

Only needed if you change something. pytest is the sole dependency and only the tests use it.

pip install pytest
python -m pytest tests/ -q                                   # all of it, about a third of a second
python -m pytest tests/ -k factory -v                        # one group
python -m pytest tests/test_generate_codes.py::TestShow -v   # one class

What the suite is actually guarding:

  • Real factory codes. research/firmware/PagSWAct.csv holds 487 genuine activation codes from 22 cars. The tests decrypt each one with the public exponent — the same operation the head unit performs — and require it to yield its own SWID and VIN hash. This is the only check in the project that does not share the code's own assumptions, so treat a failure here as the algorithm being wrong rather than the test.
  • Parity with the web app. Feature names, hex values, the ksh payloads and the encoded bootstrap are compared against docs/index.html. Changing one side without the other fails the suite on purpose: the two must emit identical sticks.
  • Line endings. payloads/*.sh must stay LF. A CRLF that reaches the head unit's shell stops the script dead, and the failure on the car is silent.

If you add a check, sabotage it once before you trust it: break the thing it is meant to catch and confirm the test fails. Several tests here passed at first for the wrong reason — a VIN whose forbidden letter sat where a different rule caught it first, an assertion that matched the temporary directory's name rather than the output.

How It Works

Activation Algorithm

The PCM 3.1 uses a 64-bit RSA scheme to validate activation codes:

VIN → 8-position extraction → weighted sum → mod 2^16
Feature SWID + SubID → 4-byte record key
Record key → RSA encrypt with private key → 8-byte activation code
PCM verifies: RSA decrypt with public key → matches record key

The RSA keys (N, E, D) were extracted from CPPorscheEncrypter::verify in the QNX firmware binary via Ghidra SH4 decompilation. The 64-bit key size makes factorization trivial — the private exponent was recovered in seconds.

Script Execution

The PCM 3.1 uses the same autorun mechanism as Audi MMI3G: proc_scriptlauncher monitors the USB port for copie_scr.sh, which is XOR-encoded with a known PRNG seed. The web app handles encoding automatically.

Platform Architecture

PCM 3.1 shares the Harman Becker HN+ platform with Audi MMI3G+ and VW RNS-850:

Component Details
CPU Renesas SH4A (SH7786/SH7785)
OS QNX 6.3.2 (PSP3)
Application PCM3Root (native C++ binary, ~6MB)
IOC Renesas V850 with CMX-RTX RTOS
Display 7" touchscreen, 800×480
Storage Internal SATA HDD
Modem Cinterion AC75i (2G, dead after network shutdown)
USB ethernet devn-asix.so (ASIX AX88772) in firmware
Autorun proc_scriptlauncher + copie_scr.sh via USB

Note: Unlike Audi MMI3G+ which uses Java/J9 for the UI, PCM 3.1 uses a native C++ application (PCM3Root). The IFS images use LZO1X compression inside Harman's hbcifs container — decompressible back to a standard QNX IFS with the repo's tooling.

Project Structure

PCM-Forge/
├── docs/                        # GitHub Pages site (client-side, no build)
│   ├── index.html               #   Web app (Activation, USB Stick, Toolkit, Backup)
│   ├── app/manifest.json        #   Auto-generated module index (built from modules/)
│   ├── bootscreens/             #   Boot-logo PNGs offered in the USB builder
│   └── fonts/                   #   Self-hosted webfonts
├── modules/                     # Toolkit modules — each a self-contained USB tool
│   ├── bt-aux-fix/              #   FM->A2DP boot fix (module.json + scripts/ + bin/)
│   ├── usb-net/                 #   universal ASIX USB-ethernet
│   └── sysinfo/ telnet/ ioc-probe/ service-reset/ lte-setup/
├── builder/generate_manifest.py # Regenerates docs/app/manifest.json from modules/
├── core/                        # Shared USB payload assets
│   ├── bin/                     #   SH4 helpers (showScreen, forge_splash, ndr_probe)
│   └── lib/                     #   status images (running/done/activating .png + .bin)
├── generate_codes.py            # CLI code generator — byte-for-byte parity with the web app
├── payloads/                    # ksh scripts the CLI writes to the stick (run_*.sh)
├── tests/test_generate_codes.py # pytest: web-app parity + factory-code check
├── research/                    # 30+ reverse engineering docs (+ firmware/ Ghidra output)
│   ├── ALGORITHM_CRACKED.md     #   RSA-64 key recovery
│   ├── DISCOVERY_NARRATIVE.md   #   Full RE story
│   └── PCM31_CONNECTIVITY.md    #   LTE restoration guide
├── tools/                       # Host-side RE & firmware-analysis utilities
├── PCM4/                        # Separate PCM 4 / MIB2 research subtree (own README)
├── CLAUDE.md                    # Repo guide & safety conventions for contributors
├── FEATURES.md                  # Feature quick reference
└── LICENSE

Research Highlights

  • 64-bit RSA cracked from QNX SH4 firmware via Ghidra decompilation
  • 26 features mapped with retail costs ($150–$3,500 each)
  • USB autorun mechanism identical to Audi MMI3G+ (proc_scriptlauncher)
  • V850 IOC reverse engineered (CMX-RTX RTOS, CAN gateway)
  • LTE restoration path confirmed — devn-asix.so driver present in firmware
  • AX88772D workaround — QNX driver supports USB device ID override
  • Why the unit boots to FM — not because Bluetooth is slow, but because package 20 PHONE_AND_BLUETOOTH ships RequestState=STOP and is demand-started. No Harman platform of this era starts Bluetooth at boot (the Audi MMI does the same), so A2DP genuinely does not exist when the source is chosen. Which means every decision-layer patch is inert — including the byte patch we shipped, now measured dead on a car and paused. The fix has to ride the connect event. Also explains why debugTools.sh does not run at boot: research/BOOT_ORDER_AND_STARTER.md
  • Update discs decoded — the version ceilings are a dispatch table keyed on hardware ID, not a check; modules are RSA-1024 signed, so custom firmware cannot be installed by the OEM updater; and an official update wipes amplifier-profile edits and custom bootscreens: research/UPDATE_DISC_FORMAT.md
  • The HMI is data, not code — 34 HBM5 .mmi files hold every screen and 44,100 strings in ten languages; the compressed payloads are stock LZRW2; screens resolve to real geometry on an 800×480 display: research/HMI_MMI_FORMAT.md
  • PCM 3.0 vs 3.1 — different hardware generations, tools are PCM 3.1 only

Related Projects

  • MMI3G-Toolkit — Sister project for Audi MMI 3G/3G+ and VW RNS-850. Same Harman Becker platform, SD card delivery. Includes Google Earth restoration, 20+ modules, complete firmware reverse engineering.
  • DrGER2/MMI3GP-LAN-Setup — Original Audi LTE setup method (same adapter works on PCM 3.1)
  • WillCoder/PCM_31_AUX-BT — Found the BT/AUX boot fix and the /proc/as runtime-patch method that the BT / AUX Fix module builds on

Disclaimer

PCM-Forge modifies your PCM 3.1 head unit. The activation tool rewrites PagSWAct.002 (the original is backed up automatically). The toolkit modules go further — for example BT / AUX Fix patches the running PCM3Root in memory, Telnet opens a root shell, and USB Ethernet loads a network driver. All of it is designed to be brick-safe: everything runs from USB or a live /proc / /HBpersistence patch, nothing modifies the read-only firmware, and a reboot reverts runtime changes. Still, use at your own risk. This project is not affiliated with Porsche, Volkswagen Group, or Harman Becker.

License

MIT

About

Reverse engineering toolkit for Porsche PCM 3.1 infotainment systems (Cayenne 958, Panamera, 911 991.1, Boxster/Cayman, Macan)

Topics

Resources

Stars

35 stars

Watchers

3 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages