Skip to content

Instantly share code, notes, and snippets.

@belkone

belkone/02.md Secret

Last active May 6, 2024 11:44
Show Gist options
  • Star 22 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save belkone/fb63376a9b6b6ebe969e9c8f96c0defb to your computer and use it in GitHub Desktop.
Save belkone/fb63376a9b6b6ebe969e9c8f96c0defb to your computer and use it in GitHub Desktop.
Xiaomi Mi Home Security Camera 360° 1080p (MJSXJ02CM) firmware hack using SPI flasher method (for FW version 4.0.9_0409)

Xiaomi Mi Home Security Camera 360° 1080p (MJSXJ02CM)

firmware hack using SPI flasher method (for FW version 4.0.9_0409)

disclaimer: you do it at your own risk. make sure you have a backup!

requirements:

  • MJSXJ02CM camera with 4.0.9_0409 firmware
  • SPI flasher with SOIC8 clip (I use CH341A)
  • linux host with:
    • dd
    • binwalk
    • squashfs-tools
    • flashrom

backup first

flashrom -p ch341a_spi -r 02_backup.bin
cp 02_backup.bin 02_backup_4.0.9_0409.bin

unpack image

binwalk -e 02_backup.bin

You can use just dd and unsquashfs for extracting rootfs. I use binwalk because of the analysis of the entire firmware.

patching rootfs

Replace _02_backup.bin.extracted/squashfs-root/etc/init.d/S49factory with:

#!/bin/sh

if [ -f /mnt/sdcard/manu_test/manu.sh ]
then
  touch /tmp/factory_mode
  /mnt/sdcard/manu_test/manu.sh
fi

Remove any occurrence of umount /mnt/sdcard in init scripts. For FW 4.0.9_0409 it's just a file: _02_backup.bin.extracted/squashfs-root/etc/init.d/S12copylog

In the case of other FW version you can check the occurrences by: grep -ri 'umount /mnt/sdcard' _02_backup.bin.extracted/squashfs-root

Then re-pack rootfs:

cd _02_backup.bin.extracted
mksquashfs squashfs-root ../rootfs_patched.bin -comp xz
cd ..

prepare a new (hacked) image:

create the beginning of the system image:

cp 02_backup.bin 02_backup_patched1.bin
dd if=rootfs_patched.bin of=02_backup_patched1.bin bs=1 count=7667764 seek=2490368 status=progress

then combine with the rest:

cp 02_backup.bin 02_backup_patched_final.bin
dd conv=notrunc if=02_backup_patched1.bin of=02_backup_patched_final.bin status=progress

compare original dump with final:

binwalk 02_backup.bin > backup.log
binwalk 02_backup_patched_final.bin > final.log
diff -c final.log backup.log

The only difference should be in the creation date of Squashfs. If not, stop here and see what's wrong.

flash it

before that, make sure you have a backup!

flashrom -p ch341a_spi -w 02_backup_patched_final.bin

For MJSXJ05CM camera, you can follow: telmomarques/xiaomi-360-1080p-hacks#18 (comment)

happy hacking!

@belkone
Copy link
Author

belkone commented Jun 7, 2021

For MJSXJ05CM with 4.0.9_0426 you can use the tutorial above.
Just change everywhere occurrences in the names 02 to 05,
e.g. 02_backup.bin change to 05_backup.bin
or 02_backup_4.0.9_0409.bin to 05_backup_4.0.9_0426.bin (for better readability)

You have to change only one step:

prepare a new (hacked) image:

create the beginning of the system image:

cp 05_backup.bin 05_backup_patched1.bin
dd if=rootfs_patched.bin of=05_backup_patched1.bin bs=1 count=7733368 seek=2424832 status=progress

@belkone
Copy link
Author

belkone commented Jun 8, 2021

For macronix MX25L12833F eeprom:

backup:

flashrom -p cha341a_spi -r 05_backup.bin -c MX25L12835F/MX25L12845E/MX25L12865E

write:

flashrom -p cha341a_spi -w 05_backup_patched_final.bin -c MX25L12835F/MX25L12845E/MX25L12865E

thanks to: Bousteur :)

@pexcn
Copy link

pexcn commented Jul 27, 2021

Hi @belkone
Can you provide me with a copy of MJSXJ02CM programmer backup (16MB) ?
I originally made a backup before flashing the new firmware, but because the driver of ch341a in windows is too old, the backup is damaged...

@qwt2003
Copy link

qwt2003 commented Aug 19, 2021

hi@belkone, I found your post from google, and I follow your guide in Ubuntu 18.04, in the last step, I found my diff result “created size” is not as same as the original squashfs. And I burn this firmware to the camera, it’s not working with hacks. I checked the other steps, no errors respond. If you known how to make it works, please give me a reply, thank you.
E3C1FBB9-9FD5-49C6-98B6-0808A8D63BA0

@jimmycr
Copy link

jimmycr commented Oct 4, 2021

Hello, friends. Anyone here able to patch my dump? I'm out of luck with linux utils and dependencies :-/

Dump is saved here:
DUMP of MJSXJ02CM 4.0.9_0409

@jimmycr
Copy link

jimmycr commented Oct 5, 2021

hi@belkone, I found your post from google, and I follow your guide in Ubuntu 18.04, in the last step, I found my diff result “created size” is not as same as the original squashfs. And I burn this firmware to the camera, it’s not working with hacks. I checked the other steps, no errors respond. If you known how to make it works, please give me a reply, thank you.

Hi, have you resolved this problem? Today I finally managed to repack firmware, but just SIZE of SQUASHFS always differ (even I repacked SQUASHFS unchanged). Camera didn't boot. When I flash backup, everything works again (but no hacks of course)

@midi123
Copy link

midi123 commented Oct 27, 2021

@belkone could you please paste here what versions of utils do you use to extract and repack squashfs:

  • linux? version? kernel?
  • xz version?
  • squashfs-tools?

I have the same problem as @jimmycr and @qwt2003 on Ubuntu Server 20.04.3 LTS and Raspbian Bullseye.
I think it has something in common with xz and squashfs-tools.

@midi123
Copy link

midi123 commented Oct 27, 2021

OK finally I found a solution:

binwalk 02_backup.bin > backup.log
head backup.log

DECIMAL       HEXADECIMAL     DESCRIPTION
--------------------------------------------------------------------------------
95704         0x175D8         CRC32 polynomial table, little endian
98216         0x17FA8         xz compressed data
196672        0x30040         xz compressed data
327744        0x50040         xz compressed data
739543        0xB48D7         Cisco IOS experimental microcode, for "Y"
2490368       0x260000        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 6555947 bytes, 2030 inodes, blocksize: 131072 bytes, created: 2020-09-17 03:49:49
10158160      0x9B0050        Zlib compressed data, compressed

This is very important part!
Notice the values above as they may vary.

Decimal offset start: 2490368
Size of squashfs: 6555947
Size of whole firmware part: 10158160 - 2490368 = 7667792

Put here the evaluated values from above:

dd if=02_backup.bin of=squash.bin bs=1 count=6555947 skip=2490368 status=progress

unsquashfs squash.bin

Parallel unsquashfs: Using 1 processor
2318 inodes (1931 blocks) to write

[==========================================================================================================================================================================================================================\] 1931/1931 100%

created 1184 files
created 128 directories
created 717 symlinks
created 1 devices
created 0 fifos

Now change what you need in root filesystem of extracted squashfs under: ./squashfs-root

mksquashfs squashfs-root rootfs_patched.bin -comp xz

cp 02_backup.bin 02_backup_patched1.bin

Notice that 7667792 is a value evaluated above!

dd if=rootfs_patched.bin of=02_backup_patched1.bin bs=1 count=7667792 seek=2490368 status=progress

cp 02_backup.bin 02_backup_patched_final.bin

dd conv=notrunc if=02_backup_patched1.bin of=02_backup_patched_final.bin status=progress

The size of squashfs may vary before and after - but this shouldn't be the problem as after end of squashfs section there will be zeroes and FF's in hex (you can see them in hexeditor like mcview/mcedit).

Than write EEPROM and insert SD card with this hacks: https://github.com/telmomarques/xiaomi-360-1080p-hacks/releases

Working :)

@L337C0D3R
Copy link

rtps is not working, on 4.0.9_0409 using above method

@Redsandro
Copy link

But where is chip to flash?

image

@qwt2003
Copy link

qwt2003 commented Dec 19, 2022

But where is chip to flash?

image

On the other side

@Redsandro
Copy link

Thank you. I assumed there was only camera module there. 😅

Reference picture for future visitors:

image

I'm trying out your guide to apply patches. I think I have difficulty correctly connecting the pins because I get erasure errors. It's a bit puzzling because reading was fine on first attempt. Or maybe it just didn't notice the read errors.

Found Winbond flash chip "W25Q128.V" (16384 kB, SPI) on ch341a_spi.
Reading old flash chip contents... done.
Erasing and writing flash chip... FAILED at 0x00010000! Expected=0xff, Found=0x02, failed byte count from 0x00010000-0x00010fff: 0xfd8
ERASE FAILED!
Reading current flash chip contents... done. Looking for another erase function.
FAILED at 0x00048000! Expected=0xff, Found=0xb4, failed byte count from 0x00048000-0x0004ffff: 0x367f
ERASE FAILED!
Reading current flash chip contents... done. Looking for another erase function.
FAILED at 0x00060000! Expected=0xff, Found=0x5b, failed byte count from 0x00060000-0x0006ffff: 0xfee4
ERASE FAILED!
Reading current flash chip contents... 

@jimmycr
Copy link

jimmycr commented Dec 19, 2022

I'm trying out your guide to apply patches. I think I have difficulty correctly connecting the pins because I get erasure errors. It's a bit puzzling because reading was fine on first attempt. Or maybe it just didn't notice the read errors.

As I can remember when I was trying this using Windows - at first I had to UNLOCK the chip, REPROGRAM and then LOCK the chip again...

@Redsandro
Copy link

I managed to flash the chip. I found the exact same values for offsets and sizes as @midi123. I really appreciate that everyone shared their findings. I couldn't have attempted this without these findings.

Unfortunately, the orange light on the camera is just permanently on. No internet connectivity or qr code request. I can't downgrade to the older firmware or mount the patches. Nothing happens. Perhaps I offered the files in a wrong order. Perhaps I made a mistake in the patches (although I doubt it, they were simple enough).

I'm really impressed by the hardware build of the camera. It's very nice and cleverly put together. It's not just glued plastic. It contains more than 20 screws. It's unfortunate that such a beautiful product is severely limited by software and vendor lock-in.

But this one is soft-bricked. Now I could try to do all the steps again. But to be honest, it's becoming expensive in terms of time. I'd rather buy an old Raspberry Pi Zero 1 W for $6 and a camera module for $3, and use something like this:

I hate to create e-waste so I'll try flash the backup and sell the thing for $9 to someone who doesn't mind the vendor lock-in yet.

@hhankj2u
Copy link

I managed to flash the chip. I found the exact same values for offsets and sizes as @midi123. I really appreciate that everyone shared their findings. I couldn't have attempted this without these findings.

Unfortunately, the orange light on the camera is just permanently on. No internet connectivity or qr code request. I can't downgrade to the older firmware or mount the patches. Nothing happens. Perhaps I offered the files in a wrong order. Perhaps I made a mistake in the patches (although I doubt it, they were simple enough).

I'm really impressed by the hardware build of the camera. It's very nice and cleverly put together. It's not just glued plastic. It contains more than 20 screws. It's unfortunate that such a beautiful product is severely limited by software and vendor lock-in.

But this one is soft-bricked. Now I could try to do all the steps again. But to be honest, it's becoming expensive in terms of time. I'd rather buy an old Raspberry Pi Zero 1 W for $6 and a camera module for $3, and use something like this:

I hate to create e-waste so I'll try flash the backup and sell the thing for $9 to someone who doesn't mind the vendor lock-in yet.

I can downgrade the firmware to use the custom software and revert back to the original backup without issues.
On the chip, you can see the circle dot. Make sure the red line on your clip is on the opposite side of the chip. Can you check your clip is in right direction? My working clip:
20221113_152320

@Redsandro
Copy link

Redsandro commented Dec 20, 2022

I guess it doesn't matter as long as the dot on the chip lines up with the indicator printed on the PCB:

image

I was wondering, should it technically be possible to flash tf_recovery.bin from firmware 3.4.2_0062 directly using the EEPROM flasher?

If I can skip patching the firmware myself, at least I know I didn't make a mistake or used an incompatible tool.

@jklawiter
Copy link

jklawiter commented Mar 10, 2023

OK i think i've got all dependencies to run binwalk without real errors but still while running it i have plenty things like:

739543        0xB48D7         Cisco IOS experimental microcode, for "Y"

WARNING: Symlink points outside of the extraction directory: /home/wariat/hack/MI MJSXJ02CM camera/_02_backup.bin-1.extracted/squashfs-root-0/data -> /mnt/data/data; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/wariat/hack/MI MJSXJ02CM camera/_02_backup.bin-1.extracted/squashfs-root-0/etc/crontab -> /mnt/data/etc/crontab; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/wariat/hack/MI MJSXJ02CM camera/_02_backup.bin-1.extracted/squashfs-root-0/etc/os-release -> /mnt/data/etc/os-release; changing link target to /dev/null for security purposes.

so than:

$ ls -lR _02_backup.bin.extracted/ | grep null
lrwxrwxrwx  1 wariat wariat    9 03-10 15:41 data -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 crontab -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 localtime -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 mortoxd.conf -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 os-release -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 perp -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 Wireless -> /dev/null
lrwxrwxrwx  1 wariat wariat    9 03-10 15:41 data -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 crontab -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 localtime -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 mortoxd.conf -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 os-release -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 perp -> /dev/null
lrwxrwxrwx 1 wariat wariat     9 03-10 15:41 Wireless -> /dev/null

Will it work after I recompress the bin file after patching?

@jimmycr
Copy link

jimmycr commented Apr 28, 2023

Guys, who successfully patched latest Firmware 409 (have working camera), could you, please, provide link to your patched BIN file? Thanks

@bpfc12
Copy link

bpfc12 commented Jun 15, 2023

Hello guys. I did everything according to the described method, the camera works normally, I put an SD card with hacks, but I don't have rtsp and web. The hacks don't work for me. Do you have an idea?

@Raizelian
Copy link

Raizelian commented Sep 2, 2023

OK i think i've got all dependencies to run binwalk without real errors but still while running it i have plenty things like:

739543        0xB48D7         Cisco IOS experimental microcode, for "Y"

WARNING: Symlink points outside of the extraction directory: /home/wariat/hack/MI MJSXJ02CM camera/_02_backup.bin-1.extracted/squashfs-root-0/data -> /mnt/data/data; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/wariat/hack/MI MJSXJ02CM camera/_02_backup.bin-1.extracted/squashfs-root-0/etc/crontab -> /mnt/data/etc/crontab; changing link target to /dev/null for security purposes.

WARNING: Symlink points outside of the extraction directory: /home/wariat/hack/MI MJSXJ02CM camera/_02_backup.bin-1.extracted/squashfs-root-0/etc/os-release -> /mnt/data/etc/os-release; changing link target to /dev/null for security purposes.

(...)

Will it work after I recompress the bin file after patching?

I'm unsure if it will work after recompressing, but that issue can be avoided by using the option -1 or --preserve-symlinks to preserve symlinks when using binwalk, so something like: binwalk -1 -e 02_backup.bin. According to the man page, this option tells binwalk "Do not sanitize extracted symlinks that point outside the extraction directory (dangerous)".


Hello guys. I did everything according to the described method, the camera works normally, I put an SD card with hacks, but I don't have rtsp and web. The hacks don't work for me. Do you have an idea?

Same issue, everything works normally but the hacks don't seem to be enabled.

@aktaanos
Copy link

aktaanos commented Feb 3, 2024

Hello guys. I did everything according to the described method, the camera works normally, I put an SD card with hacks, but I don't have rtsp and web. The hacks don't work for me. Do you have an idea?

I have the same issue here, is someone answer u ?

@TheBarber82
Copy link

TheBarber82 commented Apr 26, 2024

Hi, I have tryied all seems going ok (event the @midi123 solution tested) and the hack seems do nothing but camera still work on mihome app.
If someone can help please.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment