Reverse Engineering the firmware on a Kenwood DDX9903S
UPDATE 14 MAR 2020: For discussion, see the Google group. Comments from the old WordPress site have been migrated there.
I bought and really like my Kenwood Excelon DDX9903S headunit. I had it in my WRX, and moved it to my LS430. It supports Android Auto and CarPlay, which I find really useful when driving.
However, it has a nag screen every time it boots up. This got me curious as to how it worked, and see if it could be patched to skip this disclaimer. I figured it probably ran Linux on a SoC, as pretty much everything does nowadays. So I grabbed the latest firmware for it (mine was already updated to it), and started probing.
Extract that and you get 3 folders under S_V2_7_0008_0600/:
BOOT_V2_7_0008_0600_release/ MAIN_V1_0_2758_0400/ SOC_V2_7_0008_0600/
In each there’s a .nfu file, which I’ve never encountered before. I ran binwalk on each:
[BOOT_V2_7_0008_0600_release]$ binwalk Boot_2.7.0008.0600.nfu DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 248776 0x3CBC8 Android bootimg, kernel size: 0 bytes, kernel addr: 0x4F525245, ramdisk size: 1226848850 bytes, ramdisk addr: 0x6C61766E, product name: "ERROR: Cannot read kernel image" 1571592 0x17FB08 ELF, 64-bit LSB shared object, AMD x86-64, version 1 (SYSV) 2358024 0x23FB08 ELF, 64-bit LSB shared object, AMD x86-64, version 1 (SYSV) 3209992 0x30FB08 ELF, 64-bit LSB shared object, AMD x86-64, version 1 (SYSV)
Surprise, surprise, it runs Android. But, I’m thinking this image is possibly just the firmware updater, and not what I am looking for.
[SOC_V2_7_0008_0600]$ binwalk Soc_V2_7_0008_0600.nfu DECIMAL HEXADECIMAL DESCRIPTION -------------------------------------------------------------------------------- 5767936 0x580300 Android bootimg, kernel size: 16823168 bytes, kernel addr: 0x80008000, ramdisk size: 0 bytes, ramdisk addr: 0x81000000, product name: "" 5784320 0x584300 Linux kernel ARM boot executable zImage (little-endian) 5800283 0x58815B gzip compressed data, maximum compression, from Unix, last modified: 1970-01-01 00:00:00 (null date) 41943040 0x2800000 Zip archive data, at least v2.0 to extract, compressed size: 14612206, uncompressed size: 14696448, name: 16dnx_2.5s_fbios_bootimg.img 56555332 0x35EF744 Zip archive data, at least v2.0 to extract, compressed size: 16765150, uncompressed size: 16842752, name: TCC893X_recovery.img 73320560 0x45EC870 Zip archive data, at least v2.0 to extract, compressed size: 210950775, uncompressed size: 1825360896, name: automotive-linux-16DDX-image.ext4 284271426 0x10F1A342 Zip archive data, at least v2.0 to extract, compressed size: 87690, uncompressed size: 524288, name: fbios_dual.bin 284359188 0x10F2FA14 Zip archive data, at least v2.0 to extract, compressed size: 168, uncompressed size: 223, name: filelist.txt 284359426 0x10F2FB02 Zip archive data, at least v2.0 to extract, compressed size: 29903609, uncompressed size: 39549952, name: qboot_ddx.bin 314263106 0x12BB4642 Zip archive data, at least v2.0 to extract, compressed size: 33193, uncompressed size: 5242880, name: sbios_dual.bin 314296995 0x12BBCAA3 End of Zip archive, footer length: 22
Here we go. A kernel with a sane size and name string, some recovery images, and what looks like a filesystem image! qboot_ddx.bin must be part of Ubiquitous' QuickBoot software. It does boot awfully fast, so that explains that. Would be interesting to see full kernel and init output on a stereo headunit. Well, once anyway.
Running binwalk on MAIN_V1_0_2758_0400/MainFw_1.0.2758.0400.mfu didn’t output anything. Not sure what that is.
I tried unzip to extract Soc_V2_7_0008_0600.nfu. Seemed to work, though it complained about a 41MB extra bytes at the beginning. I was really just interested in the filesystem image for the moment:
[SOC_V2_7_0008_0600]$ unzip Soc_V2_7_0008_0600.nfu Archive: Soc_V2_7_0008_0600.nfu warning [Soc_V2_7_0008_0600.nfu]: 41943040 extra bytes at beginning or within zipfile (attempting to process anyway) inflating: 16dnx_2.5s_fbios_bootimg.img inflating: TCC893X_recovery.img inflating: automotive-linux-16DDX-image.ext4 inflating: fbios_dual.bin inflating: filelist.txt inflating: qboot_ddx.bin inflating: sbios_dual.bin
Running binwalk on the .ext4 verifies it is an ext4 filesystem image. I ran binwalk on the others and nothing was notable except the presumed QuickBoot file, qboot_ddx.bin which had images, and what looks like Qt library .qml files for some type of GUI. Also a Pandora image and other images. Hmm…
I decided to mount the ext4 image to take a look.
[SOC_V2_7_0008_0600]$ sudo mount -o loop automotive-linux-16DDX-image.ext4 /mnt/temp [SOC_V2_7_0008_0600]$ cd /mnt/temp/ [temp]$ ls bin dev home lost+found Music proc sbin sys temp usr boot etc IMG_DEC_WORK media nand1 RAMDISK sdcard Syslog Temp var DB filesave lib mnt opt run share system tmp
Interesting things appear to be in: /opt/jkpf:
bin dbg_daemon_starter.sh etc kill_applications.sh lib rsc script system_init.sh
That appears to be where lots of magic happens. Whenever I’m done disassembling the rest of the car for a particularly annoying remote start installation, I’ll come back to it.