-
Notifications
You must be signed in to change notification settings - Fork 340
HowTo: Extract parts out of firmware upgrade executable (0.elf)
In this howto i describe the steps needed to extract the various parts out of the 0.elf firmware update executable which can be intercepted during download. I've based this howto on the Xiaomi 3.0.3.56 firmware file. When you execute the 0.elf firmware it will flash the firmware and give the following output:
image table size:0x0000003c
index:0
reservations:0x12345678
offset:0x00005e84
size:0x00001000
flash start address:0x00001000
flash end address:0x00001fff
index:20
reservations:0x12345678
offset:0x00006e84
size:0x002e5c54
flash start address:0x000c0000
flash end address:0x003bffff
I've used this output to base the method to use for extracting the firmware parts.
- Extract the firmware file (upd_isa.camera.isc5.bin) using 7zip
- Take the 0.elf file as this contains all the firmware parts (f.i. kernel, rootfs, nvram, uboot)
- Try to get hold of the Sonix SN986xx SDK OVA file
- Use arm-linux-objdump from the toolchain to view the file structure of 0.elf:
/home/dev/SN986_1.50_037a_20151022_1049/snx_sdk/toolchain/crosstool-4.5.2/bin/arm-linux-objdump -h 0.elf
This is the output of the objdump:
0.elf: file format elf32-littlearm
Sections:
Idx Name Size VMA LMA File off Algn
0 .interp 00000014 000080f4 000080f4 000000f4 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
1 .hash 000000c0 00008108 00008108 00000108 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
2 .dynsym 000001d0 000081c8 000081c8 000001c8 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
3 .dynstr 000000d9 00008398 00008398 00000398 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
4 .rel.plt 000000a0 00008474 00008474 00000474 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
5 .init 00000010 00008514 00008514 00000514 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
6 .plt 00000104 00008524 00008524 00000524 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
7 .text 00000d84 00008628 00008628 00000628 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
8 .fini 00000010 000093ac 000093ac 000013ac 2**2
CONTENTS, ALLOC, LOAD, READONLY, CODE
9 .rodata 00000200 000093bc 000093bc 000013bc 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
10 .image.table 009bfd70 000095c0 000095c0 000015c0 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
11 .eh_frame 00000004 009c9330 009c9330 009c1330 2**2
CONTENTS, ALLOC, LOAD, READONLY, DATA
12 .init_array 00000004 009d1334 009d1334 009c1334 2**2
CONTENTS, ALLOC, LOAD, DATA
13 .fini_array 00000004 009d1338 009d1338 009c1338 2**2
CONTENTS, ALLOC, LOAD, DATA
14 .jcr 00000004 009d133c 009d133c 009c133c 2**2
CONTENTS, ALLOC, LOAD, DATA
15 .dynamic 000000b8 009d1340 009d1340 009c1340 2**2
CONTENTS, ALLOC, LOAD, DATA
16 .got 0000005c 009d13f8 009d13f8 009c13f8 2**2
CONTENTS, ALLOC, LOAD, DATA
17 .data 00000008 009d1454 009d1454 009c1454 2**2
CONTENTS, ALLOC, LOAD, DATA
18 .bss 0000001c 009d145c 009d145c 009c145c 2**2
ALLOC
19 .comment 0000005e 00000000 00000000 009c145c 2**0
CONTENTS, READONLY
20 .ARM.attributes 00000029 00000000 00000000 009c14ba 2**0
CONTENTS, READONLY
21 .debug_aranges 00000040 00000000 00000000 009c14e8 2**3
CONTENTS, READONLY, DEBUGGING
22 .debug_info 00000258 00000000 00000000 009c1528 2**0
CONTENTS, READONLY, DEBUGGING
23 .debug_abbrev 00000028 00000000 00000000 009c1780 2**0
CONTENTS, READONLY, DEBUGGING
24 .debug_line 0000018a 00000000 00000000 009c17a8 2**0
CONTENTS, READONLY, DEBUGGING
25 .debug_frame 00000020 00000000 00000000 009c1934 2**2
CONTENTS, READONLY, DEBUGGING
This one stands out, because of it's size:
10 .image.table 009bfd70 000095c0 000095c0 000015c0 2**4
CONTENTS, ALLOC, LOAD, READONLY, DATA
Use objcopy from the toolchain to extract this ".image.table" section to file "imagetable.bin":
/home/dev/SN986_1.50_037a_20151022_1049/snx_sdk/toolchain/crosstool-4.5.2/bin/arm-linux-objcopy -O binary --only-section=.image.table 0.elf imagetable.bin
View the extracted section using an hex editor. This are the hexcodes of the first 68 bytes:
3C 00 00 00 78 56 34 12 84 5e 00 00 00 10 00 00
00 10 00 00 FF 1F 00 00 78 56 34 12 84 6e 00 00
54 5c 2e 00 00 00 0c 00 ff ff 3b 00 78 56 34 12
d8 ca 2e 00 70 30 6d 00 00 00 3c 00 ff ff ab 00
00 00 00 00
Using the output during the flashing process we can recognize certain numbers:
bytes | Hex value | Dev value | Description
------------|------------|-----------|---------------------
3C 00 00 00 | 0x0000003c | 60 | The size of the image table
78 56 34 12 | 0x12345678 | | Reservations
84 5e 00 00 | 0x00005e84 | 24196 | Offset of the image
00 10 00 00 | 0x00001000 | 4096 | Size of the image
00 10 00 00 | 0x00001000 | | Flash Start address
FF 1F 00 00 | 0x00001fff | | Flash End address
78 56 34 12 | 0x12345678 | | Reservations
84 6e 00 00 | 0x00006e84 | 28292 | Offset of the image
54 5c 2e 00 | 0x002e5c54 | 3038292 | Size of the image
00 00 0c 00 | | | Flash Start address
ff ff 3b 00 | | | Flash End address
78 56 34 12 | | | Reservations
d8 ca 2e 00 | 0x002ecad8 | 3066584 | Offset of the image
70 30 6d 00 | 0x006D3070 | 7155824 | Size of the image
00 00 3c 00 | | | Flash Start address
ff ff ab 00 | | | Flash End address
00 00 00 00 |
Apparently there are 3 images in this firmware file. We have 3 image offset:
- 0x00005e84 (= 24196)
- 0x00006e84 (= 28292)
- 0x002ecad8 (=3066584) The imagetable above has a reserved space of 512 bytes, this needs to be added to the offsets given in the imagetable.
- Use DD to extract the parts from the section:
dd iflag=skip_bytes,count_bytes skip=24708 count=4096 if=imagetable.bin of=unknown.bin
dd iflag=skip_bytes,count_bytes skip=28804 count=3038292 if=imagetable.bin of=KERNEL.bin
dd iflag=skip_bytes,count_bytes skip=3067096 count=7155824 if=imagetable.bin of=ROOTFS-R.bin
Both the KERNEL.bin and ROOTFS-R.bin file are wrapped. Here we unwrap these files.
dd iflag=skip_bytes,count_bytes skip=4 count=3038176 if=KERNEL.bin of=uImage
dd iflag=skip_bytes,count_bytes skip=0 count=7155820 if=ROOTFS-R.bin of=rootfs.cramfs
Let's try to mount the CramFS filesystem image.
mkdir -p /media/cramfs
sudo mount -t cramfs -o loop /tmp/rootfs.cramfs /media/cramfs
cd /media/cramfs
ls
Let's try to make some changes....
- Create a new directory: mkdir /media/newcramfs
- find /media/cramfs > /tmp/filelist.txt
- cat /tmp/filelist.txt | cpio -pdm /media/newcramfs
-
Replacing chinese audio files in directory: /media/cramfs/usr/share/notify
-
Remove MacOs finder cache file: rm /media/cramfs/usr/share/notify/.DS_Store
-
vi /media/cramfs/usr/share/hostapd.conf
-
vi /media/cramfs/usr/share/udhcpd_wpa2.conf
-
Modify files in: /media/cramfs/root/etc_default
-
Change timezone in: vi /media/cramfs/root/etc_default/TZ
-
Stop autostarting of "iSC3S" (Xiaomi Cloud) vi /media/cramfs/root/etc_default/init.d
-
vi /media/newcramfs/media/cramfs/linuxrc Comment out the last line: #exec /sbin/init
-
vi /media/newcramfs/media/cramfs/root/etc_default/init.d/rcS Comment out the line: #modprobe snx_wdt Comment out the last line: #/usr/bin/iSC3S/iSC3S &
Add at the end of the file:
/usr/sbin/telnetd &
hostapd -B -P /var/run/hostapd.pid /etc/hostapd.conf
udhcpd -f /etc/udhcpd.conf &
Place file in: /etc/wpa_supplicant.conf
ctrl_interface=/var/run/wpa_supplicant
ctrl_interface_group=0
ap_scan=1
network={
ssid="TP-LINK_5EE504"
key_mgmt=WPA-PSK
pairwise=CCMP TKIP
group=CCMP TKIP WEP104 WEP40
scan_ssid=1
psk="sonix123"
priority=2
}
Place file in: /etc/udhcpd.conf Place content from: https://github.com/raw/samtap/fang-hacks/0d2913f11b6bcf471f97e7bb29e6d4b5777c1dbf/etc/udhcpd.conf
Place file in /etc/hostapd.conf Place content from: https://github.com/raw/samtap/fang-hacks/master/bootstrap/hostapd.conf.tmpl
- vi /media/newcramfs/media/cramfs/root/etc_default/TZ Modify to: GMT+1:00
- Once the changes are done, use mkcramfs to create the cramfs image again: /home/dev/SN986_1.60_QR_Scan_019a_20160606_0951/snx_sdk/toolchain/crosstool-4.5.2/bin/mkcramfs /media/newcramfs/media/cramfs/ /home/dev/SN986_1.60_QR_Scan_019a_20160606_0951/snx_sdk/image/rootfs.cramfs
cp /media/sf_Temp/uImage /home/dev/SN986_1.60_QR_Scan_019a_20160606_0951/snx_sdk/image/uImage yum install ncurses-dev
make menuconfig deselect both options in Uboot Partition Size deselect NVRAM Partion > NVRAM Factory Partition deselect NVRAM Partition > NVRAM User Partition select Kernel Partition > Put Kernel into FIRMWARE.BIN select Kernel Patition > Put Kernel into FIRMWARE_F.bin select Root File System Partition > Put Rootfs into FIRMWARE.bin select Root File System Partition > Put Rootfs into FIRMWARE_F.bin deselect Rescue System Partition select Configure File Partition > (both) erase
make firmware
xxxxxxx1. You can flash the resulting file from Uboot with: fatupdate mmc 0x000C0000 0elfkernel.bin kernel verify