2012年12月3日月曜日

【Xperia AX SO-01E】セルスタンバイ問題対策

素のAXにMNVO(データ通信しか出来ないタイプ)のチップ突っ込むと、音声通信の電波を探そうとして(?)無駄に電力を消費します。
「設定」→「電源管理」→「電池」→「セルスタンバイ」を見ると、圏外時間が100%と表示されていると思います。
今回はシステムをいじり、この状態を回避しようと試みます。

前提は以下です。
・rootとってあること
・adbコマンドが使える環境であること
・javaが入っていること
・端末のビルド番号は9.0.G.0.247
・CWMを導入してあること
・母艦はWindows 7
・トラブっても自力で復旧できること(つまり自己責任)

いじるシステムファイルは、以下になります。
/system/framework/framework.odex

■必要物資
・framework.jar(dex→odexにする際に必要)
・framework.odex (今回の獲物)
・baksmali-1.4.1.jar(odexをソースファイルに展開するツール)
・smali-1.4.1.jar(ソースファイルをdexにするツール)
・7za.exe(dexをjarに埋め込む際に必要)
・dexopt-wrapper(dex入りのjar→odexを生成するツール)
・bouncycastle.odex(baksmali時に必要)
・core.odex(baksmali時に必要)
・core-junit.odex(baksmali時に必要)
・ext.odex(baksmali時に必要)

baksmaliとsmaliは、「smali」で検索してゲット。
7zaは「7-zip」で検索、コマンドラインバージョンをダウンロードしてゲット。
dexopt-wrapperは http://forum.xda-developers.com/showpost.php?p=3864655&postcount=36 からゲット。
その他jarやodexは端末からぶっこ抜きましょう。
今回のは全部端末の「/system/framework」に入っています。

■1.PCにおける作業フォルダの準備
ここでは「c:\odexwork」とします。
この中に、「old」と「new」フォルダを新規作成します。
必要物資のうち、framework.jarとframework.odexは「old」に入れておいてください。
その他の必要物資は、作業フォルダ直下に全部ぶっこみます。
以降はコマンドラインでの作業になりますが、「odexwork」フォルダをShift押しながら右クリックで「コマンド ウィンドウをここで開く」すると便利です。

□odexwork ┳ □old ┳ framework.jar
      ┃    ┗ framework.odex
      ┣ □new(deodex_framework.jarが入る予定)
      ┣ □framework(作業途中で生成される。ソースファイル群が入る)
      ┣ baksmali-1.4.1.jar
      ┣ smali-1.4.1.jar
      ┣ 7za.exe
      ┣ dexopt-wrapper
      ┣ bouncycastle.odex
      ┣ core.odex
      ┣ core-junit.odex
      ┗ ext.odex

■2.baksmaliする
C:\odexwork>java -Xmx512m -jar baksmali-1.4.1.jar --api-level 15 -x old\framework.odex -o framework

このとき、作業フォルダに必要なodexが無いとエラーが出ますが、エラーの中で何が必要か教えてくれます。
成功すると、作業フォルダ内に「framework」フォルダができ、その中にソースファイルがたくさん入っています。

■3.ソースの書き換え
以下のファイルをテキストエディタで書き換えます。

com\android\internal\telephony\gsm\GsmServiceStateTracker.smali

「.method private regCodeToServiceState(I)I」を検索。(4556行目あたり)
その下の「:pswitch_data_22」を検索。(4610行目あたり)

    :pswitch_data_22
    .packed-switch 0x0
        :pswitch_1c
        :pswitch_1d  #(a)
        :pswitch_1c  #(b1)
        :pswitch_1c
        :pswitch_1c
        :pswitch_1f
        :pswitch_5
        :pswitch_5
        :pswitch_5
        :pswitch_5
        :pswitch_1c
        :pswitch_5
        :pswitch_1c  #(b2)
        :pswitch_1c
        :pswitch_1c
    .end packed-switch
.end method

(a)の部分の文字列を、(b1)と(b2)の部分に上書きする。

    :pswitch_data_22
    .packed-switch 0x0
        :pswitch_1c
        :pswitch_1d  #(a)
        :pswitch_1d  #(b1)
        :pswitch_1c
        :pswitch_1c
        :pswitch_1f
        :pswitch_5
        :pswitch_5
        :pswitch_5
        :pswitch_5
        :pswitch_1c
        :pswitch_5
        :pswitch_1d  #(b2)
        :pswitch_1c
        :pswitch_1c
    .end packed-switch
.end method

書き換えたら保存。

■4.smaliする
C:\odexwork>java -Xmx512m -jar smali-1.4.1.jar --api-level 15 -o classes.dex framework

classes.dexが生成されます。

■5.classes.dexをframework.jarに埋め込み
C:\odexwork>copy /y old\framework.jar new\deodex_framework.jar
C:\odexwork>7za a -tzip -mx0 new\deodex_framework.jar classes.dex
C:\odexwork>del classes.dex

オリジナルのjarと区別をつけるため、「deodex_framework.jar」という名前でjarをコピーしておき、その中にclasses.dexを埋め込みます。


■6.端末をCWMモードにして待機
以降は端末をCWMモードにして作業をすすめます。
理由は安全のためと、転送したファイルの所有者が最初からrootになってて気分が良いから。
CWMの作者様に感謝です。

端末の電源を入れ、SONYロゴが出てから15秒くらいして青LEDが点くのですぐさま音量DOWNボタンを押しっぱなしにし、LEDが緑に変わったらボタンを離します。
しばらくするとCWMのメニュー画面になります。
「mounts and storage」に入り、「mount /system」と「mount /data」をしておきます。
もちろんPCと端末はUSBでつないでおいてください。

■7.ファイルを端末にぶっこむ
C:\odexwork>adb push new\deodex_framework.jar /data/local/tmp
C:\odexwork>adb push dexopt-wrapper /data/local/tmp

多分、rootをとった時に/data/local/tmpは作られていると思うので、それ前提です。

■8.dexopt-wrapperのパーミッション変更
以降は端末のシェルに入っての作業となります。

C:\odexwork>adb shell
~ # cd /data/local/tmp
/data/local/tmp # chmod 0755 dexopt-wrapper

■9.jarからodex生成
/data/local/tmp # ./dexopt-wrapper deodex_framework.jar framework.odex /system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework_ext.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/filterfw.jar

deodex_framework.jarを元に、framework.odexが生成されます。
3つ目の引数がやたら長いですが、これを指定しておかないと、上手くodexが作れません。しかも順番も重要のようですので、この部分は下手にいじらないほうが良いでしょう。

本来3つ目の引数には、BOOTCLASSPATHという環境変数を指定するそうで、これはSO-01Eの場合、

/system/framework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/framework/framework.jar:/system/framework/framework_ext.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/system/framework/apache-xml.jar:/system/framework/filterfw.jar

なのですが、元になるjar(今回の場合はframework.jar)が含まれているとちゃんとしたodexが生成されない場合があったので、削除してあります。

なお、dexopt-wrapperは生成ファイルを上書きできないようですので、すでに/data/local/tmpにframework.odexがある場合は、あらかじめ「rm framework.odex」しておきましょう。

■10.odexに署名をコピー
/data/local/tmp # busybox dd if=/system/framework/framework.odex of=framework.odex bs=1 count=20 skip=52 seek=52 conv=notrunc

手順9で生成したodexは、署名がまずいらしいので、元のodexから署名部分を移植します。

■11.パーミッション変更
出来たodexはすでにパーミッションが0644になってるかもしれませんが、念の為。

/data/local/tmp # chmod 0644 framework.odex

framework.odexのパーミッションを0644に変更。

■12.仕上げ
/data/local/tmp # mv /system/framework/framework.odex /system/framework/framework.odex.bak
/data/local/tmp # cp framework.odex /system/framework
/data/local/tmp # reboot

元のファイルをリネームしてバックアップ(すでにしたことがあれば不要)しておき、新しいframework.odexを/system/frameworkに配置。
そして再起動。
ちゃんと起動したら成功と思われます。

13 件のコメント:

  1. 初めまして
    SO-02Cのセルスタンバイ問題を解決策を検索してたどり着きました。
    ■4.smaliする の作業で下記のようなエラーが出てしまいます。原因がわからないため、もしよろしければアドバイスをいただけないでしょうか?
    よろしくお願いいたします。

    C:\odexwork>java -Xmx512m -jar baksmali-1.4.2.jar --api-level 15 -x old\framewor
    k.odex -o framework


    UNEXPECTED TOP-LEVEL EXCEPTION:
    org.jf.dexlib.Util.ExceptionWithContext: regCount does not match the number of a
    rguments of the method
    at org.jf.dexlib.Util.ExceptionWithContext.withContext(ExceptionWithCont
    ext.java:54)
    at org.jf.dexlib.Code.InstructionIterator.IterateInstructions(Instructio
    nIterator.java:91)
    at org.jf.dexlib.CodeItem.readItem(CodeItem.java:154)
    at org.jf.dexlib.Item.readFrom(Item.java:77)
    at org.jf.dexlib.OffsettedSection.readItems(OffsettedSection.java:48)
    at org.jf.dexlib.Section.readFrom(Section.java:143)
    at org.jf.dexlib.DexFile.(DexFile.java:431)
    at org.jf.baksmali.main.main(main.java:280)
    Caused by: java.lang.RuntimeException: regCount does not match the number of arg
    uments of the method
    at org.jf.dexlib.Code.Format.Instruction3rc.checkItem(Instruction3rc.jav
    a:129)
    at org.jf.dexlib.Code.Format.Instruction3rc.(Instruction3rc.java:7
    9)
    at org.jf.dexlib.Code.Format.Instruction3rc.(Instruction3rc.java:4
    4)
    at org.jf.dexlib.Code.Format.Instruction3rc$Factory.makeInstruction(Inst
    ruction3rc.java:145)
    at org.jf.dexlib.Code.InstructionIterator.IterateInstructions(Instructio
    nIterator.java:82)
    ... 6 more
    Error occured at code address 0
    code_item @0x12c8cc

    返信削除
    返信
    1. SO-02Cですよね。ということは、Android 2.3.4だと思いますが、そうであれば、API Levelは15ではなくて10のはずです。
      ですので、手順2のbaksmaliと手順4のsmaliコマンド内の「--api-level」の後の数字が「15」ではまずいと思いますので、「10」に変更してやってみてください。

      また、手順9においてコマンド引数として必要となる「BOOTCLASSPATH」の内容が異なる可能性もありますので、adb shellで端末のシェルに入り、「printenv」を実行して表示される中の「BOOTCLASSPATH=」の後の記述を確認してください。

      ともかく、ICSのSO-01EとGBのSO-02Cでは何かといろいろ異なっている可能性があり、こちらでは確認しかねますので、acroとかarcでいじっておられるサイト等を参考にされた方が早いかもしれませんね…。

      削除
    2. 早速アドバイスいただきありがとうございます。
      ご指摘の通り手順2を修正し、順調に進みましたが、
      手順8のところで下記のようなエラーが出ているようです。
      たびたび申し訳ありませんが、アドバイスをいただけないでしょうか?
      よろしくお願いいたします。

      C:\odexwork>adb shell
      ~ # cd /data/local/tmp
      cd /data/local/tmp
      /sbin/sh: cd: can't cd to /data/local/tmp
      ~ # chmod 0755 dexopt-wrapper
      chmod 0755 dexopt-wrapper
      chmod: dexopt-wrapper: No such file or directory
      ~ #

      削除
    3. エラーメッセージの通りで、おそらく /data/local/tmp が存在していないと思われますので、まず該当ディレクトリを作成してください。
      当然、手順7も失敗しているはずですので、手順7からやり直してください。

      …と、このあたりは端末をいじるうえで基本となる部分ですので、今後はご自身で十分にお調べになってからカスタムされた方がよろしいかと。

      削除
  2. キューブキューブ様
    大変お世話になっております。
    何度も、初心者の頓珍漢な質問に答えていただきありがとうございます。
    先ほどのご指摘は、/data/が書き込み不可になっておりましたので修正後順調に処理できました。
    が、最初のご指摘通り手順9で
    /sbin/sh: dexopt-wrapper: not found
    とでておりなんとなくエラーのような気がしております。

    C:\odexwork>del classes.dex

    C:\odexwork>adb push new\deodex_framework.jar /data/local/tmp
    * daemon not running. starting it now on port 5037 *
    * daemon started successfully *
    4924 KB/s (7281783 bytes in 1.444s)

    C:\odexwork>adb push dexopt-wrapper /data/local/tmp
    897 KB/s (5512 bytes in 0.006s)

    C:\odexwork>adb shell
    ~ # cd /data/local/tmp
    cd /data/local/tmp
    /data/local/tmp # chmod 0755 dexopt-wrapper
    chmod 0755 dexopt-wrapper
    /data/local/tmp # dexopt-wrapper deodex_framework.jar framework.odex /system/framework/core.jar:/sys
    tem/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/fr
    amework/framework_ext.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/syste
    m/framework/apache-xml.jar:/system/framework/filterfw.jar
    dexopt-wrapper deodex_framework.jar framework.odex /system/fra
    mework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastle.
    jar:/system/framework/ext.jar:/system/framework/framework_ext.jar:/system/framew
    ork/android.policy.jar:/system/framework/services.jar:/system/framework/apache-x
    ml.jar:/system/framework/filterfw.jar
    /sbin/sh: dexopt-wrapper: not found
    /data/local/tmp # busybox dd if=/system/framework/framework.odex of=framework.odex bs=1 count=20 ski
    p=52 seek=52 conv=notrunc
    busybox dd if=/system/framework/framework.odex of=framework.od
    ex bs=1 count=20 skip=52 seek=52 conv=notrunc
    20+0 records in
    20+0 records out
    20 bytes (20B) copied, 0.006562 seconds, 3.0KB/s

    アドバイスのとおり
    adb shellで端末のシェルに入り、「printenv」を実行して表示される中の「BOOTCLASSPATH=」をおこないましたが
    C:\odexwork>adb shell
    ~ # printenv
    printenv
    EXTERNAL_STORAGE=/sdcard
    ANDROID_DATA=/data
    PATH=/sbin
    ANDROID_ROOT=/system
    PWD=
    ANDROID_PROPERTY_WORKSPACE=9,32768
    ~ #
    と表示され、ご指摘の内容と違う内容となってしまいました。

    たびたび大変恐縮ですが、再度アドバイスをいただけると
    ありがたく思います。よろしくお願いいたします。

    返信削除
    返信
    1. まず、手順9冒頭の、dexopt-wrapperの前の「./」が抜けています。良く見てください。
      これもlinuxの基本で、パスの通っていないディレクトリのコマンドはコマンド名だけでは実行できません。

      それから、BOOTCLASSPATHの件は、dexopt-wrapperをもう少しお調べになってからの方が良いのではないかと思います。今のご理解のされ方では正直怖いですので。
      とりあえずは手順9そのままのコマンドでいけるとは思いますが。

      再三になりますが、あらゆるキーワードでお調べになって、いろいろ試行錯誤してください。「SO-02C セルスタンバイ」等で検索されましたか?

      削除
  3. キューブキューブ様
    お世話になっております。
    ご指摘ありがとうございました。
    セルスタンバイについては、かなり調べたと思います。
    他のページでは、linuxでされていると思われるのばかりで
    windowsでは、コマンドが違うのか、はじかれるのばかりでした。

    おかげさまで、処理は最後まで行きましたが、再起動した後、sonyericssonマークで無限ループの状態となっております。
    今回は特にエラーもなく処理できているのではと考えております。
    また、/data/local/tmp はからの状態でした。
    この3日間、初心者なりに頑張りましたが、
    本日のところは、ここで終了させていただきます。
    本当にありがとうございました。

    C:\odexwork>adb push new\deodex_framework.jar /data/local/tmp
    4653 KB/s (7281783 bytes in 1.528s)

    C:\odexwork>adb push dexopt-wrapper /data/local/tmp
    1076 KB/s (5512 bytes in 0.005s)

    C:\odexwork>adb shell
    ~ # cd /data/local/tmp
    cd /data/local/tmp
    /data/local/tmp # chmod 0755 dexopt-wrapper
    chmod 0755 dexopt-wrapper
    /data/local/tmp # ./dexopt-wrapper deodex_framework.jar framework.odex /system/framework/core.jar:/s
    ystem/framework/core-junit.jar:/system/framework/bouncycastle.jar:/system/framework/ext.jar:/system/
    framework/framework_ext.jar:/system/framework/android.policy.jar:/system/framework/services.jar:/sys
    tem/framework/apache-xml.jar:/system/framework/filterfw.jar
    ./dexopt-wrapper deodex_framework.jar framework.odex /system/f
    ramework/core.jar:/system/framework/core-junit.jar:/system/framework/bouncycastl
    e.jar:/system/framework/ext.jar:/system/framework/framework_ext.jar:/system/fram
    ework/android.policy.jar:/system/framework/services.jar:/system/framework/apache
    -xml.jar:/system/framework/filterfw.jar
    --- BEGIN 'deodex_framework.jar' (bootstrap=0) ---
    --- would reduce privs here
    --- waiting for verify+opt, pid=154
    --- END 'deodex_framework.jar' --- status=0x000b, process failed
    /data/local/tmp # busybox dd if=/system/framework/framework.odex of=framework.odex bs=1 count=20 ski
    p=52 seek=52 conv=notrunc
    busybox dd if=/system/framework/framework.odex of=framework.od
    ex bs=1 count=20 skip=52 seek=52 conv=notrunc
    20+0 records in
    20+0 records out
    20 bytes (20B) copied, 0.004547 seconds, 4.3KB/s
    /data/local/tmp # chmod 0644 framework.odex
    chmod 0644 framework.odex
    /data/local/tmp # mv /system/framework/framework.odex /system/framework/framework.odex.bak
    mv /system/framework/framework.odex /system/framework/framewor
    k.odex.bak
    /data/local/tmp # cp framework.odex /system/framework
    cp framework.odex /system/framework
    /data/local/tmp # reboot
    reboot

    返信削除
  4. はじめまして、SO-01Eを購入しようか考えていてたどり着きました。
    セルスタンバイ問題対策後、アイドル状態(Gmail待受のみぐらい)では一時間あたりどれくらいのバッテリー消費量になるかもしよろしければ教えていただけないでしょうか?

    返信削除
    返信
    1. きちんと検証したわけでもありませんし、減り方も一定ではなく環境や状況にもよると思いますので、私からは何とも言えません。
      ザックリとで良いなら、待ち受けで画面オフで平均1%/hくらいの感覚ですかね。
      個体差はあるかもしれませんが、私のSO-01Eはほとんど不満も無く快適に使えていますよ。

      削除
    2. 早速のお返事ありがとうございます!
      1%/hだと実用的ですねいいですね。参考になりましたありがとうございます。

      削除
  5. はじめまして!
    セルスタ問題検索していたところこちらに流れ着きました。

    早速ですが最新版のAndroid4.1.2でも大丈夫でしょうか?

    返信削除
    返信
    1. そのあたりの処理はICS→JBでもさほど変わってないと思いますので、同様の対処でイケると思います。

      削除
  6. 初めまして。
    Galaxy Tab 7.7 Plus(SC-01E)OMAMF2で成功しました。

    今まで他のサイトで公開されていたいくつかのframework.odexを書き込んでも起動しなくなってしまいましたが、ずぼらをしないでここの方法通りにするとちゃんと起動し圏外時間も100%から減っていきました。

    バッテリーの持ちがどうなるかはまだわかりませんが、とにかくありがとうございました。

    返信削除