Announcement

Collapse
No announcement yet.

Flashing the MK60 with ZCP software

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    #91
    Oh shit, I might have found CCP commands in the PT(?)-CAN table.

    Table decodes out to a bunch of CAN IDs that I was going through and, after some indirection, I found a read of the presumed-CCP EEPROM flag through a function pointer. Fortunately 0x797 was the towards the top of the table

    Looking through the payload handler:

    Click image for larger version

Name:	Screenshot 2026-10-30 at 1.28.47 AM.png
Views:	33
Size:	410.7 KB
ID:	614066
    Click image for larger version

Name:	Screenshot 2026-10-30 at 1.20.47 AM.png
Views:	35
Size:	190.1 KB
ID:	614064
    tbl_0f2eb:
    Click image for larger version

Name:	Screenshot 2026-10-30 at 1.21.40 AM.png
Views:	34
Size:	97.2 KB
ID:	614065
    Click image for larger version

Name:	Screenshot 2026-10-30 at 1.49.32 AM.png
Views:	35
Size:	435.5 KB
ID:	614067

    (I still don't know what the `_DAT_00400948` check is. Presumably a `wheel_speed == 0` check since it comes from RAM?)

    So now we know the second conditional in `can_rx_797_payload()` will evaluate to true (because the CCP flag is set). If we go to the function that gets evaluated in the conditional, we see something that looks suspiciously like an interpreter:

    Click image for larger version

Name:	Screenshot 2026-10-30 at 2.24.00 AM.png
Views:	34
Size:	543.1 KB
ID:	614069

    Looking at a CCP command ref (e.g. https://mxhelp.danlawinc.com/ccp_xcp_reference.htm), the `UPLOAD` function (0x4) is immediately interesting. Follow the function call in `case 4:` and jackpot:

    Click image for larger version

Name:	Screenshot 2026-10-30 at 2.05.16 AM.png
Views:	34
Size:	99.9 KB
ID:	614070
    Click image for larger version

Name:	Screenshot 2026-10-30 at 2.05.39 AM.png
Views:	34
Size:	218.6 KB
ID:	614068

    An unauthed, unbounded read in a loop that writes to a buffer (ignore the decompiled C code in that last screenshot, it's not looking all that great). Looks like the `UPLOAD` function to me!

    Lots of words and code to say that I was wrong and I'm now pretty convinced that CCP is supported on the e5 AND it can dump flash.

    Since the EEPROM flag is present on the MK60 dump, I'm pretty confident that it will be supported there too. Amazing.

    I know what the first thing I'm going to do when I get that MK60 is!
    2002 Topasblau M3 - Coupe - 6MT - Karbonius CSL Airbox - SSV1 - HJS - Mullet Tune - MK60 Swap - E86 Front Triangulation - ZCP Rack - Nogaros - AutoSolutions - 996 Brembos - Slon - CMP - VinceBar - Koni - Eibach - BlueBus - Journal

    2012 Alpinweiss 128i - Coupe - 6AT - Slicktop - Manual Seats - Daily - Journal

    Comment


      #92
      Oh baby! Now we’re getting somewhere
      ‘02 332iT / 6 | ‘70 Jaguar XJ6 electric conversion

      Comment


        #93
        Nice work Heinz - this is epic! very much enjoying following this along!

        Originally posted by heinzboehmer View Post
        (ignore the decompiled C code in that last screenshot, it's not looking all that great)
        FWIW pretty much all of the weirdness in the Ghidra C-code view can be resolved by making sure your function parameters (number and datatype) and return value (datatype) are correct. For example
        Code:
        int can_rx_797_payload(void)
        I'm willing to bet if you follow where it's called the return value isn't actually used. If so, and you modify the function prototype in Ghidra to be a void return type you'll see a bunch of that weirdness clean itself up.

        2005 ///M3 SMG Coupe Silbergrau Metallic/CSL bucket seats/CSL airbox/CSL console/6 point RACP brace/Apex ARC-8s
        Build Thread | Community Patch | MSS54 DS2 Tool

        Comment


          #94
          Originally posted by karter16 View Post
          FWIW pretty much all of the weirdness in the Ghidra C-code view can be resolved by making sure your function parameters (number and datatype) and return value (datatype) are correct. For example
          Code:
          int can_rx_797_payload(void)
          I'm willing to bet if you follow where it's called the return value isn't actually used. If so, and you modify the function prototype in Ghidra to be a void return type you'll see a bunch of that weirdness clean itself up.
          That's good to know! First time using Ghidra for this kind of work, so still stumbling through it. Will try to fix all this weirdness now.

          Edit: Oh man, it's so much nicer with these fixes. Thanks! Repo updated with this in mind, so any .0pa you feed the workflow will generate these nice Ghidra projects automagically.
          Last edited by heinzboehmer; Yesterday, 01:51 PM.
          2002 Topasblau M3 - Coupe - 6MT - Karbonius CSL Airbox - SSV1 - HJS - Mullet Tune - MK60 Swap - E86 Front Triangulation - ZCP Rack - Nogaros - AutoSolutions - 996 Brembos - Slon - CMP - VinceBar - Koni - Eibach - BlueBus - Journal

          2012 Alpinweiss 128i - Coupe - 6AT - Slicktop - Manual Seats - Daily - Journal

          Comment

          Working...
          X