Modify original firmware - GrumpyMeow/ModTheWyzeCamv3 GitHub Wiki
This page will describe how modifications to an original firmware can be made.
Part 1: Analyzing an original firmware
- Download an firmware from Wyze.com for the Wyze Cam v3 from https://support.wyze.com/hc/en-us/articles/360024852172-Release-Notes-Firmware. At the time of writing the latest firmware is v4.36.8.15
- Extract the .zip file to attain the firmware binary file "demo_wcv3.bin" with a filesize of 9.822.336 bytes.
- Use an (Debian/Ubuntu) Linux environment and install the Firmware analysis tool binwalk via:
apt install binwalk
. I personally use Proxmox and create an LXC Containers for these kinds of experiments. - Run:
binwalk demo_wcv3.bin
This will result in:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 uImage header, header size: 64 bytes, header CRC: 0x882BED06, created: 2021-11-18 08:13:04, image size: 9822208 bytes, Data Address: 0x0, Entry Point: 0x0, data CRC: 0x54DA8AC1, OS: Linux, CPU: MIPS, image type: Firmware Image, compression type: none, image name: "jz_fw"
64 0x40 uImage header, header size: 64 bytes, header CRC: 0xA3BC7407, created: 2021-07-02 12:31:59, image size: 1897077 bytes, Data Address: 0x80010000, Entry Point: 0x80416900, data CRC: 0xB0B2FE38, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "Linux-3.10.14__isvp_swan_1.0__"
128 0x80 LZMA compressed data, properties: 0x5D, dictionary size: 67108864 bytes, uncompressed size: -1 bytes
2031680 0x1F0040 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 3853812 bytes, 384 inodes, blocksize: 131072 bytes, created: 2021-11-18 08:13:03
6029376 0x5C0040 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 3790198 bytes, 193 inodes, blocksize: 131072 bytes, created: 2021-11-18 08:13:04
- This firmware file is using the uImage-format which is used by u-boot
- At file position 0 an uImage header is found for a "Firmware Image". This header defines an image with a size of 9.822.208 bytes. This image size is equal to filesize of demo_wcv3.bin minus the size of two uImage headers (2x64=128 bytes) (9822336-9822208=128).
- At file position 64 an uImage header is found for a "OS Kernel Image". This header defines the image with a size of 1.897.077bytes. The content for this uImage start at file position 128.
- At file position 2031680 a Squashfs file system is found.
- At file position 6029376 another Squashfs file system is found.
- The first squashfs starts at position 2031680, while the kernel-image is of size 1897077 starting from position 128. Thus the kernel image is from position 128 to 1897205 (128+1897077=1897205). Thus the data from position 1897205 to 2031680 is padding (134475 bytes).
Part 2: Extracting contents of an original firmware
- Run:
binwalk --extract demo_wcv3.bin
- View extracted files:
cd _demo_wcv3.bin.extracted
andls -lai
This will result in:
total 22784
438271 drwxr-xr-x 4 root root 4096 Jan 2 12:39 .
438270 drwxr-xr-x 3 root root 4096 Jan 2 12:39 ..
438274 -rw-r--r-- 1 root root 3853812 Jan 2 12:39 1F0040.squashfs
441714 -rw-r--r-- 1 root root 3790198 Jan 2 12:39 5C0040.squashfs
438273 -rw-r--r-- 1 root root 5841080 Jan 2 12:39 80
438272 -rw-r--r-- 1 root root 9822208 Jan 2 12:39 80.7z
438276 drwxr-xr-x 22 1000 1000 4096 Nov 18 08:13 squashfs-root
441715 drwxr-xr-x 9 1000 1000 4096 Nov 18 08:13 squashfs-root-0
- The file
80.7z
is the raw uImage firmware content. When runningbinwalk 80.7z
it will show that this file contains the LZMA-compressed-kernel and also the two squashfs filesystems. This file is extracted into80
,1F0040.squashfs
and5C0040.squashfs
- The file
80
is the uncompressed-kernel-image - The file
1F0040.squashfs
is a squashfs filesystem image and it's contents is automatically extracted by binwalk into foldersquashfs-root
- The file
5C0040.squashfs
is a squashfs filesystem image and it's contents is automatically extracted by binwalk into foldersquashfs-root-0
Part 3: Reconstruct firmware
This command will compress the kernel-file (80) and save it as an lzma compressed file 80.lzma
:
lzma --keep --compress 80
This command will create a kernel uImage file:
mkimage -A mips -O linux -T kernel -C LZMA -a 0x80010000 -e 0x80416900 -n 'Linux-3.10.14__isvp_swan_1.0__' -d 80.lzma kernel.image
Add padding to kernel uImage file to 0x1F0000:
dd if=/dev/null of=kernel.image bs=1 count=1 seek=2031616
Add padding to 1F0040.squashfs file to 3997696 bytes file size:
dd if=/dev/null of=1F0040.squashfs bs=1 count=1 seek=3997696
Add padding to 5C0040.squashfs file to 3792896 bytes file size:
dd if=/dev/null of=5C0040.squashfs bs=1 count=1 seek=3792896
Concatenate the kernel-image and squashfs parts into one file firmware.raw
:
cat kernel.image 1F0040.squashfs 5C0040.squashfs > firmware.raw
Make a firmware-image of the file firmware.raw
and save it as firmware.bin
:
mkimage -A mips -O linux -T Firmware -C none -a 0 -e 0 -n "jz_fw" -d firmware.raw firmware.bin
Add padding to firmware.bin file to 9822336 bytes file size:
dd if=/dev/null of=firmware.bin bs=1 count=1 seek=9822336
binwalk firmware.bin
will result in:
DECIMAL HEXADECIMAL DESCRIPTION
--------------------------------------------------------------------------------
0 0x0 uImage header, header size: 64 bytes, header CRC: 0x4EB8427D, created: 2022-01-02 23:30:35, image size: 9822208 bytes, Data Address: 0x0, Entry Point: 0x0, data CRC: 0xCC3A1FF8, OS: Linux, CPU: MIPS, image type: Firmware Image, compression type: none, image name: "jz_fw"
64 0x40 uImage header, header size: 64 bytes, header CRC: 0x3CB786BA, created: 2022-01-02 23:29:44, image size: 1897073 bytes, Data Address: 0x80010000, Entry Point: 0x80416900, data CRC: 0xCFD1620A, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "Linux-3.10.14__isvp_swan_1.0__"
128 0x80 LZMA compressed data, properties: 0x5D, dictionary size: 8388608 bytes, uncompressed size: -1 bytes
2031680 0x1F0040 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 3853812 bytes, 384 inodes, blocksize: 131072 bytes, created: 2021-11-18 08:13:03
6029376 0x5C0040 Squashfs filesystem, little endian, version 4.0, compression:xz, size: 3790198 bytes, 193 inodes, blocksize: 131072 bytes, created: 2021-11-18 08:13:04
Last 64 bytes of this firmware: D2 D9 D4 C4 E5 8C C2 F7 - 50 81 29 AA F3 BD C4 D1 - F4 5E 49 08 6B 29 F5 A6 - AB 08 F7 BC 41 C0 B6 A4 - 97 8B 14 88 0E A4 26 F5 - E7 8F 4F 3A F4 9B 1B 6E - 11 03 17 82 46 34 D2 7F - BF 1D 16 D1 13 CD A5 03
Another firmware last 64 bytes: E3 57 2C F2 33 84 07 BF - 11 3A 6D DF BE 4B CF A5 - 91 D2 66 32 D7 5B BE F9 - 35 5E A1 3C 59 32 CE D1 - 26 E4 59 CF 96 12 95 A1 - F5 03 CD 9B E4 C9 E7 1C - A2 35 83 CE 39 E5 7C A8 - E0 31 62 98 90 74 8E 0D
dd if=demo_wcv3.bin of=00.raw bs=1 skip=0 count=64 < firmware header
dd if=demo_wcv3.bin of=01.raw bs=1 skip=64 count=64 < kernel image header
dd if=demo_wcv3.bin of=02.raw bs=1 skip=128 count=1897077 < kernel image
dd if=demo_wcv3.bin of=03.raw bs=1 skip=1897205 count=134475 < zero padding
dd if=demo_wcv3.bin of=04.raw bs=1 skip=2031680 count=3853812 < squashfs
dd if=demo_wcv3.bin of=05.raw bs=1 skip=5885492 count=143884 < zero padding
dd if=demo_wcv3.bin of=06.raw bs=1 skip=6029376 count=3790198 < squashfs
dd if=demo_wcv3.bin of=07.raw bs=1 skip=9819574 count=2762 < padding
dd if=demo_wcv3.bin of=08.raw bs=1 skip=9822272 count=64 < checksum or special code
dd if=/dev/null of=firmware.bin bs=1 count=1 seek=9822336 cp demo_wcv3.bin firmware.bin dd if=06-2.raw of=firmware.bin conv=notrunc bs=1 seek=6029376 count=3792896
D2 D9 D4 C4 E5 8C C2 F7 - 50 81 29 AA F3 BD C4 D1 - F4 5E 49 08 6B 29 F5 A6 - AB 08 F7 BC 41 C0 B6 A4 - 97 8B 14 88 0E A4 26 F5 - E7 8F 4F 3A F4 9B 1B 6E - 11 03 17 82 46 34 D2 7F - BF 1D 16 D1 13 CD A5 03
unsquashfs 06.raw
mksquashfs squashfs-root 06-2.raw -noappend -comp xz