honeylab's blog

各種ハードウェアの改造、主にファミコンミニなどをやってます(ました)

も~っと アストロシティミニ 内部にアクセスする 詳細

honeylab.hatenablog.jp

 

↑前回に引き続き、より詳しいことが分かったのと、
意外とこのブログが(ゲームギアミクロの時より圧倒的に)読まれていることが分かったのでもう少し詳しく書いてみます。

 

まず、基板詳細図のアップデートです。
UART端子が見つかりました。
これにより、シリアルポート経由でシステムのより深い部分まで解析できました。

f:id:honeylab:20201220002333p:plain

基板上にあった4ピンの並び、一般的な組み込み機器だと 電源-GND-TXD-RXDみたいな配置出てていることがあるんですが、今回ここに出ていたのは RXD-GND,そしてI2Cの信号モニタ用の端子でした。
どうも、IC7がセキュリティ用のチップであり、そのチップに対するアクセスのデバッグ・観測などのためにこのピンを設けていたのではないかと思います。

 

さて、シリアル端子を使ったシステム解析の方法をせっかくなので書いてみます。

実際に手を動かして試すこともできない方も多いと思いますので、これを見ながらなんとなくイメージしてみてください。

本体裏から基板にアクセスし、USB-シリアルケーブルなどでPCと接続します。

今回、シリアル通信ソフトはRloginというものを使っています。

 

f:id:honeylab:20201220002956p:plain

接続がうまくいくと、電源投入時にこのような出力が見えてきます。

f:id:honeylab:20201220003031p:plain

ログインプロンプトが表れます。

ここで、ユーザ名はroot、ですが、パスワードはわかりません。

これではここから進めません。
いったん電源を切り、ターミナルから's'(小文字のs)を押しながら電源を入れなおします。

すると、さっきより詳しい起動メッセージが表れます。

f:id:honeylab:20201220003331p:plain

さらに、Linuxが起動する前のブートローダである、u-bootのモニタモードで起動できます。

この時のログをこちらに置いておきます。

 

gist.github.com

u-bootのモニタモードでは、ブートローダ環境変数Linuxの起動オプションなどを確認、変更することができます。

「help」コマンドで使用可能なコマンド一覧が表示されます。

f:id:honeylab:20201220003557p:plain

さて、ではここからどうするか。

Linuxを起動した際、パスワードを求められたのはログインシェルが起動したからです。
これを起動せず、コマンドラインを使用できるようにする方法があります。
一般的なLinuxディストリビューションでは、起動後に/sbin/initを呼び出し、自動実行スクリプトやログインシェルの起動を行います。これをストップし、最小限であるbusyboxのシェルだけが起動するようにLinuxコマンドラインを書き換えてしまいます。

(※詳しく書くとアレなのでここは割愛します)

 

このモードで起動すると、パスワード入力など関係なく、rootファイルシステムがマウントされ、busyboxのシェルが起動した状態にすることができます。

f:id:honeylab:20201220003909p:plain

いきなり / # というコマンドライン入力待ちになりました。
しかし、この状態ではいつものアストロシティのゲームは動いていませんし、ファイルシステムのマウントも不十分な状態です。緊急レスキューモードみたいな感じです。

この状態で触れる範囲でこねくり回してやり、改めて通常のLinux起動状態にした際に、パスワードを入れなくてもログインできるようにしてしまいます。

幸い、この状態でrootfsはinitramfsではなくNAND完全にマウントされていて、しかもrwの状態でした。
ここで、/etc/passwd ファイルを見てみます。

f:id:honeylab:20201220004257p:plain

すると、rootの行、赤丸で囲った部分に"x"と書かれています。
これは、rootのパスワードは別途 /etc/shadow に記載されている、という意味です。

では、/etc/shadowは、と見てみると

f:id:honeylab:20201220004400p:plain

rootの行に$6から始まる長々とした文字列が書かれています。
これは、rootのパスワードはSHA512で暗号化されて保存されている、ということです。
実は、メガドラミニ→PCEミニ→アストロシティミニは同じ開発会社によるLinuxディストリビューションが採用されています。
メガドラミニではSoCの名前を含む短めの文字列だったのですが、その後、暗号化強度が増している気がします…気のせいかもしれませんが…
本当に必要ならば、このハッシュを結果にもつ文字列を総当たりで探すこともできるのですが、それは今回時間の無駄です。もともとの/etc/passwordの中の'x'を削除してしまうだけで、/etc/shadowは参照されなくなります。また、パスワードは空になります。

f:id:honeylab:20201220004749p:plain

今回はこのファイルを含むファイルシステムがマウントされていたためこの手法がうまくいきました。

では、パスワードを削除した状態で改めてLinuxを通常起動に戻します。

 

f:id:honeylab:20201220004916p:plain

ユーザ名にrootを入力するだけで通常のLinuxとしてログインできるようになりました。

ここから、システム内部を詳しく調べていきます。

まず、SoCはAllwinner A33互換のZ7213とわかってはいますが、Linuxからどのように見えているかをコマンドで確認します。

f:id:honeylab:20201220005108p:plain

スペック通り、Quad CoreのARM7プロセッサだということがわかります。

f:id:honeylab:20201220005227p:plain

/usrに移動すると、astroディレクトリが見えます。
中を見てみると、75MBの容量を持つ一つの実行ファイル'astro'が見えます。
サイズからして、この中にROMイメージも埋め込まれているのでは、と考えられます。

 

さて、このようなシリアルコンソールからだけでもある程度の観察は可能ですが、ファイル自体が手元にないと逆アセンブルやリソース吸出しなどは困難です。
内蔵されているLinuxはゲーム専用にシュリンクされていますから、USBメモリなどを使用することができません。
しかし、カーネルオプションとして、Android Gagetと呼ばれる仕組みが偶然なのか残されていて、所定のオプションを設定してPCと接続するとデータ通信が可能になります。

まず、システム上のNANDがどのような構成になっているかを確認します。

先ほどのu-bootの起動メッセージ中にはこのような表示がありました。 

 

f:id:honeylab:20201220005835p:plain

Linuxからはこのように見えているようです。

f:id:honeylab:20201220005910p:plain


root@z7213-astro-pp:/usr/astro# cat /proc/cmdline
boot_type=0 disp_para=100 fb_base=0x0 config_size=48128 boot.serialno=28078a547088ffffd979 boot.hardware=sun8i console=ttyS0,115200 noinitrd root=/dev/nandd rootfstype=ext4 rootwait init=/sbin/init ion_cma_512m=64m ion_cma_1g=176m ion_carveout_512m=96m ion_carveout_1g=150m coherent_pool=4m loglevel=0 partitions=boot-res@nanda:env@nandb:boot@nandc:rootfs@nandd:savedata@nande:misc@nandf:UDISK@nandg

cmdlineとも合わせて確認すると、例えばこのrootfsを含むパーティションはnanddであると考えられます。

このパーティションを、USB経由でPCに認識させます。

echo 0 > /sys/class/android_usb/android0/enable
echo mass_storage > /sys/class/android_usb/android0/functions
echo /dev/nandd > /sys/class/android_usb/android0/f_mass_storage/lun/file
echo 1 > /sys/class/android_usb/android0/enable

そう、アストロシティミニの背面電源USB端子は、電源だけでなく、データ配線もきちんと有効になっています。
それを利用するため、USBケーブルでPCと接続します。
データの取り扱いのためにはLinuxのPCが一番便利ですが、簡単にやるにはVMWareなどのUSBパススルーの使えるVMでもいいでしょう(私はそうしています)

PCと接続した状態で上のコマンドラインを打つと、USBメモリが接続されたように見えます。

注意点としては、Windowsマシンの場合、このコマンドラインでは「このディスクはフォーマットされていません」などのメッセージが表示されます。
このパーティションは、Linuxの標準であるext4パーティションであり、Windowsからは全く認識できません。
うっかりフォーマットしてしまうと、アストロシティミニが見事にお陀仏になりますので気を付けましょう。この場合、VMに接続し、VMLinuxから認識させます。

f:id:honeylab:20201220010706p:plain

このように、/dev/sdbとしてNANDのrootfsパーティションが認識されました。

あとは、ddコマンドでパーティションをまるごとファイル化します。

このようにして、解析に必要なパーティションを回収します。

f:id:honeylab:20201220010855p:plain

回収したファイル、ここではnandcをファイルシステムとしてマウントしてみます。

すると、

f:id:honeylab:20201220011401p:plain

linuxカーネルイメージ、uImageファイルが置かれたfat32ファイルシステムだった、ということがわかりました。
今後、新しく作ったuImageファイルはこのパーティションにおいてやれば読み込んでくれます。

rootfsも同様にマウントします。

f:id:honeylab:20201220011646p:plain

PC側でファイルにアクセスできることが確認できました。
ここまで来てしまえばあとはなんでも調べ放題です。
ファイルを一通り調べて、動きを確認したければシリアルから動作を確認する、それを繰り返してシステムの全体を把握していきます。

とはいえ、もうこのZ7213のシステムはハードも大体固定なので、これまでに作られた各種バイナリを持ってくれば大体動いちゃうんですよね…

 

解析はこの後もまだまだ続きます。