光iフレーム WDPF-701ME をいじくりまわす

※書きかけ
※正月にxbox360という新しいおもちゃを買ってしまったので、しばらく光iフレームいじりはお休みしそうです。

0. おやくそく (あるいは上島メソッド)

以下に書かれていることを実行すると、最悪 WDPF-701ME が起動不可能になる可能性があります。
レンタル品の場合、買い取りとなって金銭的負担が発生する可能性があります。
また、下記のことを実行すること自体が、レンタル契約の何かしらに違反している可能性があります。

そもそも WDPF-701ME のハードウェア自体があまり質のいいものではないため、下記のことを実行しても使い勝手が向上するかというと微妙です。
筆者は単に「目の前にハック可能な Android 端末がある」のでハックすること自体に意味を見出しているまでです。

というわけで、正直、下記の行為は ま っ た く オ ス ス メ で き な い。
もしどうしてもやるというのであれば、最悪の事態を想定の上、※AT YOUR OWN RISK※ でお願いいたします。
何があっても当方では一切の責任を負うことはできませんのでゴショーチクダサイ。

上島

\やるなよ!絶対にやるなよ!/

1. ひつようなもの

  • TTA-20 な端子を備えた USB ケーブル

国内では COWON S9-USB CABLE が入手性がよいと思います。

http://www.amazon.co.jp/dp/B0023B16L6

ちなみにケーブルの仕様なのか 701ME 側の端子の仕様なのか単なるアンペア不足なのか分かりませんが、このケーブルで PC と接続しても給電/充電されないようです。
また、本体に S9-USB CABLE を挿している状態だとそちらが優先されるらしく、クレードルに乗せても充電されません。
つまり S9-USB ケーブルで繋いでなにかしている間はバッテリ駆動(!)となりますので、事前にフル充電しておくのが良いと思われます。(それでも活動限界約一時間…)

  • Android SDK のインストール

標準 USB ドライバが必要なのと adb shell で接続していろいろ作業するので、もしインストールしていなければ。

2. Android SDK の標準 USB ドライバに 701ME を認識させる

インストールしたままの Android SDK の USB ドライバでは 701ME を認識できずにドライバのインストールができないため、inf ファイルを書き換えます。

pathto/android-sdk-windows/google-usb_driver/android_winusb.inf
(※Windows じゃない環境では適当に読み替えてください)

の [Google.NTx86] のセクションに、以下を追記。

;WDPF-701ME
%SingleAdbInterface% = USB_Install, USB\VID_18D1&PID_0002&MI_01
%CompositeAdbInterface% = USB_Install, USB\VID_18D1&PID_0002&REV_0230&MI_01

えーそんなディレクトリもファイルもネーヨって場合パッケージが入ってない可能性があるので、SDK Manager を起動して下記の画面を参考に USB Driver Package をインストールしてください。

Google Usb Driver Package

しかるのち S9-USB ケーブルで PC と 701ME を繋ぐとドライバのインストールが始まりますので、ドライバを指定するところで先ほどの pathto/android-sdk-windows/google-usb_driver/ を指定し、インストール。
けっこうビックリするくらい長い時間がかかりますが止まっているわけではないので、お茶でも飲んで待つヨロシ。

ドライバのインストールが完了すると多分 PC 再起動を要求されるので従ってください。

3. [LEVEL1] adb install でお好きなアプリをインストール

2 までのステップが終われば adb が使える状態になりますので、フレッツマーケット以外からももっとアプリを入れたい!という要望がかなえられることになります。

コマンドプロンプトを立ち上げ、

C:> adb install アプリ名.apk

とすればインストールされます。701ME の標準ホームでも、ウィジェット一覧にちゃんと出てきます。(あそこってドロワーみたいなもんなんですね)

参考: http://www.adakoda.com/android/000218.html

apk ファイルはググって見つけるか、マーケットが使える別の Android 端末で普通にインストールしたものを AppMonster とか TitaniumBackup などでバックアップしたものから持ってきてください。

4. [LEVEL2] root 権限を取る

ここから先はグッと危険度が増しますのでご注意と覚悟の方も増し増しでお願いいたします。
root 権限の取得方法は比較的簡単ですが、システムファイルを書き換えることになりますので。

  • rageagainstthecage の入手と実行

参考: http://komugi.net/archives/2010/10/26214634.php

↑の記事でもファイル配布してるので、そこからダウンロードします。 アーカイブを展開して出てきたファイル rageagainstthecage-arm5.bin を、本体側のどこか適当な書き込み可能ディレクトリ (/dpfdata とか) に放り込む。

C:> adb push rageagainstthecage-arm5.bin /dpfdata

そして adb shell で以下のコマンドを実行。

C:> adb shell
$ cd /dpfdata
$ chmod 755 rageagainstthecage-arm5.bin
$ ./rageagainstthecage-arm5.bin

root が取れるかはタイミング次第なので、上記実行後に再度 adb shell で接続してプロンプトが # になっていたら成功、なっていなかったらもう一度実行してください。

  • su の修正と Superuser.apk のインストール

この root はテンポラリなものなので、端末を再起動すると元に戻ってしまいます。いつでも root が取れるよう su と Superuser.apk を端末に入れます。

実は su 自体は最初から端末に入っています→ /bin/su と /system/xbin/su
パスの優先順位が /bin が先なので通常に su を叩くと /bin/su が起動されます。
が、setuid されていないので失敗します。
ということで chmod して setuid してあげます。(ついでに Superuser.apk もインストール)

C:> adb install Superuser.apk
C:> adb shell
#cd /bin
#chmod 4755 su

これで次回再起動以後、adb shell で入ってから su で root になることができます。
(/bin/su は busybox なので起動するとメッセージが出ます、これがウザい場合は /bin/su を消して /system/xbin/su を chmod 4755 すると吉)

この元から入っている su に setuid で Superuser.apk が動かない場合があるみたいなので、そのときは /bin/su を消して rageagainstthecage に付属の su を入れてみてください。

5. gapps-ds-ERE36B-signed.zip の導入

(以下はまだメモレベル)

/sdcard にファイルを push

adb push lib\libgtalk_jni.so /sdcard
adb push framework\com.google.android.gtalkservice.jar /sdcard
adb push framework\com.google.android.maps.jar /sdcard
adb push etc\permissions\com.google.android.datamessaging.xml /sdcard
adb push etc\permissions\com.google.android.gtalkservice.xml /sdcard
adb push etc\permissions\com.google.android.maps.xml /sdcard
adb push app\EnhancedGoogleSearchProvider.apk /sdcard
(中略)
adb push app\YouTube.apk /sdcard

/sdcard からそれぞれ所定の位置へファイルをコピー&パーミッション設定

cp /sdcard/libgtalk_jni.so /system/lib
chmod 644 /system/lib/libgtalk_jni.so

cp /sdcard/com.google.android.*.jar /system/framework
chmod 644 /system/framework/com.google.android.*.jar

cp /sdcard/com.google.android.*.xml /system/etc/permissions
chmod 644 /system/etc/permissions/*.xml

cp /sdcard/*.apk /system/app
chmod 755 /system/app/*.apk

/system/app/SetupWizard.apk は要らないので端末へ入れないか、リネームするか消すかしておくと吉です。

ここまででマーケットアプリ自体は起動できるようになるけど、マーケットへのアクセスでエラーが出て先へ進めません。
そもそも端末への Google アカウントの設定がちゃんとできない。

6. /init.rc に Google アカウントを強制設定

どう頑張っても通常のセットアップ手順とかアプリで Google アカウントを設定することが出来なかったので、/init.rc に下記を追記してムリクリにアカウントの設定をしました。

## set google account
setprop ro.setupwizard.mode EMULATOR
setprop ro.config.google_account YOURACCOUNT@gmail.com:YOURPASSWORD

class_start default

追記する場所はどこが適切なのか分かりませんが、とりあえず class_start default の前に書いたら大丈夫だった。
この /init.rc を端末に戻した後パーミッションの設定とか間違ってると文鎮化するので※本気で気をつけてください※。
(文鎮化したらバッテリ抜いてボリュームキーのUpを押しながら電源入れれば初期化モードに入れます)

7. build.prop の編集

端末からファイルとってくる

C:> adb pull /system/build.prop

エディタで build.prop を編集し、下記の行を追加

ro.url.legal=http://www.google.com/intl/%s/mobile/android/basic/phone-legal.html
ro.url.legal.android_privacy=http://www.google.com/intl/%s/mobile/android/basic/privacy.html
ro.com.google.clientidbase=android-google
ro.com.android.wifi-watchlist=GoogleGuest
ro.setupwizard.enterprise_mode=1
ro.setupwizard.enable_bypass=1

fingerprint を何か既存の端末のやつに書き換える

#ro.build.fingerprint=generic/broadcom_cmp/cmp/:2.1/0001/jp.ntt-east.20101112.230454:jp/release
ro.build.fingerprint=verizon/voles/sholes/sholes:2.1-update1/ESE81/29593:user/release-keys

ro.setupwizard.mode をセットしている行があるので、コメントアウトする。(init.rc での指定を上書きしちゃうので。つかこっちを EMULATOR に書き換えてもいいのかも)

端末に戻す

C:> adb push build.prop /sdcard
C:> adb shell
$ su
# cd /system
# mv build.prop build.prop.bak
# cp /sdcard/build.prop ./build.prop

8. androidId の編集

/data/data/com.google.android.googleapps/databases/gls.db の meta テーブルで androidId が 0 になってるんでこれをどうにかする必要がある (多分)

私の環境では別の端末で Google アカウント設定して、select * from meta; で値をメモして持ってきた。
他の端末持ってない人は……どうしましょう。
この辺が参考になりそうです。(SDK のエミュレータで id を生成して持ってくる)

http://d.hatena.ne.jp/umi0/20100809/1281345735

[2011/02/10]
他の端末で使っている Google アカウントと androidId をセットすると、もしかすると market.android.com での Web からのインストールに問題が出るかもしれません。
光iフレーム用に新しくアカウントを作ったほうがいいかも…?

8. MarketEnabler のインストール

入手先: http://code.google.com/p/market-enabler/

C:> adb install MarketEnabler_v3.1.1.2.apk

お約束どおり 44010 にセット

9. reboot して神に祈る

再起動して上記までの諸々の変更を反映させた後、マーケットを起動してみたり終了してみたりしてどうにかならないか頑張ってください。(曖昧)

C:> adb shell am start -a android.intent.action.MAIN -n com.android.settings/.Settings

として設定画面を立ち上げ、アカウントと同期のところに init.rc に書いたアカウントが見えてたら多分うまくいくんじゃないかなと思わないこともない今日この頃です。

ダメだったらアプリケーション>アプリケーションの管理からフィルタを全てにした後、マーケットや Google アカウント管理に関係ありそうなアプリ・サービスのデータを消してみたり強制停止してみたりいろいろしてみましょう。

今のところマーケットが起動してアプリ一覧などを取れるところまでは来ましたが、実際にインストールをしようとすると「ダウンロードを開始中…」のままプログレスバーが止まって実際のデータが降ってこない、というところで詰まっております。

以降はまた後で。

Memo

dmesg 見ると、nand フラッシュのパーティションはこうなっている模様。

14 cmdlinepart partitions found on MTD device bcmumi-nand
Creating 14 MTD partitions on "bcm
umi-nand":
0x000000000000-0x000000080000 : "boot1"
0x000000080000-0x000000100000 : "boot2"
0x000000100000-0x000000200000 : "ctrl"
0x000000200000-0x000001200000 : "nvdata"
0x000001200000-0x000001500000 : "k0"
0x000001500000-0x000001800000 : "k1"
0x000001800000-0x000009800000 : "root0"
0x000009a00000-0x000011800000 : "root1"
0x000011800000-0x000038e00000 : "userdata"
0x000038e00000-0x000058e00000 : "dpfdata"
0x000058e00000-0x000060e00000 : "firmwarestorage"
0x000060e00000-0x000068e00000 : "factoryreset"
0x000068e00000-0x000068e80000 : "serialdata"
0x000009800000-0x000009a00000 : "vcfw"

試しに factoryreset をマウントして中身を覗いてみると……

# cd /tmp
cd /tmp
# mkdir factoryreset
mkdir factoryreset
# mount -t yaffs -o r /dev/mtdblock11 /tmp/factoryreset
mount -t yaffs -o r /dev/mtdblock11 /tmp/factoryreset
# ls -l /tmp/factoryreset
ls -l /tmp/factoryreset
drw-rw-rw- 1 root root 4096 Dec 23 00:42 lost+found
-rwxr-xr-x 1 root root 74032520 Jan 1 1970 ota.bin

このパーティションを使うかどうかは分かりませんが、ボリュームUpキーを押しながら起動すると初期化モードに入るのを発見しました。

recovery mode 1 大きい画像

大きい画像

初期化を実行してみると、見事に初期状態に戻りました。(su も元の使えないファイルに戻っている)
ということで、ブートローダを破壊したりリカバリイメージの入ったパーティションを破壊しない限り、起動しなくなっても最悪初期化モードで立ち上げて初期化すればどうにかなりそうな予感がします!

マーケットのプロトコル

http://www.scribd.com/doc/36452519/Reversing-Android-Market-Protocol

Google アカウントへのログインとかは HTTPS 通信してるがログインできて認証トークンが取れた後は、最終的に HTTP GET でアプリをダウンロードしているらしい。

GET
/market/download/Download?assetId=10075565&userId=7012944&deviceId=195471564845

Cookie: ANDROID=DQAAAJYAAAADnvojSuycBRJjwg0QQkoAxYzN0amI- j9JYi1IUcVqoRqIbDH40OZ88FSt2I2Ury4Ll6bl1tWjyKc5MYJJCTsYuu9v9d1IsSzwkyVw XcE5QFaHR3h-cBW98XHlJkk-BKC4gkcshdhGv-OqHHLpOJmnGmhvuip1_Pc1A7P

Host: android.clients.google.com
Connection: Keep-Alive
User-Agent: AndroidDownloadManager

みたいに。

渡してるパラメータは3つ、assetId はダウンロードしたいアプリのID、deviceId は多分何らかの端末固有IDだけどこれは書き換えてもリクエスト通るそうなので見てないっぽい、userId はなに?

http://typex2.wordpress.com/2009/09/29/android-marketのハック事情:vendingアプリを使わずにandroid-marketのフリ/

もう少し詳しい情報がありました。deviceId=androidId か。ということは androidId は渡してるけど見てないってことですね。うーむ。

changed February 10, 2011