Basic tips

Finding ELF format

readelf -h hotplug
└─$ xxd -c 1 -l 6 hotplug
00000000: 7f .
00000001: 45 E
00000002: 4c L
00000003: 46 F
00000004: 01 .
00000005: 01 .

If the last line (the sixed byte) is 01, according to ELF format, 01 is little endian and 02 is big endian.

Create file image with rootFS from scratch

dd if=/dev/zero of=myimage.img bs=1M count=500
mkdir -p MountPoint
mkfs.ext2 myimage.img
mount -t ext2 -o loop myimage.img MountPoint
cp rootfs.tar MountPoint
cd MountPoint
tar -xvf rootfs.tar
df -h
umount MountPoint
dd if=myimage.img bs=1k | gzip -v9 > rootfs.gz


file output # to check ;)

To cut the "Linux kernel version 2.6.36" we need to do:

  • Get the skip offset: 3163712

  • Get the count size: 3226456 - 3163712 = 62.744

dd if=1C bs=1 skip=3163712 count=62744 of=kernel_out
file kernel_out
kernel_out: DIY-Thermocam raw data (Lepton 3.x), scale 7417-5248, spot sensor temperature 0.000000,
cat kernel_out | strings | less

cpio unpacking

cpio -idm — no-absolute-filenames < cpio


sudo docker run --privileged=true --name=firmware -p 2221:22 -p 8888:80 -p 4443:443 -p 2223:23 -it 8d319a850335
cd /tmp
mkdir lower upper workdir overlay
mount -t overlay -o lowerdir=/tmp/lower,upperdir=/tmp/upper,workdir=/tmp/workdir none /tmp/overlay
mount -t overlay -o lowerdir=/tmp/firmwarefs,upperdir=/,workdir=/tmp/workdir none /tmp/overlay
chroot /tmp/overlay /bin/sh


Since file doesn't recognize it, the vendor probably used a custom SquashFS magic signature. I expect that unsquashfs is also giving you an error about not being able to find a valid superblock.

Give sasquatch a try; it's a modified version of unsquashfs that attempts to support such vendor hacks.

GDB server

target:> gdbserver localhost:2000 /bin/httpd
target:> ./gdbserver-7.12-mips-be-stripped localhost:5555 /bin/httpd
host :> gdb /bin/httpd
(gdb) target remote
disas "function"

Trace apps with qemu-mipsel-static

sudo apt-get install qemu qemu-user qemu-user-static
sudo apt-get install gdb-multiarch
sudo apt-get install 'binfmt*'
$ sudo apt-get install libc6-mipsel-cross # For MIPS-EL
$ sudo apt-get install libc6-armhf-armel-cross # For ARM
$ sudo apt-get install gcc-4.4-mipsel-linux-gnu # For MIPS-EL on Ubuntu 14.04
$ sudo apt-get install gcc-mipsel-linux-gnu # For MIPS-EL on Ubuntu 16.04
$ sudo apt-get install gcc-arm-linux-gnueabihf # For ARM
$ sudo mkdir /etc/qemu-binfmt
$ sudo ln -s /usr/mipsel-linux-gnu /etc/qemu-binfmt/mipsel # MIPSEL
$ sudo ln -s /usr/arm-linux-gnueabihf /etc/qemu-binfmt/arm # ARM
qemu-mipsel -strace ./myelf
qemu-mipsel-static -strace ./myelf
$ qemu-mipsel -g 12345 ./a.out &
./qemu-mipsel-static -g 12345 /bin/httpd
$ gdb-multiarch ./a.out
(gdb) set arch mips
The target architecture is assumed to be mips
(gdb) set endian little
The target is assumed to be little endian
(gdb) target remote localhost:12345
Remote debugging using localhost:12345
(gdb) info functions
Non-debugging symbols:
0x00407360 _init
0x004073f0 _ftext
0x004075a0 CheckWanType
0x004078ac check_dhcpc
0x00407d80 CheckPPPOE
0x00407ed0 random_xid
0x004082bc send_discover
0x00408754 udhcp_checksum
0x00408884 get_raw_packet
0x00408c60 parsePacket
0x004096c8 printErr
0x004097f8 computeTCPChecksum
0x0040a100 sendPADT
0x0040a874 pktLogErrs
0x0040bca0 discovery
0x0040c020 openInterface
0x0040c3e4 sendPacket
0x0040c498 receivePacket

Mips binaries