2

Tough problem - trying to reverse engineer a CANBUS controller for which I can download firmware (as far as I can tell, binary image, not ELF) but I dont know what MCU it uses. binwalk, r2 dont give me anything useful. Binwalk opcodes match mipsel but function signatures is garbage.

What can I do to determine MCU from firmware?

  • are you able to share the file via dropbox or equivalent? – julian Aug 15 at 22:02
  • @julian dataspeedinc.com/release-packages Dataspeed knows how to control Ford steering via Active Park messages. Inside archives are Steer firmware for several Ford platforms and thats where I am hoping to understand protocol – Anycorn Aug 16 at 1:06
  • For example DBW_Kit_FORD_20200221/Firmware/FORD_P5/FORD_P5_STEER_RevA_v1.2.0.hex is Ford F-150 firmware for Dataspeed HW module. I converted hex to binary, relevant strings appear in hexdump, but thats as far as I managed. – Anycorn Aug 16 at 1:12
3

It does appear to be MIPS 32-bit little-endian machine code.


First, the file was converted from .hex to binary via

$ objcopy --input-target=ihex --output-target=binary FORD_P5_STEER_RevA_v1.2.0.hex FORD_P5_STEER_RevA_v1.2.0.bin

After looking at a binwalk entropy plot and a hex dump, I sliced out the first 0x00021330 bytes, because nearly everything after is just 0x00 bytes.

000212f0  5f 50 35 20 53 74 65 65  72 00 00 00 20 24 00 00  |_P5 Steer... $..|
00021300  00 04 08 10 14 18 00 00  08 00 e0 03 00 60 62 41  |.............`bA|
00021310  08 00 e0 03 20 60 62 41  08 00 e0 03 00 00 00 00  |.... `bA........|
00021320  08 00 e0 03 00 00 00 00  00 00 00 00 00 00 00 00  |................|
00021330  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................| <--\
*                                                                                 |-- Huge gap
00071e40  01 00 00 00 02 00 00 00  00 00 00 00 46 4f 52 44  |............FORD| <--/
00071e50  20 50 35 20 53 74 65 65  72 69 6e 67 20 45 6d 75  | P5 Steering Emu|
00071e60  6c 61 74 6f 72 20 28 46  4f 52 44 5f 50 35 5f 53  |lator (FORD_P5_S|
00071e70  54 45 45 52 29 20 52 65  76 41 00 00 00 00 00 00  |TEER) RevA......|
00071e80  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
02bf9e80  00 9d 1f 3c 70 79 ff 37  08 00 e0 03 00 00 00 00  |...<py.7........|
02bf9e90  00 00 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|
*
02bfce70  ff ff ff 3e d9 79 f9 ff  5b 0e 66 ff ff ff ff 7f  |...>.y..[.f.....|
02bfce80

ISAdetect results:

{
  "prediction": {
    "wordsize": 32,
    "endianness": "little",
    "architecture": "mips"
  },
  "prediction_probability": 0.81
}

To confirm, I extracted the machine code from the slice and compared it to a reference: ford code vs. reference

The byte value distributions closely match.

| improve this answer | |
  • Thank you, I will try to proceed from there, this is very helpful. I did not know about ISADetect – Anycorn Aug 17 at 2:24
  • @Anycorn you are welcome. I think most people do not know about ISAdetect, sadly. It is relatively new, released in 2019. I only know about it because it is related to my own research – julian Aug 17 at 3:00
1

It is indeed valid MIPS litte-endian code:

seg000:1D0121F0 A8 FF BD 27                 addiu   $sp, -0x58
seg000:1D0121F4 04 00 A1 AF                 sw      $at, 0x58+var_54($sp)
seg000:1D0121F8 08 00 A2 AF                 sw      $v0, 0x58+var_50($sp)
seg000:1D0121FC 0C 00 A3 AF                 sw      $v1, 0x58+var_4C($sp)
seg000:1D012200 10 00 A4 AF                 sw      $a0, 0x58+var_48($sp)
seg000:1D012204 14 00 A5 AF                 sw      $a1, 0x58+var_44($sp)
seg000:1D012208 18 00 A6 AF                 sw      $a2, 0x58+var_40($sp)
seg000:1D01220C 1C 00 A7 AF                 sw      $a3, 0x58+var_3C($sp)
seg000:1D012210 20 00 A8 AF                 sw      $t0, 0x58+var_38($sp)
seg000:1D012214 24 00 A9 AF                 sw      $t1, 0x58+var_34($sp)
seg000:1D012218 28 00 AA AF                 sw      $t2, 0x58+var_30($sp)
seg000:1D01221C 2C 00 AB AF                 sw      $t3, 0x58+var_2C($sp)
seg000:1D012220 30 00 AC AF                 sw      $t4, 0x58+var_28($sp)
seg000:1D012224 34 00 AD AF                 sw      $t5, 0x58+var_24($sp)
seg000:1D012228 38 00 AE AF                 sw      $t6, 0x58+var_20($sp)
seg000:1D01222C 3C 00 AF AF                 sw      $t7, 0x58+var_1C($sp)
seg000:1D012230 40 00 B8 AF                 sw      $t8, 0x58+var_18($sp)
seg000:1D012234 44 00 B9 AF                 sw      $t9, 0x58+var_14($sp)
seg000:1D012238 48 00 BF AF                 sw      $ra, 0x58+var_10($sp)
seg000:1D01223C 12 40 00 00                 mflo    $t0
seg000:1D012240 4C 00 A8 AF                 sw      $t0, 0x58+var_C($sp)
seg000:1D012244 10 40 00 00                 mfhi    $t0
seg000:1D012248 50 00 A8 AF                 sw      $t0, 0x58+var_8($sp)
seg000:1D01224C 01 9D 1A 3C+                li      $k0, 0x9D012CA4
seg000:1D01224C A4 2C 5A 27
seg000:1D012254 00 00 00 00                 nop
seg000:1D012258 00 68 04 40                 mfc0    $a0, Cause       # Cause of last exception
seg000:1D01225C 00 60 05 40                 mfc0    $a1, SR          # Status register
seg000:1D012260 09 F8 40 03                 jalr    $k0
seg000:1D012264 00 00 00 00                 nop

I suspect the device is using something from the Microchip's PIC32 series.

| improve this answer | |
  • Igor, thanks. The disassembler you used was IDA? – Anycorn Aug 17 at 2:28
  • Yes, it’s from IDA – Igor Skochinsky Aug 17 at 6:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.