fc2ブログ

レトロフリークのNAND flashをダンプする

Twitterでは昨年末につぶやいておりましたが、レトロフリークのNAND flashダンプに成功しました。解析班を増やしたいので記事を書かねばと思いつつも気が付けば1月もなかば過ぎ。そんな訳で、明けましておめでとうございます。

今回は解説だけでなく、NAND flashをダンプするSDカードイメージもあわせて公開します。集え解析班、特にJavaわかる人。

ただし、このSDカードイメージを実行したことで、どんな不具合が発生するかわかりません。インストールしたゲームが消えてしまうとか、保証が効かなくなるかもしれないとか、最悪レトロフリークが壊れてしまうかもしれませんので、ご注意ください。どんな症状が発生しても、当方はいかなる責任も負いませんので悪しからず。

画像使いまわしで申し訳ありませんが、以下が昨年末にNANDダンプした内容をLinuxで確認した画面です。ダンプしたデータを解析する方法については別途解説するとして、まずはダンプ実行用のSDカードイメージを作成する手順から解説していきましょう。
CXZTYHZUkAEZxHV.png


■NAND flashダンプ用のSDカードイメージを作成する

作成するSDカードイメージは公開しますので、RetroN5のfactory reset imageは使わず、フルスクラッチで作成します。RetroN5のコードが入り込んでいるとまずいですので。

NAND flashをダンプすると、ファイルの合計サイズが3.69GBになるので、多めに4GBの領域をSDカードに確保すればよいでしょう。
ところでレトロフリークのNANDサイズは4GBですが、残りの0.31GBはAndroid(Linux)の/dev/以下にはマッピングされていないようで読み出せませんでした。ここにはRockChipのsecond stage bootloaderがいるようです。そこら辺の話はこの辺で。プロプラなコードみたいなのでとりあえず読めない0.31GBの領域は放っておきます。

今回も以前の記事で解説したroot権限で任意のコマンドを実行できる脆弱性を利用します。この脆弱性を使うためのSDカードの条件は以下でした。

・SDカードの先頭に「RETRON5___BOOTSD」が書き込まれている
・partition 2, 3のファイルシステムがext4

そして今回はNANDをダンプする領域として4GBをpartition 1に確保します。partition 2や3にダンプを吐き出してもよいのですが、ファイルシステムがext4だとWindowsやMac OS Xで扱いにくいので、partition 1をFAT32として使用します。partition 2,3は容量は小さくてよいので、100MBずつ確保することにします。無理すればぎりぎり4GBのSDカードに収められなくもなさそうですが、8GB以上のSDカード対応とします。

まずはSDカードイメージの元になるファイルを生成します。容量は4GB+100MB+100MBよりちょっと多めで。

hissorii@ubuntu:~$ dd if=/dev/zero of=RF_NAND_DUMP.img bs=1M count=4500

続けて0クリアしてしまったMBRの復旧と、partition 1, 2, 3の領域確保をfdiskコマンドにて実行します。
ちょっと長いですが、全て載せておきます。最初に出るエラーは、パーティションテーブルを0クリアしてしまったため。コマンドの実行は、パーティションテーブルの復旧、4GB, 100MB, 100MBの順でパーティション確保、さらにpartition 1のIDをデフォルトの0x83(Linux)から0xb(FAT32)に変更します。そしてパーティションの状況をprintし、最後にSDカードイメージに書き込んで終了です。

hissorii@ubuntu:~$ fdisk RF_NAND_DUMP.img
Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel
Building a new DOS disklabel with disk identifier 0x082f5a31.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): o
Building a new DOS disklabel with disk identifier 0xb45cd782.
Changes will remain in memory only, until you decide to write them.
After that, of course, the previous content won't be recoverable.

Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite)

Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
Partition number (1-4, default 1):
Using default value 1
First sector (2048-9215999, default 2048):
Using default value 2048
Last sector, +sectors or +size{K,M,G} (2048-9215999, default 9215999): +4G

Command (m for help): n
Partition type:
p primary (1 primary, 0 extended, 3 free)
e extended
Select (default p): p
Partition number (1-4, default 2):
Using default value 2
First sector (8390656-9215999, default 8390656):
Using default value 8390656
Last sector, +sectors or +size{K,M,G} (8390656-9215999, default 9215999): +100M

Command (m for help): n
Partition type:
p primary (2 primary, 0 extended, 2 free)
e extended
Select (default p): p
Partition number (1-4, default 3):
Using default value 3
First sector (8595456-9215999, default 8595456):
Using default value 8595456
Last sector, +sectors or +size{K,M,G} (8595456-9215999, default 9215999): +100M

Command (m for help): t
Partition number (1-4): 1
Hex code (type L to list codes): b
Changed system type of partition 1 to b (W95 FAT32)

Command (m for help): p

Disk RF_NAND_DUMP.img: 4718 MB, 4718592000 bytes
255 heads, 63 sectors/track, 573 cylinders, total 9216000 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk identifier: 0xb45cd782

Device Boot Start End Blocks Id System
RF_NAND_DUMP.img1 2048 8390655 4194304 b W95 FAT32
RF_NAND_DUMP.img2 8390656 8595455 102400 83 Linux
RF_NAND_DUMP.img3 8595456 8800255 102400 83 Linux

Command (m for help): w
The partition table has been altered!


WARNING: If you have created or modified any DOS 6.x
partitions, please see the fdisk manual page for additional
information.
Syncing disks.
hissorii@ubuntu:~$

次に、SDカードイメージの先頭に「RETRON5___BOOTSD」という文字列を書き込みます。

hissorii@ubuntu:~$ echo -n 'RETRON5___BOOTSD' | dd of=RF_NAND_DUMP.img conv=notrunc

念のため、書き込めているか確認します。うむ、大丈夫そうです。

hissorii@ubuntu:~$ hexdump -C -n 512 RF_NAND_DUMP.img
00000000 52 45 54 52 4f 4e 35 5f 5f 5f 42 4f 4f 54 53 44 |RETRON5___BOOTSD|
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
*
000001b0 00 00 00 00 00 00 00 00 0e 69 5e 6d 00 00 00 20 |.........i^m... |
000001c0 21 00 0b 4b 81 0a 00 08 00 00 00 00 80 00 00 4b |!..K...........K|
000001d0 82 0a 83 0a b3 17 00 08 80 00 00 20 03 00 00 0a |........... ....|
000001e0 b4 17 83 c9 a6 23 00 28 83 00 00 20 03 00 00 00 |.....#.(... ....|
000001f0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 55 aa |..............U.|
00000200

さらに、確保した各partitionをFAT32/ext4/ext4でそれぞれフォーマットします。
まずはイメージファイル上の各パーティションの開始セクタ、セクタサイズをfileコマンドで確認しておき、losetupコマンドで/dev/loop?にattachします。その後、mkfsにてフォーマットします。

hissorii@ubuntu:~$ file -k RF_NAND_DUMP.img
RF_NAND_DUMP.img: x86 boot sector; partition 1: ID=0xb, starthead 32, startsector 2048, 8388608 sectors; partition 2: ID=0x83, starthead 75, startsector 8390656, 204800 sectors; partition 3: ID=0x83, starthead 10, startsector 8595456, 204800 sectors
hissorii@ubuntu:~$ sudo losetup /dev/loop1 RF_NAND_DUMP.img -o $((2048*512)) --sizelimit $((8388608*512))
hissorii@ubuntu:~$ sudo losetup /dev/loop2 RF_NAND_DUMP.img -o $((8390656*512)) --sizelimit $((204800*512))
hissorii@ubuntu:~$ sudo losetup /dev/loop3 RF_NAND_DUMP.img -o $((8595456*512)) --sizelimit $((204800*512))
hissorii@ubuntu:~$ sudo mkfs -t vfat /dev/loop1
mkfs.fat 3.0.26 (2014-03-07)
Loop device does not match a floppy size, using default hd params
hissorii@ubuntu:~$ sudo mkfs -t ext4 /dev/loop2
(出力結果省略)
hissorii@ubuntu:~$ sudo mkfs -t ext4 /dev/loop3
(出力結果省略)

最後に、partition 2をmountし、viでbootscript.shを作成します。

hissorii@ubuntu:~$ sudo mount /dev/loop2 /mnt/tmp2/
hissorii@ubuntu:~$ sudo vi /mnt/tmp2/bootscript.sh

bootscript.shの中身は以下の通り。
内容は、まずmicro SDカードのFAT32領域用のマウントポイントとなるディレクトリhogeを/dataに作成します。/dataはmicro SDカードのpartition 2です。
次にmicro SDのpartition 1(FAT32)を/data/hogeにマウントし、/dev/block/mtdblock0から9まで(NAND flashの各領域です)を順にダンプしていきます。別プロセスがファイル書き込みをしている最中にダンプするとダンプイメージがおかしくなる気がしますが、とりあえず気にしないことにします。
書き込みが終わったことを判断できるように、書き込み完了後、リカバリモードに移行します。
ちなみに途中でsleepを入れいているのは、micro SDのpartition 1をマウント後、すぐにデータを書き込もうとするとうまくいかないことがあるのでその対応です。

#!/sbin/busybox sh

echo hoge > /data/hoge.txt
/sbin/busybox mkdir /data/hoge
echo hoge > /data/hoge/hoge.txt
/sbin/busybox mount -t vfat /dev/block/mmcblk0p1 /data/hoge -o rw
sleep 5
echo hoge >> /data/hoge/hoge.txt

/sbin/busybox cat /dev/block/mtdblock0 > /data/hoge/mtdblock0
/sbin/busybox cat /dev/block/mtdblock1 > /data/hoge/mtdblock1
/sbin/busybox cat /dev/block/mtdblock2 > /data/hoge/mtdblock2
/sbin/busybox cat /dev/block/mtdblock3 > /data/hoge/mtdblock3
/sbin/busybox cat /dev/block/mtdblock4 > /data/hoge/mtdblock4
/sbin/busybox cat /dev/block/mtdblock5 > /data/hoge/mtdblock5
/sbin/busybox cat /dev/block/mtdblock6 > /data/hoge/mtdblock6
/sbin/busybox cat /dev/block/mtdblock7 > /data/hoge/mtdblock7
/sbin/busybox cat /dev/block/mtdblock8 > /data/hoge/mtdblock8
/sbin/busybox cat /dev/block/mtdblock9 > /data/hoge/mtdblock9

/system/bin/reboot recovery

最後にbootscript.shのパーミッションを755にし、て完成です。

hissorii@ubuntu:~$ sudo chmod 755 /mnt/tmp2/bootscript.sh
hissorii@ubuntu:~$ sudo umount /mnt/tmp2

配布用にzipします。かなり小さくなりました。

hissorii@ubuntu:~$ zip RF_NAND_DUMP.zip RF_NAND_DUMP.img
adding: RF_NAND_DUMP.img (deflated 100%)
hissorii@ubuntu:~$ ls -l RF_NAND_DUMP.*
-rw-rw-r-- 1 hissorii hissorii 4718592000 Jan 17 22:10 RF_NAND_DUMP.img
-rw-rw-r-- 1 hissorii hissorii 4592860 Jan 17 22:12 RF_NAND_DUMP.zip


■SDカードイメージをmicro SDカードに書き込み、レトロフリークで実行する

早速、配布するSDカードイメージをmicro SDに書き込んでみましょう。ここではユーザの多いであろうWindowsを用います。SDカードイメージのzipファイルを展開し、その中のRF_NAND_DUMP.imgをSDカードに書き込みます。私は「Win32 Disk Imager」を使いました。待つこと25分ぐらい。
書き込みが終わるとpartition 1のFAT32の領域だけがWindowsから見えるはずです。ダンプ前なのでまだ中身は空っぽです。8GBや16GBのmicro SDでも4GBの領域しか見えなくなります。使い終わって元に戻したい場合は、「SDFormatter」等を使ってフォーマットしてください。

SDイメージをmicro SDに書き込み終わったら、レトロフリークに挿入し、レトロフリークを起動します。問題なければ、真っ白な画面のままになるので、環境によりますが20分程そのままお待ちください。一生懸命NANDダンプしています。
NANDダンプが終了すると、リカバリモード画面になりますので、そのままmicro SDを外してレトロフリークの電源を長押しで落としてください。

micro SDをPCで読み込めば、FAT32領域にmtdblock0から9までがダンプされていると思います。

G:\>dir
ドライブ G のボリューム ラベルがありません。
ボリューム シリアル番号は 2301-91BC です

G:\ のディレクトリ

2000/01/01 08:40 5 hoge.txt
2000/01/01 08:40 4,194,304 mtdblock0
2000/01/01 08:40 4,194,304 mtdblock1
2000/01/01 08:40 16,777,216 mtdblock2
2000/01/01 08:40 16,777,216 mtdblock3
2000/01/01 08:40 4,194,304 mtdblock4
2000/01/01 08:41 67,108,864 mtdblock5
2000/01/01 08:42 268,435,456 mtdblock6
2000/01/01 08:42 4,194,304 mtdblock7
2000/01/01 08:43 268,435,456 mtdblock8
2000/01/01 08:59 3,317,694,464 mtdblock9
11 個のファイル 3,972,005,893 バイト
0 個のディレクトリ 314,548,224 バイトの空き領域

G:\>

また、再現性が不明なのですが、ダンプ後再起動すると、アップデートしましたみたいなメッセージが出て言語設定からやり直しになることが何度かありました。大丈夫かとは思いますが、あくまでも自己責任でお願いいたします。

■レトロフリークのNAND flashをダンプするSDカードイメージ

という訳で、最後になりましたが、SDカードイメージです。

ダウンロード: RF_NAND_DUMP.zip (4.37MB、展開すると4.39 GB になるので注意)

ふむ、ダンプしたファイルの解析について説明するには時間が足りなくなりました。また次回にしましょう。
ということで、今回はここまで。



Comment

コメントの投稿


管理者にだけ表示を許可する

Trackback

http://hissorii.blog45.fc2.com/tb.php/259-c3de18ea

 | HOME |  »

プロフィール

ひっそりぃ

Author:ひっそりぃ
Twitter:@hissorii_com
GitHub:hissorii


月別アーカイブ


最新記事


カテゴリ



最新コメント


最新トラックバック




RSSリンクの表示


Amazon


QRコード

QRコード

Amazon


ブログランキング

ブログランキング【くつろぐ】
にほんブログ村 ゲームブログ×PlayNCBlogへ

メールフォーム

名前:
メール:
件名:
本文:


カウンタ