AndroidでMVNOなデータSIMを使うと電界強度(アンテナピクト)が表示されなかったり、セルスタンバイで圏外時間が100%になってしまって電池の消費が激しくなるという問題があったのだけど、それを解決する方法をブローヴちゃん: Android + b-mobile データ専用 SIM で電界強度を表示するで発見したので、試してみました。
上記のページだとdeodexされた環境で逆アセンブルして変更という手法がとられていたけど、手元にあるXperia Acroは非deodex環境だったので、deodex化せずに変更したみたので書いてみた。
注意: rooted環境じゃないとそもそもこのHackは適用できません。いつものことですが、失敗したら確実に文鎮化します。
用意するもの
- adbとかandroidをいじるときのお約束環境
- JDKとか
- Android SDKとか
- smali / baksmali – http://code.google.com/p/smali/
Android dexのアセンブラ・逆アセンブラ - dexopt-wrapper – http://forum.xda-developers.com/showpost.php?p=3864655&postcount=36
- Android側でbusyboxをインストールしておく
- これは用意することではありませんが、あらかじめrootedにしてCWM recoveryなどでnandroid backupを取っておきましょう
手順
- 実機から
/system/framework
を抜いてきます。$ adb pull /system/framework framework
framework.odex
とframework.jar
を作業ディレクトリにコピーします$ mkdir workspace $ cp framework/framework.odex workspace/ $ cp framework/framework.jar workspace/
framework.odex
を逆アセンブルします$ baksmali --api-level 10 -d ../framework -c:core-junit.odex -x framework.odex
-c:
オプションには逆アセンブルに必要なクラスを適宜追加します。Xperia acro(SO-02C)ではオプションを指定しなかった場合、$ baksmali --api-level 10 -d ../framework -x framework.odex Error occured while loading boot class path files. Aborting. org.jf.dexlib.Code.Analysis.ClassPath$ClassNotFoundException: Could not find superclass Ljunit/framework/TestCase; at org.jf.dexlib.Code.Analysis.ClassPath$ClassDef.loadSuperclass(ClassPath.java:830) at org.jf.dexlib.Code.Analysis.ClassPath$ClassDef.(ClassPath.java:683) at org.jf.dexlib.Code.Analysis.ClassPath.loadClassDef(ClassPath.java:280) at org.jf.dexlib.Code.Analysis.ClassPath.initClassPath(ClassPath.java:163) at org.jf.dexlib.Code.Analysis.ClassPath.InitializeClassPathFromOdex(ClassPath.java:110) at org.jf.baksmali.baksmali.disassembleDexFile(baksmali.java:104) at org.jf.baksmali.main.main(main.java:293) Error while loading class Landroid/test/AndroidTestCase; from file framework.odex Error while loading ClassPath class Landroid/test/AndroidTestCase;
こんな感じのエラーが出ました。(この場合
AndroidTestCase
が足りないのでcore-junit.odexを追加します。)- アンテナピクトの扱いを変更する
逆コンパイルしたクラスファイルを編集します。基本的にはブローヴちゃんさんの手順通りですが、展開したout
フォルダにあるcom/android/internal/telephony/gsm/GsmServiceStateTracker.smali
を編集します。
Xperia Acroでは以下のように変更するとうまくいきました。:pswitch_data_22 .packed-switch 0x0 :pswitch_20 :pswitch_1f :pswitch_1f :pswitch_1f :pswitch_20 :pswitch_1f :pswitch_5 :pswitch_5 :pswitch_5 :pswitch_5 :pswitch_20 :pswitch_5 :pswitch_1f :pswitch_1f :pswitch_20 .end packed-switch
ちなみに変更後と変更前でパッチを作りました。
http://nunnun.jp/src/so-02c/GsmServiceStateTracker.smali.patch
パッチとGsmServiceStateTracker.smali
を同一ディレクトリにおいた状態で、$ patch GsmServiceStateTracker.smali < GsmServiceStateTracker.smali.patch
で適用できます。
- 編集した
framework.odex
をアセンブルします
先ほど逆アセンブルを実行した作業ディレクトリに戻って、smali
を実行します。$ smali -o classes.dex out
うまくいくと
classes.dex
が作成されているはずです framework.jar
を展開します
jarファイルはzipファイルなので展開します$ unzip framework.jar -d framework_jar Archive: framework.jar creating: framework_jar/META-INF/ inflating: framework_jar/META-INF/MANIFEST.MF inflating: framework_jar/preloaded-classes
classes.dex
を追加します
先ほどframework.jar
を展開したディレクトリにコピーします。$ cp classes.dex framework_jar/ $ ls -l framework_jar/ total 14336 drwxr-xr-x 3 hiro staff 102 10 10 01:44 META-INF -rw-r--r-- 1 hiro staff 7269368 1 12 21:40 classes.dex -rw-r--r--@ 1 hiro staff 65580 10 10 01:19 preloaded-classes
framework.jar
を再度生成します
先ほどの逆でzipで固めます。$ zip ../framework.jar.new META-INF preloaded-classes classes.dex adding: META-INF/ (stored 0%) adding: preloaded-classes (deflated 82%) adding: classes.dex (deflated 56%)
これでPC側での作業はおわり。
- 実機に必要なファイルをコピーします
どこでもいいのですが、/data/local/tmp
とかに新しく生成したframework.jar.new
とダウンロードしたdexopt-wrapper
を転送して、dexopt-wrapper
を実行可能にします。$ adb push framework.jar.new /data/local/tmp/framework.jar.new 2047 KB/s (3185980 bytes in 1.519s) $ adb push dexopt-wrapper /data/local/tmp/ 609 KB/s (5512 bytes in 0.008s) $ adb shell chmod 755 /data/local/tmp/dexopt-wrapper
dexopt-wrapper
を使ってjarをodexに変換する$ adb shell $ cd /data/local/tmp $ ls dexopt-wrapper framework.jar.new $ ./dexopt-wrapper framework.jar.new framework.odex --- BEGIN 'framework.jar.new' (bootstrap=0) --- --- waiting for verify+opt, pid=7612 --- would reduce privs here --- END 'framework.jar.new' (success) --- $
- 署名をコピーする
このままだと動かないのでオリジナルのframework.odex
から署名部分だけコピーしてきます。$ adb shell $ cd /data/local/tmp $ busybox dd if=/system/framework/framework.odex of=framework.odex bs=1 count=20 skip=52 seek=52 conv=notrunc 20+0 records in 20+0 records out 20 bytes (20B) copied, 0.004334 seconds, 4.5KB/s $ ls -l -rw-r--r-- shell shell 7384328 2012-01-12 21:53 framework.odex -rwxr-xr-x shell shell 5512 2009-05-30 23:15 dexopt-wrapper -rw-rw-rw- shell shell 3185980 2012-01-12 21:42 framework.jar.new
注意 必ず
busybox
のdd
を使ってください。間違えると、conv option disabled
というエラーが返ります。 framework.odex
を置き換える
これはrecovery
とかで実施した方が安全です。
/system
をrwで再マウントして、# cp /data/local/tmp/framework.odex /system/framework/framework.odex.new # mv /system/framework/framework.odex /system/framework/framework.odex.bak # mv /system/framework/framework.odex.new /system/framework/framework.odex # sync
とかします。
やると意外と面倒でした。
いちおう元のframework.odex
とパッチを当てて署名したframework.odex
の差分を取ったパッチを作りました。
- framework.odex.patch
元のframework.odex
MD5 (framework.odex) = 7b474a8d99ab92d4286d422cd6e1d511
パッチ適用後: MD5 (framework_new.odex) = e3ea45b180e9e71bf39d665e4ca8b1ac
こんな感じで適用できるはずです。
$ bspatch framework.odex.bak framework.odex.new framework.odex.patch
間違っているところとかあったら指摘よろしくお願いします。
This work is licensed under a Creative Commons Attribution-ShareAlike 4.0 International License.
こんにちは。
SO-02C+bmobileu300を使っており不具合に困っていたところこのページにたどり着きました。参考にしながら何度も試してみているのですが、差し替え後にsonyロゴループに陥ってしまっています。直書き換えの手順見直しや、条件変更、差分ファイルも利用させてもらって試してもいるのですがうまくいきません。
大変恐縮ですが、もしよろしければ書き換えたframework.odexをお借りすることはできないでしょうか?
よろしくお願いします。