From f2494374f83de3ee6d5c500cc9fa3a5214de8a1e Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 8 Aug 2019 00:59:23 -0700 Subject: [PATCH] Eliminate any traces of Java in app --- app/proguard-rules.pro | 6 +- app/src/main/java/a/w.java | 10 +-- .../java/com/topjohnwu/magisk/ClassMap.kt | 1 - .../main/java/com/topjohnwu/magisk/Config.kt | 1 - .../main/java/com/topjohnwu/magisk/Info.java | 31 ------- .../main/java/com/topjohnwu/magisk/Info.kt | 26 ++++++ .../magisk/model/worker/DelegateWorker.java | 84 ------------------- .../magisk/model/worker/DelegateWorker.kt | 59 +++++++++++++ .../topjohnwu/magisk/ui/home/HomeFragment.kt | 8 +- .../topjohnwu/magisk/ui/home/HomeViewModel.kt | 8 +- .../magisk/utils/ISafetyNetHelper.java | 18 ---- .../topjohnwu/magisk/utils/SafetyNetHelper.kt | 21 +++++ .../topjohnwu/magisk/utils/SuConnector.java | 61 -------------- .../com/topjohnwu/magisk/utils/SuConnector.kt | 60 +++++++++++++ 14 files changed, 182 insertions(+), 212 deletions(-) delete mode 100644 app/src/main/java/com/topjohnwu/magisk/Info.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/Info.kt delete mode 100644 app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.kt delete mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/ISafetyNetHelper.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/SafetyNetHelper.kt delete mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.java create mode 100644 app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.kt diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index db9f789a9..37a7fea13 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -17,9 +17,9 @@ #} # Snet --keepclassmembers class com.topjohnwu.magisk.utils.ISafetyNetHelper { *; } --keep,allowobfuscation interface com.topjohnwu.magisk.utils.ISafetyNetHelper$Callback --keepclassmembers class * implements com.topjohnwu.magisk.utils.ISafetyNetHelper$Callback { +-keepclassmembers class com.topjohnwu.magisk.utils.SafetyNetHelper { *; } +-keep,allowobfuscation interface com.topjohnwu.magisk.utils.SafetyNetHelper$Callback +-keepclassmembers class * implements com.topjohnwu.magisk.utils.SafetyNetHelper$Callback { void onResponse(int); } diff --git a/app/src/main/java/a/w.java b/app/src/main/java/a/w.java index e5a2fd89a..17572db75 100644 --- a/app/src/main/java/a/w.java +++ b/app/src/main/java/a/w.java @@ -2,14 +2,14 @@ package a; import android.content.Context; -import com.topjohnwu.magisk.model.worker.DelegateWorker; - -import java.lang.reflect.ParameterizedType; - import androidx.annotation.NonNull; import androidx.work.Worker; import androidx.work.WorkerParameters; +import com.topjohnwu.magisk.model.worker.DelegateWorker; + +import java.lang.reflect.ParameterizedType; + public abstract class w extends Worker { /* Wrapper class to workaround Proguard -keep class * extends Worker */ @@ -22,7 +22,7 @@ public abstract class w extends Worker { try { base = ((Class) ((ParameterizedType) getClass().getGenericSuperclass()) .getActualTypeArguments()[0]).newInstance(); - base.setActualWorker(this); + base.attachWorker(this); } catch (Exception ignored) {} } diff --git a/app/src/main/java/com/topjohnwu/magisk/ClassMap.kt b/app/src/main/java/com/topjohnwu/magisk/ClassMap.kt index 2d8aef096..adf76b4b6 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ClassMap.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ClassMap.kt @@ -20,7 +20,6 @@ object ClassMap { SuRequestActivity::class.java to a.m::class.java ) - @JvmStatic operator fun >get(c: Class<*>): T { return map.getOrElse(c) { throw IllegalArgumentException() } as T } diff --git a/app/src/main/java/com/topjohnwu/magisk/Config.kt b/app/src/main/java/com/topjohnwu/magisk/Config.kt index 8e693f9d0..c9694a4bf 100644 --- a/app/src/main/java/com/topjohnwu/magisk/Config.kt +++ b/app/src/main/java/com/topjohnwu/magisk/Config.kt @@ -113,7 +113,6 @@ object Config : PreferenceModel, DBConfig { var darkTheme by preference(Key.DARK_THEME, true) var suReAuth by preference(Key.SU_REAUTH, false) var checkUpdate by preference(Key.CHECK_UPDATES, true) - @JvmStatic var magiskHide by preference(Key.MAGISKHIDE, true) var coreOnly by preference(Key.COREONLY, false) var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false) diff --git a/app/src/main/java/com/topjohnwu/magisk/Info.java b/app/src/main/java/com/topjohnwu/magisk/Info.java deleted file mode 100644 index 4de190ed6..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/Info.java +++ /dev/null @@ -1,31 +0,0 @@ -package com.topjohnwu.magisk; - -import androidx.annotation.NonNull; - -import com.topjohnwu.magisk.model.entity.UpdateInfo; -import com.topjohnwu.superuser.Shell; -import com.topjohnwu.superuser.ShellUtils; - -public final class Info { - - public static int magiskVersionCode = -1; - - @NonNull - public static String magiskVersionString = ""; - - @NonNull - public static UpdateInfo remote = new UpdateInfo(); - - public static boolean keepVerity = false; - public static boolean keepEnc = false; - public static boolean recovery = false; - - public static void loadMagiskInfo() { - try { - magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":")[0]; - magiskVersionCode = Integer.parseInt(ShellUtils.fastCmd("magisk -V")); - Config.setMagiskHide(Shell.su("magiskhide --status").exec().isSuccess()); - } catch (NumberFormatException ignored) { - } - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/Info.kt b/app/src/main/java/com/topjohnwu/magisk/Info.kt new file mode 100644 index 000000000..f226ae5cf --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/Info.kt @@ -0,0 +1,26 @@ +package com.topjohnwu.magisk + +import com.topjohnwu.magisk.model.entity.UpdateInfo +import com.topjohnwu.superuser.Shell +import com.topjohnwu.superuser.ShellUtils + +object Info { + + var magiskVersionCode = -1 + + var magiskVersionString = "" + + var remote = UpdateInfo() + + var keepVerity = false + var keepEnc = false + var recovery = false + + fun loadMagiskInfo() { + runCatching { + magiskVersionString = ShellUtils.fastCmd("magisk -v").split(":".toRegex())[0] + magiskVersionCode = ShellUtils.fastCmd("magisk -V").toInt() + Config.magiskHide = Shell.su("magiskhide --status").exec().isSuccess + } + } +} diff --git a/app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.java b/app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.java deleted file mode 100644 index f9460e824..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.java +++ /dev/null @@ -1,84 +0,0 @@ -package com.topjohnwu.magisk.model.worker; - -import android.content.Context; -import android.net.Network; -import android.net.Uri; - -import androidx.annotation.MainThread; -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.annotation.RequiresApi; -import androidx.work.Data; -import androidx.work.ListenableWorker; - -import com.google.common.util.concurrent.ListenableFuture; - -import java.util.List; -import java.util.Set; -import java.util.UUID; - -public abstract class DelegateWorker { - - private ListenableWorker worker; - - @NonNull - public abstract ListenableWorker.Result doWork(); - - public void onStopped() {} - - public void setActualWorker(ListenableWorker w) { - worker = w; - } - - @NonNull - public Context getApplicationContext() { - return worker.getApplicationContext(); - } - - @NonNull - public UUID getId() { - return worker.getId(); - } - - @NonNull - public Data getInputData() { - return worker.getInputData(); - } - - @NonNull - public Set getTags() { - return worker.getTags(); - } - - @NonNull - @RequiresApi(24) - public List getTriggeredContentUris() { - return worker.getTriggeredContentUris(); - } - - @NonNull - @RequiresApi(24) - public List getTriggeredContentAuthorities() { - return worker.getTriggeredContentAuthorities(); - } - - @Nullable - @RequiresApi(28) - public Network getNetwork() { - return worker.getNetwork(); - } - - public int getRunAttemptCount() { - return worker.getRunAttemptCount(); - } - - @NonNull - @MainThread - public ListenableFuture startWork() { - return worker.startWork(); - } - - public boolean isStopped() { - return worker.isStopped(); - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.kt b/app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.kt new file mode 100644 index 000000000..fe91cdf82 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/model/worker/DelegateWorker.kt @@ -0,0 +1,59 @@ +package com.topjohnwu.magisk.model.worker + +import android.content.Context +import android.net.Network +import android.net.Uri +import androidx.annotation.MainThread +import androidx.annotation.RequiresApi +import androidx.work.Data +import androidx.work.ListenableWorker +import com.google.common.util.concurrent.ListenableFuture +import java.util.* + +abstract class DelegateWorker { + + private lateinit var worker: ListenableWorker + + val applicationContext: Context + get() = worker.applicationContext + + val id: UUID + get() = worker.id + + val inputData: Data + get() = worker.inputData + + val tags: Set + get() = worker.tags + + val triggeredContentUris: List + @RequiresApi(24) + get() = worker.triggeredContentUris + + val triggeredContentAuthorities: List + @RequiresApi(24) + get() = worker.triggeredContentAuthorities + + val network: Network? + @RequiresApi(28) + get() = worker.network + + val runAttemptCount: Int + get() = worker.runAttemptCount + + val isStopped: Boolean + get() = worker.isStopped + + abstract fun doWork(): ListenableWorker.Result + + fun onStopped() {} + + fun attachWorker(w: ListenableWorker) { + worker = w + } + + @MainThread + fun startWork(): ListenableFuture { + return worker.startWork() + } +} diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt index 42f0d47fb..775ee86ef 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeFragment.kt @@ -17,8 +17,8 @@ import com.topjohnwu.magisk.extensions.writeTo import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.ui.base.MagiskActivity import com.topjohnwu.magisk.ui.base.MagiskFragment -import com.topjohnwu.magisk.utils.ISafetyNetHelper import com.topjohnwu.magisk.utils.DynamicClassLoader +import com.topjohnwu.magisk.utils.SafetyNetHelper import com.topjohnwu.magisk.view.MarkDownWindow import com.topjohnwu.magisk.view.dialogs.* import com.topjohnwu.superuser.Shell @@ -26,7 +26,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel import java.io.File class HomeFragment : MagiskFragment(), - ISafetyNetHelper.Callback { + SafetyNetHelper.Callback { override val layoutRes: Int = R.layout.fragment_magisk override val viewModel: HomeViewModel by viewModel() @@ -101,8 +101,8 @@ class HomeFragment : MagiskFragment(), val clazz = loader.loadClass("com.topjohnwu.snet.Snet") val helper = clazz.getMethod("newHelper", Class::class.java, String::class.java, Activity::class.java, Any::class.java) - .invoke(null, ISafetyNetHelper::class.java, EXT_APK.path, - requireActivity(), this) as ISafetyNetHelper + .invoke(null, SafetyNetHelper::class.java, EXT_APK.path, + activity, this) as SafetyNetHelper if (helper.version < Const.SNET_EXT_VER) throw Exception() helper.attest() diff --git a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt index 285f60874..62c4879b7 100644 --- a/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt +++ b/app/src/main/java/com/topjohnwu/magisk/ui/home/HomeViewModel.kt @@ -12,7 +12,7 @@ import com.topjohnwu.magisk.extensions.toggle import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.ui.base.MagiskViewModel -import com.topjohnwu.magisk.utils.ISafetyNetHelper +import com.topjohnwu.magisk.utils.SafetyNetHelper import com.topjohnwu.superuser.Shell enum class SafetyNetState { @@ -142,8 +142,8 @@ class HomeViewModel( fun finishSafetyNetCheck(response: Int) = when { response and 0x0F == 0 -> { - val hasCtsPassed = response and ISafetyNetHelper.CTS_PASS != 0 - val hasBasicIntegrityPassed = response and ISafetyNetHelper.BASIC_PASS != 0 + val hasCtsPassed = response and SafetyNetHelper.CTS_PASS != 0 + val hasBasicIntegrityPassed = response and SafetyNetHelper.BASIC_PASS != 0 safetyNetTitle.value = R.string.safetyNet_check_success ctsState.value = if (hasCtsPassed) { SafetyNetState.PASS @@ -164,7 +164,7 @@ class HomeViewModel( ctsState.value = SafetyNetState.IDLE basicIntegrityState.value = SafetyNetState.IDLE safetyNetTitle.value = when (response) { - ISafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid + SafetyNetHelper.RESPONSE_ERR -> R.string.safetyNet_res_invalid else -> R.string.safetyNet_api_error } } diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/ISafetyNetHelper.java b/app/src/main/java/com/topjohnwu/magisk/utils/ISafetyNetHelper.java deleted file mode 100644 index 52b6f06c7..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/utils/ISafetyNetHelper.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.topjohnwu.magisk.utils; - -public interface ISafetyNetHelper { - - int RESPONSE_ERR = 0x01; - int CONNECTION_FAIL = 0x02; - - int BASIC_PASS = 0x10; - int CTS_PASS = 0x20; - - void attest(); - - int getVersion(); - - interface Callback { - void onResponse(int responseCode); - } -} diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/SafetyNetHelper.kt b/app/src/main/java/com/topjohnwu/magisk/utils/SafetyNetHelper.kt new file mode 100644 index 000000000..68e7efd82 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/utils/SafetyNetHelper.kt @@ -0,0 +1,21 @@ +package com.topjohnwu.magisk.utils + +interface SafetyNetHelper { + + val version: Int + + fun attest() + + interface Callback { + fun onResponse(responseCode: Int) + } + + companion object { + + val RESPONSE_ERR = 0x01 + val CONNECTION_FAIL = 0x02 + + val BASIC_PASS = 0x10 + val CTS_PASS = 0x20 + } +} diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.java b/app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.java deleted file mode 100644 index f38291651..000000000 --- a/app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.java +++ /dev/null @@ -1,61 +0,0 @@ -package com.topjohnwu.magisk.utils; - -import android.net.LocalSocket; -import android.net.LocalSocketAddress; -import android.os.Bundle; -import android.text.TextUtils; - -import java.io.BufferedInputStream; -import java.io.BufferedOutputStream; -import java.io.DataInputStream; -import java.io.DataOutputStream; -import java.io.IOException; - -public abstract class SuConnector { - - private LocalSocket socket; - protected DataOutputStream out; - protected DataInputStream in; - - protected SuConnector(String name) throws IOException { - socket = new LocalSocket(); - socket.connect(new LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT)); - out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream())); - in = new DataInputStream(new BufferedInputStream(socket.getInputStream())); - } - - private String readString() throws IOException { - int len = in.readInt(); - byte[] buf = new byte[len]; - in.readFully(buf); - return new String(buf, "UTF-8"); - } - - public Bundle readSocketInput() throws IOException { - Bundle bundle = new Bundle(); - while (true) { - String name = readString(); - if (TextUtils.equals(name, "eof")) - break; - bundle.putString(name, readString()); - } - return bundle; - } - - public void response() { - try { - onResponse(); - out.flush(); - } catch (IOException e) { - e.printStackTrace(); - } - try { - in.close(); - out.close(); - socket.close(); - } catch (IOException ignored) { } - } - - protected abstract void onResponse() throws IOException; - -} diff --git a/app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.kt b/app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.kt new file mode 100644 index 000000000..70ce53094 --- /dev/null +++ b/app/src/main/java/com/topjohnwu/magisk/utils/SuConnector.kt @@ -0,0 +1,60 @@ +package com.topjohnwu.magisk.utils + +import android.net.LocalSocket +import android.net.LocalSocketAddress +import android.os.Bundle +import android.text.TextUtils +import timber.log.Timber +import java.io.* +import java.nio.charset.Charset + +abstract class SuConnector @Throws(IOException::class) +protected constructor(name: String) { + + private val socket: LocalSocket = LocalSocket() + protected var out: DataOutputStream + protected var input: DataInputStream + + init { + socket.connect(LocalSocketAddress(name, LocalSocketAddress.Namespace.ABSTRACT)) + out = DataOutputStream(BufferedOutputStream(socket.outputStream)) + input = DataInputStream(BufferedInputStream(socket.inputStream)) + } + + @Throws(IOException::class) + private fun readString(): String { + val len = input.readInt() + val buf = ByteArray(len) + input.readFully(buf) + return String(buf, Charset.forName("UTF-8")) + } + + @Throws(IOException::class) + fun readSocketInput(): Bundle { + val bundle = Bundle() + while (true) { + val name = readString() + if (TextUtils.equals(name, "eof")) + break + bundle.putString(name, readString()) + } + return bundle + } + + fun response() { + runCatching { + onResponse() + out.flush() + }.onFailure { Timber.e(it) } + + runCatching { + input.close() + out.close() + socket.close() + } + } + + @Throws(IOException::class) + protected abstract fun onResponse() + +}