電源ボタンを長押しすると、「電源を切る」等の終了メニューが出てきますが、ここに「再起動」オプションを追加します。
「再起動」をタップしたあとのメッセージは電源を切る時と同じになります。
もっと細かく作り込むことも出来るのでしょうが、いろいろややこしそうですので、とりあえずは再起動が機能することを目標にします。
※なお、こちらの記事の方法を使うと、アイコンや項目の文字を自由に変更できるようになります。
前提は以下です。
・rootとってあること
・adbコマンドが使える環境であること
・javaが入っていること
・端末のビルド番号は9.0.G.0.247
・CWMを導入してあること
・母艦はWindows 7
・トラブっても自力で復旧できること(つまり自己責任)
いじるシステムファイルは、以下になります。
/system/framework/android.policy.odex
■必要物資
・android.policy.jar(dex→odexにする際に必要)
・android.policy.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時に必要)
・framework.odex(baksmali時に必要)
・framework_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」フォルダを新規作成します(すでにある場合はそのまま使います)。
必要物資のうち、android.policy.jarとandroid.policy.odexは「old」に入れておいてください。
その他の必要物資は、作業フォルダ直下に全部ぶっこみます(すでにある物に関してはそのままでいいです)。
以降はコマンドラインでの作業になりますが、「odexwork」フォルダをShift押しながら右クリックで「コマンド ウィンドウをここで開く」すると便利です。
□odexwork ┳ □old ┳ android.policy.jar
┃ ┗ android.policy.odex
┣ □new(deodex_android.policy.jarが入る予定)
┣ □android.policy(作業途中で生成される。ソースファイル群が入る)
┣ baksmali-1.4.1.jar
┣ smali-1.4.1.jar
┣ 7za.exe
┣ dexopt-wrapper
┣ bouncycastle.odex
┣ core.odex
┣ core-junit.odex
┣ ext.odex
┣ framework.odex
┗ framework_ext.odex
┃ ┗ android.policy.odex
┣ □new(deodex_android.policy.jarが入る予定)
┣ □android.policy(作業途中で生成される。ソースファイル群が入る)
┣ baksmali-1.4.1.jar
┣ smali-1.4.1.jar
┣ 7za.exe
┣ dexopt-wrapper
┣ bouncycastle.odex
┣ core.odex
┣ core-junit.odex
┣ ext.odex
┣ framework.odex
┗ framework_ext.odex
■2.baksmaliする
C:\odexwork>java -Xmx512m -jar baksmali-1.4.1.jar --api-level 15 -x old\android.policy.odex -o android.policy
このとき、作業フォルダに必要なodexが無いとエラーが出ますが、エラーの中で何が必要か教えてくれます。
成功すると、作業フォルダ内に「android.policy」フォルダができ、その中にソースファイルがたくさん入っています。
■3.ソースファイルの作成・書き換え等
「android.policy」フォルダ内で、以下のフォルダを探して開きます。
com\android\internal\policy\impl
【3-1】
「GlobalActions$2.smali」というファイルを複製し、「GlobalActions$9.smali」にリネーム。
出来た「GlobalActions$9.smali」の内容をテキストエディタで書き換えます。
ソース内に「GlobalActions$2」が3か所くらい存在しています。(1行目、30行目、44行目あたり)
まず、それらをすべて「GlobalActions$9」 に書き換えます。
次に「.method public onPress()V」を検索(39行目あたり)
その直下の「.registers 3」を「.registers 4」に書き換えます。
# virtual methods
.method public onPress()V
.registers 3
↓↓↓.method public onPress()V
.registers 3
# virtual methods
.method public onPress()V
.registers 4 #変更
.method public onPress()V
.registers 4 #変更
もしかしたら「.registers 3」じゃなくて「.locals 2」とかになっているかもしれませんが、とにかく数字を1つ増やします。
その10行くらい下(50行目あたり)の「const/4 v1, 0x1」を「const-string v1, "now"」に書き換え、空行を挟んで「const/4 v2, 0x1」を追加します。
さらにその直下の「invoke-static うんたらかんたら ->shutdown( うんたらかんたら」の行も書き換えます。
move-result-object v0
const/4 v1, 0x1
invoke-static {v0, v1}, Lcom/android/internal/app/ShutdownThread;->shutdown(Landroid/content/Context;Z)V
↓↓↓const/4 v1, 0x1
invoke-static {v0, v1}, Lcom/android/internal/app/ShutdownThread;->shutdown(Landroid/content/Context;Z)V
move-result-object v0
const-string v1, "now" #変更
const/4 v2, 0x1 #追加
invoke-static {v0, v1, v2}, Lcom/android/internal/app/ShutdownThread;->reboot(Landroid/content/Context;Ljava/lang/String;Z)V #変更
const-string v1, "now" #変更
const/4 v2, 0x1 #追加
invoke-static {v0, v1, v2}, Lcom/android/internal/app/ShutdownThread;->reboot(Landroid/content/Context;Ljava/lang/String;Z)V #変更
v1は再起動の理由(文字列)が入ります。通常の再起動の場合は"now"にしておきます。今すぐ再起動って感じですかね。
v2はシャットダウン確認のダイアログを出すかどうかの値です。0x0にすると「再起動」をタップした途端、確認無しに再起動となります。お好みで。
以上、書き換えたら上書き保存。
【3-2】
「GlobalActions.smali」というファイルを書き換えます。
「.method private createDialog()Landroid/app/AlertDialog;」を検索。(394行目あたり)
その直下の「.registers 14」を「.registers 15」に書き換えます。
.method private createDialog()Landroid/app/AlertDialog;
.registers 14
↓↓↓.registers 14
.method private createDialog()Landroid/app/AlertDialog;
.registers 15 #変更
.registers 15 #変更
これも手順3-1のように「.registers 14」じゃなくて「.locals 13」とかになっているかもしれませんが、とにかく数字を1つ増やします。
その3行くらい下(398行目あたり)に「const v12, 0x1080030」というのがありますが、空行を挟んで「const v13, 0x108004d」を追加します。
.prologue
const v12, 0x1080030
↓↓↓const v12, 0x1080030
.prologue
const v12, 0x1080030
const v13, 0x108004d #追加
const v12, 0x1080030
const v13, 0x108004d #追加
「0x108004d」というのは、点を丸い矢印が取り囲んだアイコンを表します。もし再起動のアイコンが「電源を切る」のアイコンと同じで良ければ、v12の値と同じく「0x1080030」にしておいてください。
その44行くらい下(444行目あたり)に、
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$2;
const v2, 0x10401a7
invoke-direct {v1, p0, v12, v2}, Lcom/android/internal/policy/impl/GlobalActions$2;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
const v2, 0x10401a7
invoke-direct {v1, p0, v12, v2}, Lcom/android/internal/policy/impl/GlobalActions$2;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
という部分があります。
この下に数行記述を追加し、以下のようにします。
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$2;
const v2, 0x10401a7
invoke-direct {v1, p0, v12, v2}, Lcom/android/internal/policy/impl/GlobalActions$2;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$9; #追加
const v2, 0x10403a9 #追加
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$9;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V #追加
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z #追加
const v2, 0x10401a7
invoke-direct {v1, p0, v12, v2}, Lcom/android/internal/policy/impl/GlobalActions$2;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z
new-instance v1, Lcom/android/internal/policy/impl/GlobalActions$9; #追加
const v2, 0x10403a9 #追加
invoke-direct {v1, p0, v13, v2}, Lcom/android/internal/policy/impl/GlobalActions$9;-><init>(Lcom/android/internal/policy/impl/GlobalActions;II)V #追加
invoke-virtual {v0, v1}, Ljava/util/ArrayList;->add(Ljava/lang/Object;)Z #追加
これがメニューの「電源を切る」の下に「再起動」を追加する部分になります。
編集がすんだら上書き保存してください。
■4.smaliする
C:\odexwork>java -Xmx512m -jar smali-1.4.1.jar --api-level 15 -o classes.dex android.policy
classes.dexが生成されます。
■5.classes.dexをandroid.policy.jarに埋め込み
C:\odexwork>copy /y old\android.policy.jar new\deodex_android.policy.jar
C:\odexwork>7za a -tzip -mx0 new\deodex_android.policy.jar classes.dex
C:\odexwork>del classes.dex
C:\odexwork>7za a -tzip -mx0 new\deodex_android.policy.jar classes.dex
C:\odexwork>del classes.dex
オリジナルのjarと区別をつけるため、「deodex_android.policy.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_android.policy.jar /data/local/tmp
C:\odexwork>adb push dexopt-wrapper /data/local/tmp
C:\odexwork>adb push dexopt-wrapper /data/local/tmp
多分、rootをとった時に/data/local/tmpは作られていると思うので、それ前提です。
すでにdexopt-wrapperを導入している場合、2行目は不要です。
■8.dexopt-wrapperのパーミッション変更
以降は端末のシェルに入っての作業となります。
C:\odexwork>adb shell
~ # cd /data/local/tmp
/data/local/tmp # chmod 0755 dexopt-wrapper
~ # cd /data/local/tmp
/data/local/tmp # chmod 0755 dexopt-wrapper
すでにdexopt-wrapperを導入している場合、3行目は不要です。
■9.jarからodex生成
/data/local/tmp #
./dexopt-wrapper deodex_android.policy.jar android.policy.odex
/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/services.jar:/system/framework/apache-xml.jar:/system/framework/filterfw.jar
deodex_android.policy.jarを元に、android.policy.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(今回はandroid.policy.jar)が含まれているとちゃんとしたodexが生成されない場合があったので、削除してあります。
なお、dexopt-wrapperは生成ファイルを上書きできないようですので、すでに/data/local/tmpにandroid.policy.odexがある場合は、あらかじめ「rm android.policy.odex」しておきましょう。
■10.odexに署名をコピー
/data/local/tmp # busybox dd if=/system/framework/android.policy.odex of=android.policy.odex bs=1 count=20 skip=52 seek=52 conv=notrunc
手順9で生成したodexは、署名がまずいらしいので、元のodexから署名部分を移植します。
■11.パーミッション変更
すでにパーミッションが0644になってるかもしれませんが、念の為。
/data/local/tmp # chmod 0644 android.policy.odex
android.policy.odexのパーミッションを0644に変更。
■12.仕上げ
/data/local/tmp # mv /system/framework/android.policy.odex /system/framework/android.policy.odex.bak
/data/local/tmp # cp android.policy.odex /system/framework
/data/local/tmp # reboot
/data/local/tmp # cp android.policy.odex /system/framework
/data/local/tmp # reboot
元のファイルをリネームしてバックアップ(すでにしたことがあれば不要)しておき、新しいandroid.policy.odexを/system/frameworkに配置。
そして再起動。
ちゃんと起動し、電源ボタン長押しでメニューが出たら成功と思われます。
はじめまして、お世話になります。
返信削除私はSO-03Dなんですが、電源オプションに再起動とCWMリカバリは追加しています。スクリーンショットの追加もチャレンジしていますが、これがうまくいきません。
某掲示板のGXスレを参考にframework-res.apkに画像と画像リソースID追加、android.policy.jarのGlobalAction.smali、GlobalAction$9.smali、GlobalAction$9$1.smali、PhoneWindowManager.smali、PhoneWindowManager$23.smaliの修正・追加しました。
電源長押し時には表示されるのですが、動作しません。よろしかったらキューブキューブさんはどうやったかご教授お願いします。
不躾で申し訳ありませんが、宜しくお願いします。
はじめまして。
削除電源メニューのスクリーンショットは、SO-01Eには初めから搭載されているので、そこに関して私は実はいじっていないんですね…。
SO-01Eの場合、GlobalAction$3$1.smali(そちらでのGlobalAction$9$1.smaliに相当するのかな?)の中で「com.sonymobile.intent.action.SCREEN_CAPTURE」というアクションのIntentをsendBroadCastしていて、それをシステムが受け取ってスクリーンショットを撮るような感じになっていますが…SO-03Dとどれだけ違うか分からないので何とも言えませんね。
あまりお役に立てず申し訳無いです。
zをこの記事で弄ってますがGlobalActions$2.smaliを複製してG~$9にリネームとありますがG~$9のファイルが元から存在してますがどうすば良いですか?他機種ですみませんがご教授お願いします。素人で申しわけありません。
返信削除まず機種によって$の後の数字が異なる可能性がありますので、そちらを確認してください。GlobalActions$2.smaliは多分共通していると思いますが、「うんたらかんたら->shutdown()V」が存在していれば大丈夫だと思われます。
削除そしてリネームするファイル名に関して、$の後の数字は既存のファイルとかぶらなければ何でも良いです。もっと言うと数字でなくても良くて、「GlobalActions$CWM.smali」とかでも構いません。ただしその場合は、記事中に出てくる「$9」は(GlobalActions.smaliに追加するコードも含め)すべて読み替えてください。
さらにあらかじめ言うと、この続きの記事に出てくるShutdownThread.smaliは、SO-02Eではおそらくframework.odexではなくservices.odexのcom/android/server/pmにあります。
…正直申し上げるならば、素人を自称されるのであればカスタムはあまりお勧めしません。(一言多くて申し訳無いです。)
この記事を参考にZでカスタムしてる記事がありました。詳しくありがとうございます。
削除はじめまして、お世話になります✞vanishment✞です。ツイッターフォローさせてもらいました
返信削除早速なんですが、先日SO-04E(ミクモデル)を買いましてこちらのサイトを参考にroot化して使っております。
再起動追加に挑戦したいのですが・・・最初の最初でつまずきましてコメントさせてもらいました。
odexworkというファイルはc:\Users\(ユーザー名)\Desktop\odexwork という風に作りました 中身は完璧です・・・たぶん
で、コマンドラインでコマンドを実行すると
Error occured while loading boot class path files. Aborting.
org.jf.dexlib.Util.ExceptionWithContext: Cannot locate boot class path file tele
phony-common.odex
at org.jf.dexlib.Code.Analysis.ClassPath.loadBootClassPath(ClassPath.jav
a:218)
at org.jf.dexlib.Code.Analysis.ClassPath.initClassPath(ClassPath.java:14
6)
at org.jf.dexlib.Code.Analysis.ClassPath.InitializeClassPathFromOdex(Cla
ssPath.java:111)
at org.jf.baksmali.baksmali.disassembleDexFile(baksmali.java:94)
at org.jf.baksmali.main.main(main.java:308)
と出ます どうすればよいのでしょう
母機は windows7 です
不躾で申し訳ありませんが、
キューブキューブさん、ご教授宜しくお願いします。m(_ _)m
で、telephony-common.odexがないということでしょうか?
返信削除SO-04Eのframeworkにはありませんでした
適当にネットから取ってきてもよいのですか?
スイマセンもう一回端末からコピーし直したら
削除ありましたご迷惑をおかけしました