Disassemble Nav FX firmware
Posted: 23 Jul 2019, 20:37
Hey guys! I recently loaded one of my FX satnav firmware dumps of the mainboard into IDA-Pro 7. I used these settings:
ARM Little Endian
Processor Kernel Option: ARMv5TEJ
Load as ROM from 0x00000000 onwards.
Convert first bytes to code and go...
The first instruction is a call ("B" = Branch) to memory location 0x0000 0D1C:
where we find this:
Well, whatever this means I used to do Assembler on Z80 but this is decades ago.
Loads the general puropse processor register R0 with the value 0xD3 (0b1101 0011) and this into the CPSR register. "CPSR_c" is a special instruction which only loads the lower 8 control bits into the register.
Bits 0-4 are the current processor mode to use, which is 0b10011 (0x13) and means "SVC (supervisor)".
Bit 5 gives Thumb-Mode if set. Here it is not, so the CPU is not using Thumb, which means every instruction is 4 bytes long.
Bit 6 is FIQ disable which is the case for us. So all Fast-IRQs are disabled and would not be fired during initialization.
Bit 7 is the same for normal IRQ.
So loading "0xD3" means something like "bring the CPU into supervisor mode", where it can access everything.
The next instruction will load the memory address 0xFFFED400 into register R0:
As from the OMAP5912 datasheet this ist the "OMAP32_ID Register" which should contain the processor type and revision, a 32 bit value. This is loaded by the next instruction into register R1:
And now comes the funny part, it is compared with the value loaded into R2 (0x3320500)
and if they don't match (BNE = Branch If Not Equal) the execution is forwarded to address 0x16E0:
In the datasheet of the OMAP, the OMAP32_ID of 0x03320500 means "POMAP5912" or "OMAP5912B", revision 2.2. So this instruction is to check on which processor the software is running!
ARM Little Endian
Processor Kernel Option: ARMv5TEJ
Load as ROM from 0x00000000 onwards.
Convert first bytes to code and go...
The first instruction is a call ("B" = Branch) to memory location 0x0000 0D1C:
Code: Select all
ROM:00000000 B loc_D1C ; DATA XREF: sub_17C42A:loc_17C562↓r
ROM:00000000 ; sub_17C42A+140↓w ...
Code: Select all
ROM:00000D1C ; ---------------------------------------------------------------------------
ROM:00000D1C CODE32
ROM:00000D1C
ROM:00000D1C loc_D1C ; CODE XREF: ROM:00000000↑j
ROM:00000D1C MOV R0, #0xD3 ; set CPSR to "1101 0011" which will enable the "Supervisor mode" of the ARM9 CPU
ROM:00000D20 MSR CPSR_c, R0
ROM:00000D24 LDR R0, =0xFFFED400
ROM:00000D28 LDR R1, [R0]
ROM:00000D2C LDR R2, =0x3320500
ROM:00000D30 CMP R1, R2
ROM:00000D34 BNE loc_16E0
ROM:00000D38 LDR R0, =0xFFFECE00
ROM:00000D3C MOV R1, #1
ROM:00000D40 STR R1, [R0,#0x14]
ROM:00000D44 LDR R2, =0xFFFE1804
ROM:00000D48 LDR R3, [R2]
ROM:00000D4C MOV R2, #0xE0000
ROM:00000D50 ANDS R2, R3, R2
ROM:00000D54 BNE loc_DB0
ROM:00000D58 LDR R0, =0xFFFE1000
ROM:00000D5C LDR R1, [R0,#0x44]
ROM:00000D60 LDR R2, =0x2000FFF0
ROM:00000D64 STR R1, [R2]
ROM:00000D68 MOV R4, #1
ROM:00000D6C STR R4, [R0,#0x44]
ROM:00000D70 AND R1, R1, #1
ROM:00000D74 CMP R1, #1
ROM:00000D78 BNE loc_DC8
ROM:00000D7C LDR R1, =0xDBDBDBDB
ROM:00000D80 LDR R2, =0x2000FFFC
ROM:00000D84 LDR R3, [R2]
ROM:00000D88 CMP R1, R3
ROM:00000D8C BNE loc_16E4
ROM:00000D90 LDR R1, =0x17051973
ROM:00000D94 LDR R2, =0x2000FFEC
ROM:00000D98 LDR R3, [R2]
ROM:00000D9C CMP R1, R3
ROM:00000DA0 BNE loc_16E4
ROM:00000DA4 LDR R2, =0x2000FFF4
ROM:00000DA8 LDR R1, [R2]
ROM:00000DAC B loc_DEC
ROM:00000DB0 ; ---------------------------------------------------------------------------
Code: Select all
ROM:00000D1C MOV R0, #0b11010011
ROM:00000D20 MSR CPSR_c, R0
Bits 0-4 are the current processor mode to use, which is 0b10011 (0x13) and means "SVC (supervisor)".
Bit 5 gives Thumb-Mode if set. Here it is not, so the CPU is not using Thumb, which means every instruction is 4 bytes long.
Bit 6 is FIQ disable which is the case for us. So all Fast-IRQs are disabled and would not be fired during initialization.
Bit 7 is the same for normal IRQ.
So loading "0xD3" means something like "bring the CPU into supervisor mode", where it can access everything.
The next instruction will load the memory address 0xFFFED400 into register R0:
Code: Select all
ROM:00000D24 LDR R0, =0xFFFED400
Code: Select all
ROM:00000D28 LDR R1, [R0]
Code: Select all
ROM:00000D2C LDR R2, =0x3320500
ROM:00000D30 CMP R1, R2
Code: Select all
ROM:00000D34 BNE loc_16E0