diff --git a/app/src/main/java/com/saradabar/easyblu/MainActivity.java b/app/src/main/java/com/saradabar/easyblu/MainActivity.java index 05362d3..a09a8d0 100644 --- a/app/src/main/java/com/saradabar/easyblu/MainActivity.java +++ b/app/src/main/java/com/saradabar/easyblu/MainActivity.java @@ -9,7 +9,6 @@ import android.os.Bundle; import android.os.Handler; import android.os.IBinder; -import android.os.Looper; import android.os.RemoteException; import android.provider.Settings; import android.view.View; @@ -32,26 +31,33 @@ public class MainActivity extends Activity { - private static final boolean CT3 = Build.PRODUCT.equals("TAB-A04-BR3"); // CT3 かどうかの真偽値 - private static final String BOOTDEVICE = "/dev/block/platform/bootdevice/mmcblk0"; // 内部ストレージ + private static final String BLOCK_DEVICE = "/dev/block/platform/bootdevice/"; + private static final String BOOTDEVICE = BLOCK_DEVICE + "mmcblk0"; // 内部ストレージ private static final String PART24 = BOOTDEVICE + "p24"; // CT3 で新規パーティションを作成した際の割振番号 + private static final String FRP = "frp"; + private static final String EXPDB = "expdb"; + private static final String FRP_BLOCK = BLOCK_DEVICE + "by-name/" + FRP; // ro.frp.pst と同様 + private static final String FRP_CLONE = "/cache/" + FRP; // FRP のバックアップ + private static final String APP_PATH = "/data/data/com.saradabar.easyblu/cache/"; // getCacheDir() + "/" と同様 - private static final String DCHA_PACKAGE = "jp.co.benesse.dcha.dchaservice"; + private static final boolean CT3 = Build.PRODUCT.equals("TAB-A04-BR3"); // CT3 かどうかの真偽値 + + private static final String DCHA_PACKAGE = "jp.co.benesse.dcha.dchaservice"; // DchaService を使用 private static final String DCHA_SERVICE = DCHA_PACKAGE + ".DchaService"; // copyUpdateImage を使ってシステム権限でファイルを操作 private static final String DCHA_STATE = "dcha_state"; private static final int DIGICHALIZE_STATUS_DIGICHALIZED = 3; // 開発者向けオプションのロック(BenesseExtension.checkPassword)の阻止 private static final String DCHA_SYSTEM_COPY = "/cache/.."; // 内部の if 文で弾かれるのを防ぐ + private static final String SETTINGS_PACKAGE = "com.android.settings"; private static final String SETTINGS_ACTIVITY = SETTINGS_PACKAGE + ".Settings"; // 設定アプリのメインアクティビティ - private static final String FRP_ORIGIN_PATH = "/dev/block/platform/bootdevice/by-name/frp"; // ro.frp.pst と同様 - private static final String FRP_ORIGIN_FILE = "/data/local/tmp/frp"; - private static final String SHRINKER = "shrinker"; // 純正 boot の CTX/CTZ 専用。`getenforce` を実行 + + private static final String GETENFORCE = "getenforce"; private static final String PERMISSIVE = "Permissive"; // デバイスを書き換えられるかどうかの確認 + private static final String SHRINKER = "shrinker"; // 純正 boot の CTX/CTZ 専用。`getenforce` を実行 private static final String MTK_SU = "mtk-su"; // CT3 専用。root シェルを実行 private static final String PARTED = "parted"; // CT3 でデバイスブロックの書き換えに必須 private static final String PARTED_CMD = APP_PATH + PARTED + " -s " + BOOTDEVICE + " "; // parted のコマンド短縮 - private static final String FRP = "frp"; - private static final String EXPDB = "expdb"; + /** * @param savedInstanceState If the activity is being re-initialized after @@ -63,7 +69,6 @@ public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - //requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.activity_main); echo(""" **************************** @@ -81,7 +86,7 @@ protected void onCreate(Bundle savedInstanceState) { * @since v2.1 */ private void callFunc(Runnable func) { - new Handler(Looper.getMainLooper()).post(func); + new Handler(getMainLooper()).post(func); } /** @@ -194,7 +199,16 @@ private void warning(String str) { */ private void error(Exception e) { echo("- エラー:" + System.lineSeparator() + e); - callFunc(this::init); + TextView textView = findViewById(R.id.text_status); + textView.setText("始めからやり直しますか?"); + Button mainButton = findViewById(R.id.button_main); + Button subButton = findViewById(R.id.button_sub); + mainButton.setEnabled(true); + mainButton.setText("はい"); + mainButton.setOnClickListener(v -> callFunc(this::init)); + subButton.setEnabled(true); + subButton.setText("いいえ"); + subButton.setOnClickListener(v -> finish()); } /** @@ -246,7 +260,7 @@ private void init() { /** * エクスプロイト実行関数。SEStatus が Permissive かどうかで処理を分岐する。 * 実行に失敗した場合は自己を再度呼び出す - * @see #getEmmcSize() + * @see #getBlockDeviceSize() * @see #overwriteFrp() * @author Syuugo * @since v2.1 @@ -254,8 +268,8 @@ private void init() { private void setup() { // retry() と同様 exec(APP_PATH + (CT3 ? MTK_SU : SHRINKER)); notify((CT3 ? MTK_SU : SHRINKER) + " を実行しました"); - if (exec("getenforce").toString().contains(PERMISSIVE)) { - notify("成功しました。"); + if (exec(GETENFORCE).toString().contains(PERMISSIVE)) { + notify("SELinux ポリシーの強制を解除しました。"); notify(CT3 ? EXPDB + " のサイズを計算します。" : FRP + " の修正を試みます。"); callFunc(CT3 ? this::checkFixed : this::overwriteFrp); } else { @@ -268,7 +282,7 @@ private void setup() { // retry() と同様 * parted のコマンドを実行 * @param cmd parted のコマンド * @see #exec(String) - * @see #getEmmcSize() + * @see #getBlockDeviceSize() * @see #fixExpdb() * @see #createFrp() * @author Syuugo @@ -288,8 +302,8 @@ private void parted(String cmd) { private void overwriteFrp() { copyAssets(FRP); try { - copyFile(FRP_ORIGIN_PATH, FRP_ORIGIN_FILE); - copyFile(APP_PATH + FRP, FRP_ORIGIN_PATH); + copyFile(FRP_BLOCK, FRP_CLONE); // オリジナルの FRP を cache パテにコピー + copyFile(APP_PATH + FRP, FRP_BLOCK); // 修正済み FRP を適用 } catch (Exception e) { error(e); } @@ -297,10 +311,10 @@ private void overwriteFrp() { } /** - * DchaServicecopyUpdateImage を実行。 + * DchaService{@code copyUpdateImage} を実行。 * システム権限でファイルの操作が可能 * @param src コピー元ファイルパス - * @param dst コピー先ファイルパス。"/cache" から始まる必要があるが相対パス使用可能なので(ry + * @param dst コピー先ファイルパス。{@code /cache} から始まる必要があるが相対パス使用可能なので(ry * @throws RemoteException サービススロー * @see #overwriteFrp() * @author Syuugo @@ -331,14 +345,14 @@ public void onServiceDisconnected(ComponentName componentName) { /** * CT3 において、expdb が修正されているかを確認する関数 - * @see #getEmmcSize() + * @see #getBlockDeviceSize() * @see #fixExpdb() * @see #createFrp() * @author Syuugo * @since v2.0 */ private void checkFixed() { - if (getEmmcSize().contains("124MB 134MB")) { // 純正 expdb のセクタ範囲 + if (getBlockDeviceSize().contains("124MB 134MB")) { // 純正 expdb のセクタ範囲 notify(EXPDB + " は修正されていません。"); } else { notify(EXPDB + " は既に修正済みです。"); @@ -355,9 +369,9 @@ private void checkFixed() { * @since v2.1 */ @NonNull - private String getEmmcSize() { + private String getBlockDeviceSize() { copyAssets(PARTED); - notify("mmcblk0 の詳細を出力します。"); + notify("BOOTDEVICE の詳細を出力します。"); return exec(PARTED_CMD + "print").toString(); } @@ -394,10 +408,6 @@ private void createFrp() { parted("name 24 " + FRP); notify(FRP + " のフラグを修正します。"); parted("toggle 24 msftdata"); - notify("コピーした " + FRP + " の権限を修正します。"); - exec("chmod -v 600 "+ APP_PATH + FRP); - exec("chown -v root:root " + APP_PATH + FRP); - exec("chcon -v u:object_r:" + FRP + "_block_device:s0 " + APP_PATH + FRP); notify(PART24 + " を上書き修正します。"); copyAssets(FRP); exec("dd if=" + APP_PATH + FRP + " of=" + PART24); // 必ずフルパス @@ -418,7 +428,13 @@ private void doBootloader() { Button subButton = findViewById(R.id.button_sub); mainButton.setEnabled(true); mainButton.setText("はい"); - mainButton.setOnClickListener(v -> exec("reboot bootloader")); + mainButton.setOnClickListener(v -> { + try { + exec("reboot bootloader"); + } catch (Exception e) { + error(e); + } + }); subButton.setEnabled(true); subButton.setText("いいえ"); subButton.setOnClickListener(v -> callFunc(this::openSettings));