Page 1 of 1

Setup IDA Pro to disassemble preFL Convers+ Firmware 7M2T-14C026-AG

Posted: 02 Nov 2021, 12:07
by Go4IT
In this topic i'd like to show how i setup my reverse engineering environment to disassemble the IPC firmware of release 7M2T-14C026-AG.

Re: Setup IDA Pro to disassemble preFL Convers+ Firmware 7M2T-14C026-AG

Posted: 02 Nov 2021, 12:32
by Go4IT
Part 1) What is needed?

To answer this question let's take a look at the memory layout of the MAC7116:
memory_map.png
The important parts we need are:
Start addressEnd addressSizeContentComment
0x0000_00000x0000_001F0x0000_0020Reset Vector tableUsed for the MAC to know where to jump under certain conditions (e.g. Reset, Interrupt, ...)
0x0000_10000x0000_3FFFF0x0000_4000Primary Bootloader (PBL)This code is needed to bring the MAC and it's periphals up and running, like the BIOS of a PC
0x0000_50000x00FB_4FFF0x00FB_0000MAIN Firmware1 MB of Firmware code, placed into internal Flash of MAC
0x3000_00000x3001F_FFFF0x0020_0000FLASH Firmware2 MB of Firmware code/data, placed into the external Flash attached to the MAC
0x4000_00000x4000_BFFF0x0000_C000SRAM48 KB internal SRAM of the MAC
0xFC00_00000xFC0F_FFFF0x0010_0000Control Register Space1 MB address space to access periphals of the MAC

Part 2) Gathering the needed data (binary images)

For the firmware itself, those VBF files are needed:
  • 7M2T-14C026-AG.vbf -> MAIN
  • 7M2T-14C026-BC.vbf -> FLASH
Extract the binary images from the VBFs (use a VBF-Tool or do it with some knowledge about VBF-Structure found here https://mk4-wiki.denkdose.de/artikel/vbf/start). I've added both, VBF and BIN, to the ZIP-file below.

Now we also need the PBL code and the Reset-Vectors.Those are not available as VBF files, since they are programmed by the manufacturer. One way to get them is to download it from an working device having the same(!) firmware applied. I did it using JTAG, my Segger J-Link and J-Mem, a tool to read out memory locations through JTAG.
To do so, connect the J-Link probe to the IPC board, attach a 12V source to it (no IGN simulation needed), open "J-Link Commander" shell and issue these commands to connect to the device:

Code: Select all

selectinterface 0
speed 750
jtagconf -1,-1
device MAC7116
BE
connect
After that, you can type in these commands to readout the memory locations from the MAC and save them to a local file (adapt target path/name as needed):

Code: Select all

savebin c:\temp\bootvectors.bin, 0x0, 0x20
savebin c:\temp\pbl.bin, 0x1000, 0x4000

Part 3) Putting it all together

For a quick startup, i've added a ZIP containing all the files needed.
1.) Startup IDA Pro and choose "New"
ida-pro_quickstart_dialog.png
2.) Start with the bootvectors file "7M2T-14C026_VECTORS_0x00000000-0x0000001F.bin" file using "File" -> "Open...".

3.) Choose "ARM Big-endian [ARMB]" processor type (this can't change this afterwards!)
ida-pro_load_file_processor_setup.png
4.) Just accept the following dialog:
ida-pro_disassembly_memory_organization.png
5.) Go to "View" -> "Open subviews..." -> "Segments" (or just press "Shift-F7") to open the "Program Segmentation" view. There, right-click and "Edit segment" (or just press "Ctrl+E") on the newly created "ROM" segment. Change segment name to "VECT" and check the "Execute" and "Read" permissions.
ida-pro_edit-segment.png
6.) Load the PBL file "7M2T-14C026_PBL_0x00001000_0x00004FFF.bin" with "File" -> "Load file" -> "Additional binary file...". Set "Loading segment" to "0x0" and "Loading offset" to "0x1000" ("Create segments" and "Code segment" should be checked):
ida-pro_load_additional_file.png
After loading, edit the newly created segment (usually called "seg...") and change it's name to "PBL" and also check the "Execute" and "Read" boxes.
ida-pro_segment_pbl.png
7.) Do the very same (load additional file) with the Main-Firmware file called "7M2T-14C026-AG_MAIN_0x00005000-0x000FFFFF.bin". Set "Loading segment" to "0x0" and "Loading offset" to "0x5000". Edit the segment and change name to "MAIN" and check "Execute", "Read".

8.) Now load the external Flash file "7M2T-14C026-BC_FLASH_0x30000000-0x30200000.bin" in either the same way. Set "Loading segment" to "0x0" and "Loading offset" to "0x30000000", but this time uncheck the "Code segment" box as this file only contains data. Edit the new segment and change it's name to "FLASH", segment class to "DATA" and only check the "Read" box.
ida-pro_segment_flash.png
9.) The last file to add is the RAM file "7M2T-14C026_RAM-SNAP-NOIGN_0x40000000-0x4000C000.bin". This is only a J-Mem snapshot of a booted Convers+ having this firmware (no ignition, no other signals attached) and it should only aid us as a hint to have reasonable values in there instead of 0x00 ;-). Load it as any other file before, set "Loading segment" to "0x0" and "Loading offset" to 0x40000000. Again enshure "Code segment" is unchecked. Change segment name to "RAM", segment class to "RAM" also (just enter it, if it's not there) and only check "Read", "Write" boxes.

10.) In the end your segmentation should look like this:
ida-pro_segments.png
And now it's time to save your work! So go to "File" -> "Save as..." (use a filename and directory you like)

11.) The very last thing to prepare is to do a inital analyzing of the code, where IDA try to detect the code out of the bytes in the segments flagged als executeable. Therefore double-click the "VECT" segment in the segmentation view, which leads you to the "IDA-View A" window:
ida-pro_undisassembled_view.png
Now choose "Edit" -> "Select all", which will select the whole bytes of all segments, and hit "C" to auto-analyze all data:
ida-pro_perform_analysis.png
Answer "Yes" to this question:
ida-pro_undefine_existing.png
Now, it takes a while to analyze the code:
ida-pro_analyzing.png
You got functions detected on the left pane and see how IDA has changed from simply showing bytes to an Assembler view of commands:
ida-pro_analyze_done.png
IDA gave you an impression of the memory layout in the top bar:
ida-pro_memory_overview-bar.png
What you find here is, where IDA could automatically detect code during analysis (blue) and where not (grey).

Now you are ready to go!
And beware: IDA Pro HAS NO UNDO (CTRL-Z) so "save early - save often".

Re: Setup IDA Pro to disassemble preFL Convers+ Firmware 7M2T-14C026-AG

Posted: 02 Nov 2021, 20:44
by DGAlexandru
RAM is shadowed to multiple ranges

For Ghidra I could use a separate file I created from MAC7116 PDF to describe its peripherals and their subsystems (a CMSIS-SVD format as it is described here: https://www.keil.com/pack/doc/CMSIS/SVD/html/index.html). This way the 0xFC00_0000 - 0xFC0F_FFFF memory range is automatically translated to names of pheriperals / subsystem of peripherals... and it is easier to understand what a function does.
Couldn't find this option in IDA :|

Re: Setup IDA Pro to disassemble preFL Convers+ Firmware 7M2T-14C026-AG

Posted: 02 Nov 2021, 21:05
by Go4IT
Yeah, i know what you mean and i did create such file for IDA Pro myself, but for a different processor type (HCS12). Will look forward to have this done for the MAC7100 family as well. In IDA this is set in a *.cfg file inside the "cfg" folder of the program directory.

The only thing that is tricky here is that we see the Firmware code does not contain direct pointers to those periphal addresses, but use "add" to create them from a base address, an module offset and also then using index-commands to access the serveral registers. How could IDA Pro relate those constructs to the final registers?

Re: Disassemble MAC7116 software (Ford IPC)

Posted: 04 Nov 2021, 13:05
by Go4IT
Let's start from there... The first lines of code shows the vectortable:

Code: Select all

VECT:00000000 ; Segment type: Pure code
VECT:00000000                 AREA VECT, CODE, ALIGN=0
VECT:00000000                 CODE32
VECT:00000000                 B               loc_1018
VECT:00000000                                         ; DATA XREF: sub_2DF82+34↓r
VECT:00000000                                         ; sub_2DF82:loc_2DFCE↓r
VECT:00000004 ; ---------------------------------------------------------------------------
VECT:00000004                 B               loc_5308
VECT:00000008 ; ---------------------------------------------------------------------------
VECT:00000008                 B               loc_530C
VECT:0000000C ; ---------------------------------------------------------------------------
VECT:0000000C                 B               loc_5310
VECT:00000010 ; ---------------------------------------------------------------------------
VECT:00000010                 B               loc_5314
VECT:00000014 ; ---------------------------------------------------------------------------
VECT:00000014                 B               loc_5318
VECT:00000018 ; ---------------------------------------------------------------------------
VECT:00000018                 B               loc_531C
VECT:0000001C ; ---------------------------------------------------------------------------
VECT:0000001C                 B               loc_5320
VECT:0000001C ; VECT          ends
As you can see these are just commands ("B" = Branch to, a jump instruction). IDA Pro generates dynamic labels (names) for the targets, prefixed with "loc_" (short for "location"), followed by the hex address of the destination. So here we see the first vector jumps into the PBL code (0x1000-0x4FFF) and all the other ones goes into the MAIN firmware code (0x5000 up). I think it's obvious that the first vector is the RESET vector (cold start) and the others are vectors for different purposes. BUT - there is a datasheet telling us excactly what they are used for:
reset-vectors.png
This is called the "Core exception table", which are all some kind of "interrupt". The first one is caused by a Reset, regardless if it was triggered by poweron, soft-reset or watchdog-reset. The next one is caused whenever the PC (Program Counter) of the CPU is placed to something which is not executable/known opcode, and so on.

Rename locations/functions

So now, that we knew what they are used for and how they are called, we could give them more readable names. Therefore click on the name "loc_1018" and press "N" and this dialog comes up:
ida-pro_rename_address.png
Here i put "reset_entryPoint" in, and so it changes the name everywhere it was mentioned in the code:

Code: Select all

VECT:00000000                 B               reset_handler
We can repeat this for the other destinations, without knowing how they get handled by code, this does not matter.


Follow references

Now, to get to the code of the handler, just double-click on the label "reset_handler" here and IDA jumps to the location and shows us the code:

Code: Select all

PBL:00001018 ; ---------------------------------------------------------------------------
PBL:00001018
PBL:00001018 reset_handler                           ; CODE XREF: VECT:00000000↑j
PBL:00001018                 LDR             R0, =0x4000BEFC
PBL:0000101C                 MSR             CPSR_c, #0xD2
PBL:00001020                 SUB             SP, R0, #0x100
PBL:00001024                 MSR             CPSR_c, #0x5F ; '_'
PBL:00001028                 B               loc_3E50
PBL:00001028 ; ---------------------------------------------------------------------------
This is a typicall bootstrap init code for ARM. After loading the value "0xx4000BEFC" to register R0. That's of no use now, but later.
Next "MSR CPSR" set's the CPSR (Current Program Status Regsiter). This ARM-Register contains flags (bits) which enabled/disables some behaviour of the CPU. First it is loaded with direct value "0xD2", and it is more usefull here to have it shown as Binary not Hexadecimal expression. To change it, just click on the value and it get' marked, then press "B" and it changes to Binary view:

Code: Select all

PBL:0000101C                 MSR             CPSR_c, #0b11010010
This will not change the code, just the way it is displayed. The same could be achieved by right-clicking the value and choose the appropriate entry from the context-menu.

Re: Setup IDA Pro to disassemble preFL Convers+ Firmware 7M2T-14C026-AG

Posted: 04 Nov 2021, 19:32
by Stevebe
first time i have under stood how to use ida thanks

Re: Setup IDA Pro to disassemble preFL Convers+ Firmware 7M2T-14C026-AG

Posted: 04 Nov 2021, 20:40
by Go4IT
Detecting strings

Another cool feature of IDA Pro is to detect strings in the images. This gives also valuable hints, especially of we found where those strings are "used". Before we let IDA look for them we need to setup some parameters that it knows what a string is and what not. This is done in "Options" -> "General" -> "Strings":
ida-pro_options_general_strings.png
The most important settings here are:
"Default string literal type" =>"C-style" is used if strings terminated with an 0x00
("Pascal style" is used if strings have a char-count as first, followed by the string chars itself, without an termination char)

After setting that, go to "View" -> "Open subviews" -> "Strings" (or hit "Shift+F12") and IDA starts collecting strings from the image an show them in a separate tab called "Strings window":
ida-pro_strings_window.png
As you see, IDA Pro has also added labels to the strings starting with "a" (see setup above) and continued by a CamelCase representation of the string. This way, if it was directly referred to in the code, you see it where it is used.

Very interesting what we can find here! And a good starting point for reverse engineering the code!

Re: Setup IDA Pro to disassemble preFL Convers+ Firmware 7M2T-14C026-AG

Posted: 04 Nov 2021, 21:06
by Go4IT
Sometimes IDA is wrong...

Beware that even if IDA Pro is a smart tool, i may sometimes convert nonsense to code. Most often easy to identify, like here:

Code: Select all

MAIN:000050D0                 SVC             0xEFEFEF
MAIN:000050D4                 SVC             0xEFEFEF
MAIN:000050D8                 SVC             0xEFEFEF
MAIN:000050DC                 SVC             0xEFEFEF
MAIN:000050E0                 SVC             0xEFEFEF
MAIN:000050E4                 SVC             0xEFEFEF
MAIN:000050E8                 SVC             0xEFEFEF
MAIN:000050EC                 SVC             0xEFEFEF
MAIN:000050F0                 SVC             0xEFEFEF
MAIN:000050F4                 SVC             0xEFEFEF
MAIN:000050F8                 SVC             0xEFEFEF
MAIN:000050FC                 SVC             0xEFEFEF
MAIN:00005100                 STRHEQ          R6, [R0],-R4
MAIN:00005104                 STRHEQ          R6, [R0],-R12
MAIN:00005108                 ANDEQ           R6, R0, R4,ASR#7
MAIN:0000510C                 ANDEQ           R6, R0, R12,ASR#7
MAIN:00005110                 LDRDEQ          R6, R7, [R0],-R4
MAIN:00005114                 LDRDEQ          R6, R7, [R0],-R12
MAIN:00005118                 ANDEQ           R6, R0, R4,ROR#7
MAIN:0000511C                 ANDEQ           R6, R0, R12,ROR#7
MAIN:00005120                 STRDEQ          R6, R7, [R0],-R4
MAIN:00005124                 STRDEQ          R6, R7, [R0],-R12
MAIN:00005128                 ANDEQ           R6, R0, R4,LSL#8
MAIN:0000512C                 ANDEQ           R6, R0, R12,LSL#8
MAIN:00005130                 ANDEQ           R6, R0, R4,LSL R4
MAIN:00005134                 ANDEQ           R6, R0, R12,LSL R4
MAIN:00005138                 ANDEQ           R6, R0, R4,LSR#8
MAIN:0000513C                 ANDEQ           R6, R0, R12,LSR#8
MAIN:00005140                 ANDEQ           R6, R0, R4,LSR R4
MAIN:00005144                 ANDEQ           R6, R0, R12,LSR R4
MAIN:00005148                 ANDEQ           R6, R0, R0,ASR#8
MAIN:0000514C                 ANDEQ           R6, R0, R8,LSR#9
MAIN:00005150                 STRHEQ          R6, [R0],-R0
MAIN:00005154                 STRHEQ          R6, [R0],-R4
MAIN:00005158                 STRHEQ          R6, [R0],-R8
MAIN:0000515C                 ANDEQ           R6, R0, R8,ROR#9
MAIN:00005160                 STRDEQ          R6, R7, [R0],-R0
MAIN:00005164                 STRDEQ          R6, R7, [R0],-R4
MAIN:00005168                 STRDEQ          R6, R7, [R0],-R12
MAIN:0000516C                 ANDEQ           R6, R0, R0,LSL R5
MAIN:00005170                 ANDEQ           R6, R0, R8,LSL R5
MAIN:00005174                 ANDEQ           R6, R0, R0,LSR#10
MAIN:00005178                 ANDEQ           R6, R0, R8,LSR#10
MAIN:0000517C                 ANDEQ           R6, R0, R0,LSR R5
MAIN:00005180                 ANDEQ           R6, R0, R8,LSR R5
MAIN:00005184                 ANDEQ           R6, R0, R0,ASR#10
MAIN:00005188                 ANDEQ           R6, R0, R4,ASR#10
MAIN:0000518C                 ANDEQ           R6, R0, R12,ASR#10
MAIN:00005190                 ANDEQ           R6, R0, R0,ROR#10
MAIN:00005194                 ANDEQ           R6, R0, R4,ROR#10
MAIN:00005198                 ANDEQ           R6, R0, R12,ROR#10
MAIN:0000519C                 ANDEQ           R6, R0, R4,ROR R5
MAIN:000051A0                 ANDEQ           R6, R0, R12,ROR R5
MAIN:000051A4                 ANDEQ           R6, R0, R4,LSL#11
MAIN:000051A8                 ANDEQ           R6, R0, R12,LSL#11
MAIN:000051A8 ; ---------------------------------------------------------------------------
The first lines containing "SVC 0xEFEFEF" are just because of empty Flash. Normally it should be 0xFF but somebody has decided to make empty flash areas 0xEF.
The rest "ANDEQ, STRDEQ" makes no sense at all, could be some leftovers from old code or data which hasn't referred to right now. You can turn such "false positive code" back to pure data by selecting the area with the mouse and hitting "U" for "undefine".