Xiaomi Mi Router 4A Gigabit Edition (R4AG/R4A Gigabit) -- fully supported and flashable with OpenWRTInvasion

I got a bunch of dumps right here, because I flashed 20+ devices this way. So it should be no problem, to send you one of them.

But the problem could be, that the mac-address of your device would change to that one in the dump.
Also I don´t know, if there is some kind of device-specific calibration data in the dump of if calibration processes are done while booting the device (I think I read something about calibration in the console while the device was booting...).


Can you upload a dump somewhere please? :slight_smile: or even better, two or three dumps, so we can compare them and check what you are saying about the mac address.

1 Like

Of course - any suggestions for a hoster to choose?

1 Like

media fire

Ok ... just used that one... I think it should not matter :stuck_out_tongue_winking_eye:


It includes 10 dumps, as I said I got some more if you need them. (Could not access them right now.)


I can run the exploit on firmware 2.28.26 (sorry it is 2.28.62)


after flash openwrt, wifi not activated,

connect lan port, ssh to machine, opkg install luci and done.


Firmware 2.28.26 is the only one officially released by Xiaomi, right? The one that is in Chinese?

EDIT: also I see in your log that the version you are running is 2.28.62, not 2.28.26.


thank you mirror link to your file:



I am realising now that the exploit may be useful to install OpenWrt in other Xiaomi routers and firmware versions


yes yes yes and Y E S !!!!!

Thanks @acecilia and your team

Question: Is there any newer/stable version that we can use ?


The snapshot image is daily built from the latest code, so it is the newest out there. For a stable version you will need to wait for the next OpenWrt release

1 Like

I added a mention to the new method in the wiki, in https://openwrt.org/toh/xiaomi/mir3g#xiaomi_mi_wifi_r3g_mi_wifi_router_3gmir3gmi3gr4a_gigabit/

I also added it in https://openwrt.org/inbox/toh/xiaomi/xiaomi_mi_router_4a_gigabit_edition.

I am a bit confused about why the information for this router is spread around two different wiki pages.

Thanks all for your help! :rocket:


Very strange .... again.
It's not working for me.
Yes, I get root access
Yes, I can overwrite OS1

But: after rebooting, the router changed it's MAC address (only the last digit differs from the previous MAC)
I can ping, but there are no open ports (checked with nmap) and also there is no wifi.
I had to bootp and flash 2.28.62 image with chinese UI.
Fortunately I made a backup of OS1- and overlay-partitions, so I was able to restore it to 2.28.132 with english UI.
I tried several things, including factory reset before flashing openwrt, but always the same. The router comes up with a different MAC and not access at all.

Any ideas?

1 Like

download latest snapshot for mir3g-v2 from here : ( xiaomi_mir3g-v2-squashfs-sysupgrade.bin)


after flashing openwrt you need to ssh to router and install luci then enable wifi from settings.

1.ssh root@
2.opkg update
3.opkg install luci

it is also possible to directly install the openwrt image to the flash image.

Readout the image from flash with:
ch341prog -r readout_image_from_mir3gv2.img

Install OpenWRT with dd on the image:
dd if=openwrt-ramips-mt7621-xiaomi_mir3g-v2-squashfs-sysupgrade.bin of=readout_image_from_mir3gv2.img conv=notrunc bs=1 seek=1572864

Erase flash with:
ch341prog -e

And write the modified image back:
ch341prog -w readout_image_from_mir3gv2.img


That sounds great for me !!!
So I could save a lot of time, because until now I was dumping with flashrom, enabling bootmenu-delay within the dump, reflashed the patched dump, tftp-booted OpenWrt and then did the sysupgrade.

Could you tell me how you found out the right start-position (seek=1572864)?

1 Like

I analysed the binary with binwalk:

97696         0x17DA0         U-Boot version string, "U-Boot 1.1.3 (Feb 22 2019 - 06:43:39)"
98248         0x17FC8         CRC32 polynomial table, little endian
524288        0x80000         JFFS2 filesystem, little endian
1572864       0x180000        uImage header, header size: 64 bytes, header CRC: 0x6056EBF4, created: 2019-02-22 06:51:44, image size: 1856070 bytes, Data Address: 0x81001000, Entry Point: 0x813ECCE0, data CRC: 0x1522C879, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "MIPS OpenWrt Linux-3.10.14"
1572928       0x180040        LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 5458688 bytes
2705694       0x29491E        COBALT boot rom data (Flat boot rom or file system)
3473408       0x350000        Squashfs filesystem, little endian, version 4.0, compression:xz, size: 11349156 bytes, 2236 inodes, blocksize: 262144 bytes, created: 2019-02-22 06:51:40
15204352      0xE80000        JFFS2 filesystem, little endian

Just tried it out now, and it seems to work well :slight_smile:

I wrote a shell script. I use flashrom instead of ch341prog, but I think its easy to modify for those who want to use ch341prog.

timestamp=`date "+%Y%m%d_%H%M%S"`
start=`date +%s` #for calculating runtime

function exit_error () {
	printf "Error @ line:\t%i\n" "${BASH_LINENO[-2]}"
	#removing files
		cd "${dir}"; rm -r "bkps/${timestamp}";
	exit 1

function check_error () {
	if [ $? != 0 ]; then #The return value is stored in $?. 0 indicates success, others indicates error.

function show_runtime () {
	end=`date +%s`
	printf "\nruntime: %s seconds\n\n" ${runtime}

#create folders 
	mkdir -p "bkps/${timestamp}"; cd "bkps/${timestamp}"; file="${timestamp}_dev-dump"

#create dumbs
	printf "\n\n\n ***** +++++ ***** creating dump-files ***** +++++ *****\n"
	flashrom -p ch341a_spi -c GD25Q127C/GD25Q128C -V -r "${file}Nr01.bin"
	#2nd dump-file
	gpio write 2 0; sleep 2; gpio write 2 1; sleep 1 #Powering ON SPI_header-VCC
	flashrom -p ch341a_spi -c GD25Q127C/GD25Q128C -V -r "${file}Nr02.bin"
#compare dumps
	hash1=$(md5sum "${file}Nr01.bin" | cut -f1 -d" ") # only get the hash value
	hash2=$(md5sum "${file}Nr02.bin" | cut -f1 -d" ")
	if [ "${hash1}" = "${hash2}" ]; then
		printf "hashs are identical - continue\n"
		printf "hashs are different - please retry reading the flash.\n"

#patch file
	#enable bootdelay
		sed 's/\x62\x6F\x6F\x74\x64\x65\x6C\x61\x79\x00\x00\x00\x6F\x66\x66/\x62\x6F\x6F\x74\x64\x65\x6C\x61\x79\x00\x00\x00\x00\x00\x35/g' "${file}Nr01.bin" > "${file}Nr01.bin.patched"
	#write openWrt into dumpfile
		wget "https://downloads.openwrt.org/snapshots/targets/ramips/mt7621/openwrt-ramips-mt7621-xiaomi_mir3g-v2-squashfs-sysupgrade.bin"
		dd if="${sysupgrade_file}" of="${file}Nr01.bin.patched" conv=notrunc bs=1 seek=1572864 status=progress
		rm "$sysupgrade_file"

#flash file
	printf "\n\n\n ***** +++++ ***** flashing patched file ... ***** +++++ ***** \n"
	flashrom --noverify -p ch341a_spi -c GD25Q127C/GD25Q128C -V -w "${file}Nr01.bin.patched"
	printf "\n\n\n ***** +++++ ***** device succesfully patched! ***** +++++ *****\n"

#print runtime

I could put the script in the wiki, if you think it could be useful?


@acecilia Thanks for the exploit.
I successfully managed to install OpenWrt on 2 new Mi router 4A 100 (Non gigabit version) running firmware 2.18.51


@acecilia Thanks again for the exploit.
Successfuly installed on Xiaomi Router 4A 100M (R4AC) running firmware 2.18.58