新作です。今年はこれでいこう。
ラズベリーパイゼロとPICを使用しています。
2017年4月4日火曜日
NES Classic Editionのコントローラの通信内容解析⑥
では、ダンプしてわかった「NES Classic Edition」のコントローラの通信内容をまとめます。以下は起動してから本体側から見た動作になります。
- レジスタ"0xF0"にデータ"0x55"をライト
- レジスタ"0xFB"にデータ"0x00"をライト
この2つの手順が暗号化OFF設定らしい。 - レジスタ"0xFE"にデータ"0x03"をライト
この設定はよくわからない。デバイス識別子を書き換えている? - レジスタ"0xFA"から6Byteのデータ(デバイス識別子)をリード
デフォルトコントローラなら"0x01 0x00 0xA4 0x20 0x03 0x01"が読み出される。これ以外の識別子が読み出されたときの動作は未調査。たぶん、動かないのではないかと思われる。そう考えると、アドレス"0xFE"に"0x03"をライトしたのはクラシックコントローラなどを使用してもデバイス識別子を似通ったものにするため? - レジスタ"0x00"から21Byteをリード
この中にボタン情報が格納されている。該当箇所はアドレス"0x06-0x07"の2Byteっぽい。何故に21Byte?他のデータは何?など疑問は残るが深く考えずスルーすることも大人の知恵だったりする。
ちなみに後日解析した結果、この21Byteのボタン情報以外のデータ部分にオール"0x00"を設定するとうまく動かないという現象が発生したので以下の値を使うのがよろしい。
0x83 0x85 0x85 0x86 0x00 0x00 0xXX 0xXX 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
※XXはボタン情報の格納場所
※オール"0x00"にすると"NES Classic Edition"の起動時のゲーム選択画面では操作できるが、ゲーム選択後に操作不可能になるという謎の現象に陥る - 以降、レジスタ"0x00"からの21Byteリードが繰り返される
リード間隔は約6.6ms。ということは秒間150回リード?120回でも180回でもなく、なんか中途半端な気が…。
- 何も押していないときは"0xFFFF"
上でも書いているが、該当データはレジスタ"0x06-0x07"の場所のデータ。 - 各ボタンの該当位置は以下の通り
Right Down X Select X Start X X X B X A X X Left Up
例えば、右キーを押している場合は"0x7FFF"、Bボタンを押している場合は"0xFFBF"、右キーとBボタンを同時に押している場合は"0x7FBF"となる。
てっきり暗号化していると思いこんでいたのでちょっとびっくりしました。この動作を真似すれば「NES Classic Edition」のコントローラを作成することができます。
NES Classic Editionのコントローラの通信内容解析⑤
ここで、解析されているクラシックコントローラの通信内容についてまとめておきます。
Wiimote/Extension Controllers - WiiBrew
Wiimote/Extension Controllers/Classic Controller - WiiBrew
-> WiiBrewというサイトに詳しいことがまとまっています
WiiLi.org Wii Linux - Wiimote/Extension Controllers/Classic Controller
-> WiiLiというサイトもあったようですが、今はなくなっているようなのでアーカイブサイトのリンクです
次 → NES Classic Editionのコントローラの通信内容解析⑥
- コントローラは内部に256Byte(アドレス8bit)のレジスタを持っている
- コントローラにはI2Cからレジスタにアクセスすることで通信を行う
- ライト動作
0xA4 "レジスタアドレス" "データ0" "データ1" …
"0xA4"はデバイスアドレス"0x52"+ ライトビット"0"です。この次にライトするレジスタアドレスを指定する。次にライトするデータを指定、データが連続したときにはレジスタアドレスをインクリメントしながらライトしていきます。 - リード動作
0xA4 "レジスタアドレス"
0xA5 "データ0" "データ1" …
最初にライト動作でリードしたいレジスタアドレスを指定して一旦通信を終わります。次にリード動作をするのですが、最初の"0xA5"はデバイスアドレス"0x52"+ リードビット"1"です。次にコントローラ側からリード対象のレジスタアドレスのデータを読み出すのですが、ライト動作と同じく、データが連続したときはレジスタアドレスをインクリメントしながらリードされます。連続リードはリードしている側のNACKによって止められます。
- 0xFA-0xFF(6Byte)
デバイス識別子。自分がどのデバイスかを格納している。例えば、"0100A4200101"ならクラシックコントローラPROというような感じ。 - 0x20-0x2F(16Byte)
キャリブレーションデータらしい、何のかは知らない。 - 0x30-0x3F(16Byte)
0x20-0x2Fのデータのコピーらしい、なぜコピーしているかは知らない。 - 0xF0(1Byte)
暗号化のON/OFFに関係しているレジスタ。0xAAを書き込むと暗号化ONで、0x55を書き込むと暗号化OFFらしい。 - 0x00-0x05(6Byte)
コントローラのボタン状態。何のボタンを押しているか、スティックの状態がどうかを格納している。 - 0x06-0x07(2Byte)
「NES Classic Edition」のコントローラのボタン状態が格納されているっぽい。暗号化OFFのときに有効?
Wiimote/Extension Controllers - WiiBrew
Wiimote/Extension Controllers/Classic Controller - WiiBrew
-> WiiBrewというサイトに詳しいことがまとまっています
WiiLi.org Wii Linux - Wiimote/Extension Controllers/Classic Controller
-> WiiLiというサイトもあったようですが、今はなくなっているようなのでアーカイブサイトのリンクです
次 → NES Classic Editionのコントローラの通信内容解析⑥
NES Classic Editionのコントローラの通信内容解析④
では、実際の通信内容を見ていきます。まずはI2Cのパラメータについて。
通信内容を文字に起こしたものが以下です。
次 → NES Classic Editionのコントローラの通信内容解析⑤
- SDA&SCLは3.3Vでプルアップ
- 本体側がマスタ、コントローラ側がスレーブ
- コントローラのスレーブアドレスは"0x52"
- 通信速度は400kHz
- 分解動画などではコントローラ部の基盤部分までDeviceDetectが来ていないので、コネクタ部分でVCCに接続されているような気がします。
【朗報】ニンテンドークラシックミニのコントローラー問題を解決、無線化も簡単にできることが判明! - がじぇぶ GADGETY BLOG
通信内容を文字に起こしたものが以下です。
- DeviceDetectが"Low"から"High"に変化
- ライト(マスター → スレーブ)
0xA4 0xF0 0x55 - ライト(マスター → スレーブ)
0xA4 0xFB 0x00 - ライト(マスター → スレーブ)
0xA4 0xFE 0x03 - ライト(マスター → スレーブ)
0xA4 0xFA - リード(スレーブ → マスター)
0xA5 0x01 0x00 0xA4 0x20 0x03 0x01 - ライト(マスター → スレーブ)
0xA4 0x00 - リード(スレーブ → マスター)
0xA5 0x83 0x85 0x85 0x86 0x00 0x00 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 4.6ms程度待機
- ライト(マスター → スレーブ)
0xA4 0x00 - リード(スレーブ → マスター)
0xA5 0x83 0x85 0x85 0x86 0x00 0x00 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 4.8ms程度待機
- ライト(マスター → スレーブ)
0xA4 0x00 - リード(スレーブ → マスター)
0xA5 0x83 0x85 0x85 0x86 0x00 0x00 0xFF 0xFF 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 - 4.8ms程度待機
- …(以下ループ)
次 → NES Classic Editionのコントローラの通信内容解析⑤
NES Classic Editionのコントローラの通信内容解析③
ようし、I2Cを使用していることはわかった。信号線の配置もわかった。これでコントローラを自由自在に使いこなせるぞ!え?暗号化?なんですかそれ?
ということで、コントローラと本体ではI2Cで通信を行っているのですが、その通信内容は暗号化されているようです。
例えば、以下のページではI2Cの暗号化された通信内容をダンプしています。
コメを噛め» Blog Archive » Wii クラシックコントローラとの通信
とは言え、所詮はハードウェアで実装されている暗号化なのですでに解析されているようです。
Reverse engineering the Wiimote's encryption
上記が暗号解析成功報告みたいです(2008年)。"weak"という言葉があるので、暗号強度的には弱いのでしょうね、ハードウェア固定ですし。
暗号化のプロトコルについて以下に箇条書します。
実コード掲載のされているページの例
wii-retropad-adapter/src/wii-retropad-adapter at master · bootsector/wii-retropad-adapter · GitHub
次 → NES Classic Editionのコントローラの通信内容解析④
ということで、コントローラと本体ではI2Cで通信を行っているのですが、その通信内容は暗号化されているようです。
例えば、以下のページではI2Cの暗号化された通信内容をダンプしています。
コメを噛め» Blog Archive » Wii クラシックコントローラとの通信
とは言え、所詮はハードウェアで実装されている暗号化なのですでに解析されているようです。
Reverse engineering the Wiimote's encryption
上記が暗号解析成功報告みたいです(2008年)。"weak"という言葉があるので、暗号強度的には弱いのでしょうね、ハードウェア固定ですし。
暗号化のプロトコルについて以下に箇条書します。
- 暗号キーは本体側からコントローラ側に送付する
起動時に本体側から16Byteの暗号キーをコントローラ側に送信する。暗号キーはランダムで生成されるようです。 - コントローラ側では暗号キーを基に暗号テーブルを作成する
"S-Box"という共通鍵暗号化技術を使っているようです(よく知らない)。 - コントローラ側から本体側に情報を送るときには暗号テーブルで暗号化してデータを送付する
- 本体側を作る場合
クラシックコントローラなどを機器のコントローラとして使用する場合は、暗号キーを固定値にすることで容易に復号ができます。前述の通り、暗号化に使用する暗号テーブルは起動時に送付する暗号キーによって生成されるので、逆説的に暗号キーを固定すると暗号テーブルも固定されます。すると実質的に復号機能はいらなくなります。
実際には暗号キーをすべて"0x00"にして使用するということをよくやるみたいです。 - コントローラ側を作る場合
コントローラ側の機器を作成する場合は、暗号キーから暗号テーブルを作成する機能と暗号化機能は必須です。さらに本体側がI2Cのマスターになるので作成する機器はスレーブとして機能する必要があります。
もっとも、所長以外にコントローラ側を作りたい人なんているんですかね?
実コード掲載のされているページの例
wii-retropad-adapter/src/wii-retropad-adapter at master · bootsector/wii-retropad-adapter · GitHub
次 → NES Classic Editionのコントローラの通信内容解析④
NES Classic Editionのコントローラの通信内容解析②
では、「NES Classic Edition」のコントローラの通信内容について見ていきます。
まず、通信方法なのですがI2Cが使用されています。ですので、スーパーファミコンなどと比べてだいぶ扱い易くなっています。
参考までに以前調査したものです。
スーパーファミコンコントローラの解析 - ハードウェアとか研究所
スーパーファミコンはほぼ独自規格のようなものだったのですが、I2Cであれば既存のマイコンなどでも簡単に扱えます。
コネクタについては以下のページが参考になります。
Wiimote/Extension Controllers - WiiBrew
コネクタには6端子ありますが、1端子が未使用なので使用しているのは実際には5端子です
信号線についてはこちら。
「ミニファミコン」で大きなコントローラーも使えるように改造してみました(ウェブ情報実験室) - Engadget 日本版
上記のページではファミコンクラッシクミニを改造して、クラシックコントローラを接続しています(デフォルトのコントローラが小さいので)。つまり、Wiiなどで使用できるクラシックコントローラで使用されている通信方法とファミコンクラシックミニのコントローラの通信方法は同じだということみたいです(よくよく考えれば当然か)。さらに「NES Classic Edition」のコントローラも同じだということは想像するに易いです。
今回使用した延長ケーブルの中の線には色がついているのですが、参考にしたページと同じでした。以下に載せておきます。
まず、通信方法なのですがI2Cが使用されています。ですので、スーパーファミコンなどと比べてだいぶ扱い易くなっています。
参考までに以前調査したものです。
スーパーファミコンコントローラの解析 - ハードウェアとか研究所
スーパーファミコンはほぼ独自規格のようなものだったのですが、I2Cであれば既存のマイコンなどでも簡単に扱えます。
コネクタについては以下のページが参考になります。
Wiimote/Extension Controllers - WiiBrew
コネクタには6端子ありますが、1端子が未使用なので使用しているのは実際には5端子です
信号線についてはこちら。
「ミニファミコン」で大きなコントローラーも使えるように改造してみました(ウェブ情報実験室) - Engadget 日本版
上記のページではファミコンクラッシクミニを改造して、クラシックコントローラを接続しています(デフォルトのコントローラが小さいので)。つまり、Wiiなどで使用できるクラシックコントローラで使用されている通信方法とファミコンクラシックミニのコントローラの通信方法は同じだということみたいです(よくよく考えれば当然か)。さらに「NES Classic Edition」のコントローラも同じだということは想像するに易いです。
今回使用した延長ケーブルの中の線には色がついているのですが、参考にしたページと同じでした。以下に載せておきます。
- 黄緑色
→ GND - ピンク色
→ VCC(電源)3.3V - 水色
→ SDA(I2Cデータライン) - 白色
→ SCL(I2Cクロックライン) - 黒色
→ デバイス検出(コントローラが接続されているかどうかの検出)
NES Classic Editionのコントローラの通信内容解析①
今回はNES Classic Editionのコントローラと本体で行われている通信内容を解析してみます。
使用するのは海外版ファミコンミニである「NES Classic Edition」です。
「NES Classic Edition」はコントローラをコネクタで接続する仕様になっています。コネクタはWiiリモコンについている拡張コネクタと同様のものが採用されています。今回は改造しない方法を取りますのでWiiリモコンに接続するヌンチャクコントローラのための延長ケーブルを使用します。
簡単に言うと、この延長ケーブルをぶった切って通信内容をプローブします。本体を改造しても同様のことはできるのですが、それをやらないのは所長の任天堂へのリスペクトだと思ってください。
次 → NES Classic Editionのコントローラの通信内容解析②
使用するのは海外版ファミコンミニである「NES Classic Edition」です。
「NES Classic Edition」はコントローラをコネクタで接続する仕様になっています。コネクタはWiiリモコンについている拡張コネクタと同様のものが採用されています。今回は改造しない方法を取りますのでWiiリモコンに接続するヌンチャクコントローラのための延長ケーブルを使用します。
簡単に言うと、この延長ケーブルをぶった切って通信内容をプローブします。本体を改造しても同様のことはできるのですが、それをやらないのは所長の任天堂へのリスペクトだと思ってください。
次 → NES Classic Editionのコントローラの通信内容解析②
登録:
投稿 (Atom)