WinKFP / EDIABAS reverse engineering research — looking for real-hardware testers

Post #1

Arkayda

Watchlisted

Joined
26.09.2026
Messages
4
Reactions
1
Hi everyone,

I’m working on an open research project focused on reverse engineering and reproducing parts of the BMW WinKFP / EDIABAS flashing stack:


The project is focused on understanding the actual runtime behaviour rather than simply implementing a new flashing tool.

So far I have been researching and testing:

  • WinKFP / winkfpt execution flow
  • EDIABAS API interaction
  • VDLE programming sequence
  • INIT_VDLE / REQUEST_SEGMENTINFO / SEND_SEGMENT / RESEND
  • TesterPresent and diagnostic session handling
  • WinKFP security-access/authentication flow
  • SGIDC / SGIDD authentication containers
  • symmetric / simple / asymmetric authentication paths
  • differential testing against reconstructed implementations
  • EDIABAS API emulation and real EDIABAS API contact
  • safety and programming-state validation

The next step is real-hardware validation over K+DCAN.

I’m particularly interested in comparing an original WinKFP session with the reconstructed implementation:

WinKFP -> EDIABAS -> IFH -> K+DCAN -> BMW ECU

I’m looking for people who have experience with:

  • BMW E60/E9x and similar E-series vehicles
  • WinKFP + EDIABAS
  • K+DCAN interfaces
  • EDIABAS/IFH tracing
  • WinKFP programming logs
  • BMW SP-Daten
  • reverse engineering of BMW diagnostic/flashing software

Initially I’m mainly interested in collecting diagnostic/session traces and understanding the communication sequence. I’m not looking for someone to experiment with an unknown ECU or perform risky flashing.

If anyone has already captured useful WinKFP/EDIABAS traces over K+DCAN, or has experience instrumenting the EDIABAS/IFH layer, I would be very interested in comparing results.

The goal is to document the protocol and runtime behaviour in a reproducible way and eventually understand how far the original WinKFP functionality can be reproduced with an independent implementation.

Any technical information, corrections, observations, or pointers to e
xisting research are welcome.

Thanks!
Arkayda
 
Ratings and Reviews
Total ratings: 0

Post #2

Quick progress update since the original post.

A lot more has been reproduced since then, including several parts that were initially only hypotheses.

On the WinKFP side, I was able to reproduce and differentially validate the actual runtime behaviour of the original executable rather than just implementing an assumed protocol.

Some of the results so far:

- Reproduced the VDLE job flow from the original WinKFP runtime:
INIT_VDLE -> REQUEST_SEGMENTINFO -> SEND_SEGMENT / RESEND
  • Recovered the actual FLASH_SCHREIBEN block layout, including little-endian address encoding and the duplicated length fields.
  • Reproduced TesterPresent scheduling and the related diagnostic-session handling.
  • Recovered and validated the three WinKFP authentication paths: Symmetric, Simple and Asymmetric.
  • Reproduced the MSVC rand() behaviour used by the Symmetric authentication path.
  • Reproduced the RSA byte-order / bignum handling used by the original code.
  • Parsed the actual SGIDC / SGIDD authentication-container format and identified the relationship between authentication method and key type.
  • Executed the original authentication/key-generation code under emulation and compared the resulting output against the original runtime.
  • Built a reconstructed EDIABAS layer and performed event-by-event differential testing against the original WinKFP behaviour.
  • Implemented a native EDIABAS API adapter and validated the API lifecycle independently.
  • Reproduced the signature-checking / polling result semantics used by the original programming flow.
  • Reconstructed parts of the original EDIABAS/IFH communication path, including the lower-level transport behaviour.

The interesting part is that this has now reached the physical layer as well.

I implemented a standalone native K+DCAN transport in the research repository (no runtime dependency on my other project) and connected it directly to a real E60/ZF 6HP EGS.

The first physical validation was intentionally read-only.

For example, the following request was sent directly from the reconstructed transport:

TX:
82 18 F1 1A 86 2B

The ECU returned the expected-format AIF response, and repeated runs produced byte-for-byte identical TX/RX frames. Only the response timing varied.

I also captured and reproduced the physical response to:

TX:
82 18 F1 3E 00 C9

Again, the raw wire traffic is now being treated separately from higher-level job mappings.

This distinction is important: I am only marking something as an observed WinKFP job mapping when there is direct evidence from the original EDIABAS/SGBD execution. A physically observed diagnostic frame by itself is not being used to claim that a particular WinKFP job produces it.

At this point the project has essentially three independently testable layers:

1. Original WinKFP runtime behaviour
2. Reconstructed WinKFP/EDIABAS behaviour
3. Direct physical K+DCAN communication with the ECU

The next phase is to correlate these layers using controlled read-only hardware traces before touching any programming operation.

The research repository has also been sanitized: previously recovered proprietary OEM key material was removed from the public history and the public authentication fixtures are now synthetic.

Still very interested in comparing traces with anyone who has WinKFP/EDIABAS logs from an E-series car, especially raw IFH/K+DCAN traffic :sneaky::unsure:
 

Post #3

That's impressive progress on the reverse-engineering front. The differential validation approach — especially emulating the original x86 code and comparing event-by-event output — is a solid methodology for confirming you're reproducing actual runtime behavior rather than guessing at protocol semantics.

A few observations based on what you've described:

Authentication path coverage
You've identified and validated all three authentication methods (Symmetric MD5, Simple XOR, Asymmetric RSA). The MSVC rand() reproduction is a good detail to catch — tester nonce generation matters for replay resistance, and matching the original PRNG state is key for differential testing. The RSA bignum byte-order handling is also a common source of divergence between implementations (big-endian vs. little-endian encoding of modulus and exponents).

VDLE block structure
The little-endian address encoding and duplicated length fields in FLASH_SCHREIBEN blocks align with typical bootloader CAN/KWP2000 transport conventions. The duplication is usually a basic integrity check or header/footer consistency marker.

EDIABAS layer reconstruction
Building a mock EDIABAS layer and performing event-log differential testing is the right approach for isolating WinKFP behavior from the underlying bus/IFH layer. The API lifecycle validation (init, job execution, result polling, cleanup) gives you confidence that the reconstructed stack can serve as a drop-in emulation target.

Next step: K+DCAN hardware validation
Since you're now looking for real-hardware testers, a few practical suggestions:

  • Start with read-only diagnostics: Before attempting any VDLE flash sequence, validate the diagnostic session establishment, seed/key authentication, and TesterPresent keepalive against a real ECU. This confirms timing, transport framing, and session management without write risk.
  • Capture parallel traces: Run the original WinKFP and your reconstructed implementation back-to-back on the same ECU, capturing full IFH/EDIABAS traces. Compare telegram-level output (addresses, payloads, timing gaps) to identify any remaining divergence.
  • Bench setup first: If possible, test on a bench ECU (DME/EGS pulled from a scrapped vehicle) with stable 13.5V supply and no vehicle CAN bus activity. This eliminates variables like gateway interference, sleep mode, and multi-ECU contention.
  • Target a well-documented ECU: E60/E9x MS4x or MSV70 DME variants, or ZF 6HP EGS units, are relatively common and have known SP-Daten variants. Starting with a widely flashed ECU gives you more reference material and community knowledge.

Looking at your GitHub repo structure, the evidence model (L0–L7) and the explicit safety interlocks in reconstruction/safety/ are solid practice. The fact that you're clearly separating "validated in emulation" (L4) from "validated on physical ECU" (L6/L7) shows you're taking this seriously.

If you're looking for hardware testers, you'll likely need people who already have a K+DCAN interface (INPA-compatible USB or Ethernet adapter), a working WinKFP/EDIABAS/NCS setup, and ideally a bench ECU they can afford to brick if something goes wrong. Anyone willing to test should also be comfortable capturing and sharing sanitized EDIABAS .trc files and event logs.

Let me know if you want help with trace analysis, differential log parsing, or specific protocol details once you start collecting hardware data.
 

Post #4

That's impressive progress on the reverse-engineering front. The differential validation approach — especially emulating the original x86 code and comparing event-by-event output — is a solid methodology for confirming you're reproducing actual runtime behavior rather than guessing at protocol semantics.

A few observations based on what you've described:

Authentication path coverage
You've identified and validated all three authentication methods (Symmetric MD5, Simple XOR, Asymmetric RSA). The MSVC rand() reproduction is a good detail to catch — tester nonce generation matters for replay resistance, and matching the original PRNG state is key for differential testing. The RSA bignum byte-order handling is also a common source of divergence between implementations (big-endian vs. little-endian encoding of modulus and exponents).

VDLE block structure
The little-endian address encoding and duplicated length fields in FLASH_SCHREIBEN blocks align with typical bootloader CAN/KWP2000 transport conventions. The duplication is usually a basic integrity check or header/footer consistency marker.

EDIABAS layer reconstruction
Building a mock EDIABAS layer and performing event-log differential testing is the right approach for isolating WinKFP behavior from the underlying bus/IFH layer. The API lifecycle validation (init, job execution, result polling, cleanup) gives you confidence that the reconstructed stack can serve as a drop-in emulation target.

Next step: K+DCAN hardware validation
Since you're now looking for real-hardware testers, a few practical suggestions:

  • Start with read-only diagnostics: Before attempting any VDLE flash sequence, validate the diagnostic session establishment, seed/key authentication, and TesterPresent keepalive against a real ECU. This confirms timing, transport framing, and session management without write risk.
  • Capture parallel traces: Run the original WinKFP and your reconstructed implementation back-to-back on the same ECU, capturing full IFH/EDIABAS traces. Compare telegram-level output (addresses, payloads, timing gaps) to identify any remaining divergence.
  • Bench setup first: If possible, test on a bench ECU (DME/EGS pulled from a scrapped vehicle) with stable 13.5V supply and no vehicle CAN bus activity. This eliminates variables like gateway interference, sleep mode, and multi-ECU contention.
  • Target a well-documented ECU: E60/E9x MS4x or MSV70 DME variants, or ZF 6HP EGS units, are relatively common and have known SP-Daten variants. Starting with a widely flashed ECU gives you more reference material and community knowledge.

Looking at your GitHub repo structure, the evidence model (L0–L7) and the explicit safety interlocks in reconstruction/safety/ are solid practice. The fact that you're clearly separating "validated in emulation" (L4) from "validated on physical ECU" (L6/L7) shows you're taking this seriously.

If you're looking for hardware testers, you'll likely need people who already have a K+DCAN interface (INPA-compatible USB or Ethernet adapter), a working WinKFP/EDIABAS/NCS setup, and ideally a bench ECU they can afford to brick if something goes wrong. Anyone willing to test should also be comfortable capturing and sharing sanitized EDIABAS .trc files and event logs.

Let me know if you want help with trace analysis, differential log parsing, or specific protocol details once you start collecting hardware data.

Thanks - that's pretty much the direction I'm taking.

One distinction I'm being very strict about is separating runtime evidence from physical wire evidence.

The authentication algorithms are already validated against the original WinKFP runtime/emulated execution, but I don't want to jump directly to real-ECU seed/key testing. The immediate hardware milestone is deliberately read-only: establish the native K+DCAN path, capture deterministic TX/RX traffic, and correlate it with existing WinKFP/EDIABAS traces.

I'm also treating the duplicated length fields in FLASH_SCHREIBEN as an observed structural property for now, rather than assuming they are an
integrity mechanism until there is direct evidence for that.

The parallel-trace approach is exactly what I want to do next: original WinKFP/EDIABAS trace -> reconstructed implementation -> physical wire trace, with each layer kept separately classified.

Once that correlation is solid, authentication/session behaviour can be looked at as a separate milestone rather than mixing it into the initial hardware validation :)
 

Post #5

Thanks - that's pretty much the direction I'm taking.

One distinction I'm being very strict about i...

That's the right sequencing. Keeping runtime validation, wire-level correlation, and authentication testing as separate milestones avoids conflating evidence types — especially when you're building a reproducible claim about what the original code actually does versus what happens on the bus.

The read-only hardware milestone is a clean gate: you're confirming that your reconstructed EDIABAS/IFH layer produces the same K+DCAN telegrams that the original stack does for non-invasive diagnostic operations (e.g., VIN read, status queries, session establishment without write jobs). That gives you wire-level ground truth before introducing any state-changing operations.

On the FLASH_SCHREIBEN block structure, treating the duplicated length as an observed artifact rather than an assumed CRC or integrity field is the correct stance until you either see the ECU reject a block with mismatched lengths or find the bootloader code that validates it. It could be a legacy layout convention, a transport-layer requirement, or simply redundant framing — the wire will tell you.

The parallel-trace correlation methodology (original trace → reconstructed trace → physical wire capture) is solid. Once you have deterministic TX/RX alignment for known-good sessions, you can confidently move authentication and seed/key exchange into scope as a controlled experiment rather than an untested leap.

Looking forward to seeing the K+DCAN correlation results once you have hardware access.
 

Post #6

Quick progress update since the previous comment.

The work has moved beyond the initial physical transport proof and into correlating the original WinKFP/SGBD definitions with the actual EGS wire behaviour.

Several previously ambiguous physical frames are now resolved from the original SP-Daten / SGBD sources rather than inferred from the raw traffic alone.

For the GKE195 / 10FLASH EGS path, I was able to correlate and validate:

  • 1A80 as the IDENT job, including the BMW part number / hardware ID fields and the embedded software-identification fields.
  • 1A87 as PHYSIKALISCHE_HW_NR_LESEN, returning the physical ECU hardware number (PECUHN).
  • the 1A80 / 1A87 relationship and the corresponding fallback behaviour directly from the 10FLASH SGBD implementation.
  • AIF_LESEN as a ReadMemoryByAddress (0x23) operation with the concrete address/length payload used by the SGBD.
  • ZIF / reference-data jobs as separate 0x22 subfunctions rather than treating every reference read as an 0x1A service.
  • the factory trace target address (0x78) and the physical EGS target address (0x18) as separate evidence domains.

This also exposed and corrected several terminology / provenance mistakes from the earlier reconstruction.

In particular, a physically observed 0x1A86 frame is now kept explicitly as a reconstruction / bench alias unless there is direct SGBD evidence that a named WinKFP job produces that frame.

Likewise, the physical 1A80 fields are no longer being labelled as ZB/SW values simply because they are numeric part numbers. Their actual meanings are taken from the decoded 10FLASH implementation.

On the runtime side, I also introduced a clean read-only transport boundary:

EDIABAS Job API
-> CanonicalPipeline
-> DiagnosticTransport
-> raw DS2 response
-> ResponseValidator
-> SGBD parser
-> EdiabasJobResult

The new DiagnosticTransport interface operates only on complete DS2 wire frames and knows nothing about SGBD jobs, WinKFP semantics or evidence classification.

Two deterministic transport implementations are now available for offline execution:

  • FixtureTransport for replaying pinned physical traces
  • MockTransport for synthetic/error-path testing

The canonical replay and pipeline code can now use the same transport interface instead of having separate execution paths for fixture replay and transport-backed execution.

The transport layer also now has explicit fail-closed handling for:

  • timeouts
  • low-level transport errors
  • malformed DS2 framing
  • checksum failures
  • addressing mismatches
  • unexpected response IDs
  • ECU negative responses
  • unsupported / write-side jobs before anything reaches the transport

The entire regression suite is currently green:

153 tests
153 passed
0 skipped
0 failed

The canonical hardware trace JSON files remain byte-for-byte unchanged.

The physical side is still intentionally read-only. No SecurityAccess request, programming request, erase routine, transfer-data operation or ECU reset is part of this validation phase.

The important distinction at this point is that the project now has three correlated but separately testable layers:

1. Original WinKFP / EDIABAS runtime behaviour
2. Offline reconstructed WinKFP / EDIABAS behaviour
3. Direct physical K+DCAN communication with the EGS

The current effort is focused on keeping those layers strictly separated while correlating them through evidence-backed service mappings and deterministic replay.

There are still explicit UNKNOWNs, especially where a physical frame has not yet been captured for a service that is already confirmed from the SGBD definition.
 

Post #7

The post cuts off mid-sentence ("...simply becau"), so I'm missing the end of the update and whatever question or request it closes with. Can you paste the rest, and tell me what you want from me? For example, a reply for thread #2611, a technical review of the claims, or a cleaned-up write-up of the findings.From what's visible, the technical framing holds up:
  • 0x1A is KWP2000 ReadEcuIdentification, so 1A80 as the main IDENT record and 1A87 as a separate hardware-number option is consistent with how BMW SGBDs split identification jobs.- AIF_LESEN as 0x23 ReadMemoryByAddress with a fixed address and length matches how the AIF block is usually read on this generation of ECUs.- Treating ZIF and reference reads as 0x22 identifiers, rather than forcing everything into 0x1A, is a sensible correction.- Keeping the trace address (0x78) and the physical EGS address (0x18) as separate evidence domains avoids mixing gateway or tester artifacts with real ECU behaviour.- Marking 0x1A86 as a bench alias until an SGBD job is shown to emit it is good provenance discipline.Some things you could suggest in a reply:
  • A per-job mapping table of SGBD job name → request bytes → target address → response offsets → SGBD result names (for example IDBMWNR, IDHWNR). This would make the 1A80/1A87 field correlation checkable by testers.- Documenting the exact negative response (7F 1A xx) that triggers the 1A87 fallback. Other people's hardware may return a different NRC.- Asking testers to report EGS variant and software level along with their traces, since the IDENT layout can differ between variants.Send the rest of the post and I'll put together whichever of these you need.
 
Activity
So far there's no one here