Pages: [1]
Author Topic: MG1CS003 MPC5777M BMW B48/58: CAN messages handling/interception  (Read 423 times)
windel
Newbie
*

Karma: +0/-2
Offline Offline

Posts: 6


« on: November 04, 2024, 12:53:56 PM »

Hi,

I'm trying to investigate how CAN messages handled in this ECU(e.g. intercept cruise control buttons to switch maps). And at all logic, how this functionality is working in embeded systems.
I'm not professional reverse engineer, just studying. And have no experience with embedded development(just desktop/web software development).
So will be very appresiate for any help/advices.
Maybe I'm doing something wrong, so will be very happy if someone correct me.

1. Preparation steps:
1.1. Loaded .bin file in Ghidra with 0x09000000 offset
1.2. At LAB_09040468 I found some registers definition:
Code:
e_lis      r1,0x5280
e_or2i     r1,0x6060
e_lis      r13,0x952
e_or2i     r13,0x1ee0
e_lis      r2,0x4000
e_or2i     r2,0x8e00
e_lis      r14,0x4800
e_or2i     r14,0x0
e_lis      r15,0x5280
e_or2i     r15,0x8048
e_lis      r16,0x5080
e_or2i     r16,0x8048
e_lis      r17,0x5180
e_or2i     r17,0x8048
and set values for appropriate registers via selecting all code.(not sure that this correct).

2. Tryied next attempts during my investigation:
2.1. Got some RAM variables from A2L, and via XREF in Ghidra tryied to find a function where it set: no results...

2.2. According to MPC Manual define memory map in Ghidra:
 - 0xFFED4000: Shared CAN Message RAM
 - 0xFFED8000: Shared CAN Message RAM (extended)
 - 0xFFEDC000: Time Triggered Controller Area Network 0 (TTCAN_0)
 - 0xFFEE4000: CAN Subsystem: Controller Area Network 1 (MCAN_1)
 - 0xFFEE8000: CAN Subsystem: Controller Area Network 2 (MCAN_2)
 - 0xFFEEC000: CAN Subsystem: Controller Area Network 3 (MCAN_3)
 - 0xFFEF0000: CAN Subsystem: Controller Area Network 4 (MCAN_4)
Just only in MCAN_1 I have XREF to main code at DAT_ffee4018, but it wasn't help me much. Maybe I missed some global registers configuration?

2.3. Looking in manual: CAN Subsystem -> Memory map and register description
And tryied to identify place where registers(M_CAN_CREL, M_CAN_ENDN, M_CAN_FBTP etc.) configured. Didn't work...

2.4. At 0x090F9000 I found some calls to functions, which is look very similar to what I need(but I'm not sure...)

As far as I'm not embeded developer, I'm not fully understand how ECU is working.
What I undestand(correct me if I'm wrong):
 - Somewhere in code there is CAN message receiving function, from where data bytes parsed and assigned to some addresses in RAM
 - Somewhere in code there is CAN message sending function, from where appropriate RAM addresses reading, and setting CAN message data bytes.
So, manipulating with values in RAM we can achive that ECU will send CAN message with changed bytes, and in such way we can achive what we want(e.g. display current map in tacho, if modify rpm byte of appropriate CAN message)

Can someone explain me, what I'm missing, how to understand CAN system configuration, etc.

Here on forum I found some usefull topic: http://nefariousmotorsports.com/forum/index.php?topic=9027
With help of it I was able to reproduce that steps on MEVD17.2.G BMW N55, but for that TC1797 I have no much info Ghidra(and have no car with such ECU for tests), so I decided to switch back my MPC5777 project.

Will be very appreciate for any help, or even ready for some paid consultation via Skype/GoogleMeet.

And attaching a file on which I'm working. This is a full file with btld and calibrations. Software started at 0x040000, Calibrations at 0x680000
https://drive.google.com/file/d/17iLSndpWJVVlMewibNbzx_T56U2LC-Um
Logged
elias
Full Member
***

Karma: +20/-3
Offline Offline

Posts: 65


« Reply #1 on: November 04, 2024, 04:08:48 PM »

>Somewhere in code there is CAN message receiving function, from where data bytes parsed and assigned to some addresses in RAM

This is theoretically correct. Practically, the code is spread over dozens of functions due to abstractions. The "can-reading" will be done in function a, and the decoding in function b. Between the two steps there are thousands of other things happening. Its rather easier to find the decoding by looking at certain predefined variables. For example, you for sure know that the RPM will be sended somewhere, so you could check for that(just an example, dont take it as a method)

If you have a Funktionsrahmen from the ECU , you could start by looking up where exactly its getting read. If not, looking at the a2l definitions might also help.

Logged
fastboatster
Full Member
***

Karma: +3/-0
Offline Offline

Posts: 78


« Reply #2 on: November 04, 2024, 04:55:06 PM »

What's your main focus with this project - understanding CAN messaging of this DME in general or do you primarily want to do map switching?
I'm not familiar with Bx8 CAN stack, but if you just want to do a map switch, you don't need to get down to that level. DME should have bit flag vars like B_fgrtbe, B_fgrtbh and a whole bunch of others. At least for the n55, most of these should share the same RAM address (but different bits). It sounds like you have an a2l for your file, so find their address(es) and read it (them) while messing with cruise control stack. It's not practical to "understand" everything, reversing CAN stalk will take a while.
Logged
windel
Newbie
*

Karma: +0/-2
Offline Offline

Posts: 6


« Reply #3 on: November 04, 2024, 06:36:40 PM »

My main focus to implement map switching.

Yes, I found B_fgr variable in A2L
Code:
/begin MEASUREMENT
    B_fgr_msg
    "Bedingung FGR (Tempomat) aktiv"
    UBYTE
    B_TRUE
    1
    100
    0.00
    1.00000000000

    BIT_MASK 0x1
    FORMAT "%13.11"
   
    [b]ECU_ADDRESS 0x508006D3[/b]
/end MEASUREMENT

And another "St_fgr:0x50802D5F"

Even identified some decompiled code which using "tables". Looking address in WinOLS I renamed them, and find schemes in FR by that ids. Logic in FR is synced with logic that I'm seeing in code:
Code:
  
  if ((DAT_096c1292__CW_WRPTQW_OUT_01 >> 2 & 1) == 0) {
    DAT_50802d5e = (&DAT_096c1280__K_MAP_USECASE_ANTR)[uVar2];
  }
  DAT_50802d5d = 0;
  if ((DAT_096c1292__CW_WRPTQW_OUT_01 & 8) == 0) {
    DAT_50802d5d = (&DAT_096c1280__K_MAP_USECASE_ANTR)[uVar2];
  }
  if (((DAT_096c1292__CW_WRPTQW_OUT_01 >> 1 & 1) == 0) && ((DAT_5080308f__St_fw & 1) != 0)) {
    DAT_50802d5f__St_fgr = DAT_50802d5f__St_fgr | 1;
    return;
  }
  DAT_50802d5f__St_fgr = DAT_50802d5f__St_fgr & 0xfe;
  return;

So, by looking on varibles I can clearly identify a logic how ECU is working.

And same for B_fgr, it using BitMask 0x1 from St_fgr. This is the same what I was find in FR.
For B_fgr I even identify some code, which is looking like what I need:
Code:
void FUN_0941065c(void)
{
  if (DAT_50800154 == '\x03') {
    FUN_0941059c();
    return;
  }
  if (DAT_50800154 != '\x04') {
    if (DAT_50800154 != '\x05') {
      return;
    }
    if (DAT_50800159 == '\x02') {
      if ((DAT_50802d5f__St_fgr & 1) == 0) {
        DAT_508006d3__B_fgr_msg = DAT_50802d5f__St_fgr & 1;
        return;
      }
      DAT_508006d3__B_fgr_msg = 1;
      return;
    }
  }
  FUN_094104b8();
  return;
}

But I'm not sure that this is true.

In general, what I can to do: I can connect CAN-Analyzer to wires, and identify CAN-ID of cruise control buttons, and it bytes(with bits for RES/SET/+/- buttons).
This is why I want to find some function which handling CAN message with appropriate ID, take a look where parsed bytes/bits is putting, and then looking on that addresses identify appropriate place to where inject my code.

My problem now, that I don't know a best place in code where to inject my own code.

I want to start with some small code injection, e.g. intercept some action from steering wheel(or maybe some other place), and re-write some RAM to identify response(e.g. blink MIL(I found some addresses in A2L for it) or do some other action).


Maybe I started with some complex way(steering wheel). Maybe in such case I need to chose some other "interaction" device(e.g. acceleration pedal, brake pedal, DSC button status etc.).
What you can advice?

Or maybe gearbox is sending something interesting to DME via CAN, and from there I can extract variables(with help of A2L) and identify a logic.

Thanks!

Logged
windel
Newbie
*

Karma: +0/-2
Offline Offline

Posts: 6


« Reply #4 on: November 04, 2024, 06:41:32 PM »

I also found something in FR:
there are many schemes with BusInput -> and getting parameters. I was search that params in A2L, get an address for it, and take a look XREF for that addresses. I tried many variables, but all the time I am messing up in Ghidra code, and can't identify something interesting and clear for me...
Logged
prj
Hero Member
*****

Karma: +1069/-476
Offline Offline

Posts: 6011


« Reply #5 on: November 05, 2024, 02:36:20 AM »

Insert code into a 10ms or 100ms raster with debouncing.
It's completely irrelevant where the CAN messages are read, if you already have the variables and they are changing how you expect.
Logged

PM's will not be answered, so don't even try.
Log your car properly - WinOLS database - Tools/patches
windel
Newbie
*

Karma: +0/-2
Offline Offline

Posts: 6


« Reply #6 on: November 05, 2024, 10:21:25 AM »

Insert code into a 10ms or 100ms raster with debouncing.
It's completely irrelevant where the CAN messages are read, if you already have the variables and they are changing how you expect.

Sorry, I'm not so experienced in all this embedded terms(( I'm just beginer and not fully understand what you wrote.
I'm not asking you to explain me basics of ECU reverse engeneering, but will be very appreciate if you will share some info/examples, or where to read something about it.

Thanks!
Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines Page created in 0.018 seconds with 16 queries. (Pretty URLs adds 0s, 0q)