MiWiFi mkxqimageコマンドを使ってファームウェアを編集できる!!

(成功編) mkxqimageコマンドを使ってMiWiFi R1DのFWを編集しているサイトを見つけました。MiWiFi Nanoでもできるのか試してみた。


miwifi_r1cl_all_8864d_2.2.8.binで確認
mkxqimageコマンドでFWの展開・再構築

小米路由器固件修改 - IPTV爱好者
http://www.iptvfans.cn/wiki/index.php/%E5%B0%8F%E7%B1%B3%E8%B7%AF%E7%94%B1%E5%99%A8%E5%9B%BA%E4%BB%B6%E4%BF%AE%E6%94%B9

このサイトによるとMiWiFiのmkxqimageコマンドを使ってFWを展開・再構築できるそうです。
ここではMiWiFi R1Dを使っていますが、MiWiFi Nanoにもmkxqimageコマンドが含まれていたので同じ様なことができそうです。
展開

# mkxqimage -x brcm4709_hdr_039ef_0.4.85.bin

再構築
# mkxqimage -o brcm4709_hdr_00000_0.4.85.bin -p ./private.pem -t 5 -f brcm4709_nor.bin -f root.ext4.lzma

MiWiFi Nanoで実際にやってみる

(※mkxqimageコマンドでは展開できませんでした。)

root@XiaoQiang:/tmp/fw# mkxqimage -x miwifi_r1cl_all_8864d_2.2.8.bin
root@XiaoQiang:/tmp/fw# ls
firmware.bin                     uboot.bin
miwifi_r1cl_all_8864d_2.2.8.bin  xiaoqiang_version
ramfs.bin
MiWiFi NanoのROMは16MBと少ないため、空き容量が足らず0Byteの壊れたファイルが作成されていました。


展開プログラムがあった
こちらのサイトに公開されているプログラムを使うことでUbuntu上で展開することができました。
extract_fw.c
#include <stdio.h>

struct {
        char magic[4];
        int size;
        unsigned int crc;
        short type;
        short model;
        unsigned int offset[4];
} header;

struct {
        char magic[4];
        unsigned int reserved;
        int size;
        unsigned int reserved2;
        char filename[32];
} section;

int main(int argc, char *argv[]) {
        int i, j;
        int size;
        FILE *input;
        FILE *output;
        char buffer[1024];

        if (argc < 2) {
                fprintf(stderr, "Usage: split filename\n");
                return 1;
        }
        if ((input = fopen(argv[1], "rb")) == NULL) {
                fprintf(stderr, "File %s open error\n", argv[1]);
                return 1;
        }
        if (fread(&header, 1, sizeof(header), input) != sizeof(header)) {
                fprintf(stderr, "File %s read error\n", argv[1]);
                return 1;
        }
        for (i=0; i<4; i++) {
                if (header.offset[i] == 0)
                        continue;
                fseek(input, header.offset[i], SEEK_SET);
                if (fread(&section, 1, sizeof(section), input) != sizeof(section))
                        continue;
                if ((output = fopen(section.filename, "wb")) == NULL) {
                        fprintf(stderr, "File %s open error\n", section.filename);
                        continue;
                }
                printf("Create file %s\n", section.filename);
                for (j=0; j<section.size; j+=sizeof(buffer)) {
                        size = section.size-j;
                        if (size > sizeof(buffer))size = sizeof(buffer);
                        if (fread(buffer, 1, size, input) != size)
                                break;
                        fwrite(buffer, 1, size, output);
                }
                fclose(output);
        }
        fclose(input);

        return 0;
}
$ cc -o extract_fw extract_fw.c
$ ./extract_fw miwifi_r1cl_all_8864d_2.2.8.bin
Create file xiaoqiang_version
Create file firmware.bin
Create file uboot.bin
Create file ramfs.bin
(このfirmware.binをMiWiFiのfirmware領域にmtdコマンドで書き込むことで正常に起動することを確認しました。)

MiWiFi Nanoは十分な空き領域が無くmkxqimageコマンドで再構築が出来そうにないので、編集後のfirmware.binをmtdコマンドで直接書き込みます。

OpenWrtファームウェアの編集
初めにbinwalkというファイル構造解析ソフトを使ってfirmware.binの構造を調べます。
$ sudo apt-get install binwalk squashfs-tools
$ binwalk firmware.bin 

DECIMAL    HEX        DESCRIPTION
-------------------------------------------------------------------------------------------------------
0          0x0        uImage header, header size: 64 bytes, header CRC: 0x19718DC0, created: Wed Nov 11 19:33:31 2015, image size: 1467466 bytes, Data Address: 0x80000000, Entry Point: 0x80000000, data CRC: 0x281CE358, OS: Linux, CPU: MIPS, image type: OS Kernel Image, compression type: lzma, image name: "MIPS OpenWrt Linux-3.10.14"
64         0x40       LZMA compressed data, properties: 0x6D, dictionary size: 8388608 bytes, uncompressed size: 4237412 bytes
1507328    0x170000   Squashfs filesystem, little endian, version 4.0, compression:  size: 8145752 bytes,  1851 inodes, blocksize: 262144 bytes, created: Wed Nov 11 19:33:27 2015 
「Squashfs filesystem」がMiWiFiのrootfsのようです。
rootfsを編集したいのでSquashfsの部分とそれ以外の部分を分割します。
$ dd if=firmware.bin of=firstchunk.bin bs=1 ibs=1 count=1507328
$ dd if=firmware.bin of=secondchunk.bin bs=1 ibs=1 count=8145752 skip=1507328
取り出したsecondchunk.binはSquashfsイメージファイルなのでunsquashfsコマンドで展開できます。
$ unsquashfs secondchunk.bin
squashfs-root以下に展開されるので、必要なファイルを編集します。
(MiWiFi miniの言語ファイルを移植)
$ cp luci-i18n-english squashfs-root/etc/uci-defaults/
$ cp base.en.lmo squashfs-root/usr/lib/lua/luci/i18n/
mksquashfs4コマンドを使ってSquashfsイメージに再構築します。
$ ./mksquashfs4  squashfs-root/ new-secondchunk.bin -nopad -noappend -root-owned -comp xz -Xpreset 9 -Xe -Xlc 0 -Xlp 2 -Xpb 2 -b 256k
最後にfirstchunk.binと新しく作成したSquashfsイメージを連結してnew-firmware.binを作成します。
$ cat firstchunk.bin new-secondchunk.bin > new-firmware.bin

書き込み
telnetでアクセス後new-firmware.binをMiWiFiに転送し、mtdコマンドで書き込みます。
root@XiaoQiang:/tmp# scp test@192.168.31.206:/home/test/new-firmware.bin /tmp/
root@XiaoQiang:/tmp# mtd -r write /tmp/new-firmware.bin firmware
結果:起動した!!
追加したbase.en.lmoが増えているのを確認

一度初期化すると英語になりました!!
翻訳におかしな所があるような…
※追記(miwifi_r1cm_all_75496_2.8.91_ENG.binの言語ファイルを使うといい感じです!!)



メモ
前回のfirmware-mod-kitではfirmware.binを再構築することは出来ませんでした。
起動ログを見ると「SQUASHFS error: Filesystem uses "lzma" compression. This is not supported」となっており起動しないファームウェアが作成されました。



0 件のコメント :