プログラミング
16GB iPod Nano 3G アップグレード
16GB iPod Nano 3G Upgrade (tuckerosman.com)
要約
この記事は、第3世代iPod Nanoのストレージを16GBにアップグレードするという個人的なプロジェクトについて詳述しています。著者は、はんだ付けやリバースエンジニアリングの経験がない状態から始め、ファームウェアのNANDチップテーブルをパッチするために、ロックボックスブートローダーやEFIブートローダーの解析といった高度な技術を駆使しました。この困難なプロセスを経て、最終的に目標を達成しました。
全文翻訳
16GB iPod Nano 3G アップグレード
2026-09-05
最初のビデオを見る
このプロジェクトのアイデアを最初に思いついたのは、パンデミックが始まった2020年4月でした。プロジェクト自体やパンデミックがどれくらい続くかわからず、なぜ誰もこのプロジェクトを試したことがないのか(パンデミックではなくプロジェクトについて)疑問に思いました。この時点では、はんだ付けの経験も、リバースエンジニアリングの経験もなく、5歳からソフトウェアに関わってきましたが、それまではArduinoを非常に「Adafruit」的なメイカーレベルでしか扱ったことがなく、ハードウェアの経験はほとんどありませんでした。
このプロジェクトがどれほど大きな挑戦になるか気づいていませんでした。主に、すべてをゼロから学んでいたからです。しかし、今ではそれが完了したので、それだけの価値があったと自信を持って言えます。本来かかるはずだった時間よりも長くかかりましたが、勘弁してください。
問題の紹介
YouTubeで、iPod Classicのストレージを1TB、2TB、4TBにアップグレードする人々の動画を見たことがあるかもしれません(RAMが足りなくなり失敗します)。大型iPodのハードドライブを「ユーザーが修理可能」とは呼びませんが、NANDチップに比べれば確かにそうです。NANDチップは、iPod Nano、Shuffle、そして現在Appleが製造している他のほとんどのデバイス(AirTagを除く)に見られます。
私は無邪気に、NanoのNANDチップを交換するのは簡単で、すぐに動作するだろうと思っていました。iPod Nano第3世代を選んだ理由は2つあります。第一に、NANDチップに足(BGAはんだ付けよりも私にとって扱いやすいが、それでも私の手に負えないレベルでした)が付いているNanoの最新リビジョンだからです。第二に、子供の頃に持っていたNanoなので、私の心に最も近いNanoだからです。あの頃はそれが大好きでした。人々は自分のiPodを愛していました。オーストラリアのドラマーでヘビの飼い主がiPodについてYouTubeチャンネルで公開している動画の人気がそれを証明しています。ただし、そのチャンネルはiPodについてではなく、iPodについて作れるコンテンツは限られているためです。
どのNanoも分解するのは地獄です。破壊せずに分解することは、おそらく不可能です。しかし、第3世代Nano(以降、「n3g」と呼びます)を分解することに成功すると、すぐにNANDチップが見えます。
iPodの内部構造が初めて公開されたわけではありません
低速のホットエアガンを使えば、はんだ付けを外すのは簡単です。はんだ付けはそれほど簡単ではありません。最初の数台のiPodは、私の親友Wesleyが彼のガレージで作業しました。文字通り、彼のガレージで。
「これだ」と、私はカメラを持って、iPodのUIの「情報」セクションにあの待ち望んだ16GBが表示されるのを見るのを期待して、愚かにも思いました。しかし、そうではありませんでした。代わりに得られたのは、忌まわしい赤いXでした。
赤いX
Wesleyのガレージに立って、私はこれが「チップがフォーマットされていない、オペレーティングシステムはどこ?」という意味だと思いました。それは私には理にかなっていました。iPodを復旧しようとしましたが、iTunesでさえ認識できないことがわかりました。Wesleyは組み込みエレクトロニクスに経験があり、通常はファームウェアに許容されるNANDのテーブルのようなものがあり、チップがそのテーブルに見つからない場合は停止すると説明しました。
私は家に帰り、何が起こっているのかを解明し、これを機能させるために改造しようと決意しました。どれほど難しいことだろうか?テーブルを見つけて、NANDチップの詳細でパッチを当てるだけだろ?
私の最初の発見は、Wesleyの言ったことが正しかったことを確認しました。Rockboxのn2gポートで同様のテーブルを見つけました。
struct nand_device_info_type {
uint32_t id;
uint16_t blocks;
uint16_t userblocks;
uint16_t pagesperblock;
uint8_t blocksizeexponent;
uint8_t tunk1;
uint8_t twp;
uint8_t tunk2;
uint8_t tunk3;
} __attribute__((packed));
static const struct nand_device_info_type nand_deviceinfotable[] = {
{0x1580F1EC, 1024, 968, 0x40, 6, 2, 1, 2, 1},
{0x1580DAEC, 2048, 1936, 0x40, 6, 2, 1, 2, 1},
{0x15C1DAEC, 2048, 1936, 0x40, 6, 2, 1, 2, 1},
{0x1510DCEC, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
{0x95C1DCEC, 4096, 3872, 0x40, 6, 2, 1, 2, 1},
...and a lot more...
};
このテーブルはどこかから来たに違いないので、n3gのバージョンがファームウェアのどこにあるかを見つける必要がありました。数年前にn3gにRockboxを移植しようとしていた開発者から、半ば完成したリバースエンジニアリング作業を引き継ぎました。これにはRockboxのブートローダーが含まれており、iPodでコードを実行させるという私の最初の成功につながりました。コード実行が最初の本当のハードルになることはわかっていましたが、誰かがすでにそれを成し遂げていたというのは、正しい方向への大きな一歩でした。
Rockboxブートローダーを初めて実行させたとき (2020年7月13日、私は非常に興奮していました)
Rockboxブートローダーは、Pwnage 2.0エクスプロイトを使用してコードを実行します。詳細はこちらとこちらで読むことができますが、基本的に、初期のApple S5L8xxx BootROMのASN.1/DER証明書解析ロジックのバグを標的としたスタックオーバーフローエクスプロイトです。証明書チェーン解析コンテキスト全体(der::chain::parse_ctx)がスタック上に割り当てられ、保存されたリンクレジスタ(LR)がその構造体のすぐ後ろの既知のオフセットに配置されるため、攻撃者は悪意のある最後の証明書を作成し、その大きすぎるsignatureValueがバッファを344〜345バイトオーバーフローさせ、保存されたLRを攻撃者が制御するアドレスで上書きすることができます。攻撃者はそこに任意の実行可能シェルコードを配置でき、上書きされたリターンアドレスは単にそのペイロードに実行をリダイレクトし、BootROMレベルでの完全な署名なしコード実行を達成します。
コードを実行できるようになると、コードを表示してダンプすることができます。最初に触れる必要があるファームウェアの一部は、EFIブートローダーと呼んでいるものです。なぜなら、まさにそれだからです。これを見たときは少しショックでした。EFI(およびUEFIですが、Appleが何かUをするとは期待しないでください)が主にコンピュータのブートローダーであると思っていました。AppleはApple TV、Mac、その他何にでもEFIを積極的に使用していたのでしょうから、理にかなっています。それでも、これには重すぎると感じましたし、さらに、静的解析をいくらか困難にしました。
EFI内のNANDテーブルは、NANDドライバーに存在します。驚くことではありませんが、コードパスをチップIDを識別する場所までたどることができ、そこからNANDドライバーの初期化ルーチンを見つけました。基本的に、初期化中に、NANDドライバーはNANDバンクのIDをチェックし、バッファメモリ、VFL、FTLを初期化し、それら両方を開きます。明らかにステップ1で失敗していたので、テーブルのIDとジオメトリを私が持っていたチップのものに置き換えました。
初期の頃、私のパッチ適用方法は非常に面倒でした。RockboxブートローダーはNORフラッシュからの読み書きが可能でした。パッチを試すたびに、これらのひどい手順に従う必要がありました。
1. ヘキサエディタで、試したいパッチをバイトを変更して書き込みます。
2. 保存します。
3. UEFIToolを使用して、NANDドライバーのPE32バイナリを私のものに置き換えます。
4. 保存します。
5. この目的のために作成したバイナリdiffアルゴリズムで処理します。ただし、おそらく効率は良くありません。
6. それをRockboxブートローダーにコンパイルします。
7. Rockboxブートローダーをアップロードして実行し、NORからEFIをロードし、diffのビットストリームをその上に展開してから、変更されたEFIをNORに書き戻します。
8. ブートローダーはNORを起動し、パッチが表示されるのを待ちます。
このプロセスは非常に手動で、楽しくありませんでした。さらに複雑にするために、Excelスプレッドシートでパッチを追跡していました。面倒でした。
NANDテーブルのパラメータを変更しても助けにはなりませんでした。まだ忌まわしい赤いXが表示されていました。その画像はNORではbdhw(Bad hardware)と呼ばれています。それでも満足していませんでした。なぜかはわかりませんでした。何らかの内的検査が必要でした。EFIはユーザーに見えるものをほとんどエクスポートしません。表示される画像は、おそらく(bdhw、bdsw、lbatなど)ですが、NANDモジュール内から来ているわけではありません。そこで、私は2つのツールを準備しました。
ツール1:スピンニング
これは1段落に値するほどではないので、簡潔に説明します。条件分岐の片方にb .を追加して、iPodがフリーズするかどうかを確認することで、コードパスを二分法で特定できました。非常にクールで、特別なことは何もありません。
ツール2:診断モードを通じたデータ抽出
Thi