Eliminate any traces of Java in app

This commit is contained in:
topjohnwu 2019-08-08 00:59:23 -07:00
parent 48395ba860
commit f2494374f8
14 changed files with 182 additions and 212 deletions

View File

@ -17,9 +17,9 @@
#} #}
# Snet # Snet
-keepclassmembers class com.topjohnwu.magisk.utils.ISafetyNetHelper { *; } -keepclassmembers class com.topjohnwu.magisk.utils.SafetyNetHelper { *; }
-keep,allowobfuscation interface com.topjohnwu.magisk.utils.ISafetyNetHelper$Callback -keep,allowobfuscation interface com.topjohnwu.magisk.utils.SafetyNetHelper$Callback
-keepclassmembers class * implements com.topjohnwu.magisk.utils.ISafetyNetHelper$Callback { -keepclassmembers class * implements com.topjohnwu.magisk.utils.SafetyNetHelper$Callback {
void onResponse(int); void onResponse(int);
} }

View File

@ -2,14 +2,14 @@ package a;
import android.content.Context; import android.content.Context;
import com.topjohnwu.magisk.model.worker.DelegateWorker;
import java.lang.reflect.ParameterizedType;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import androidx.work.Worker; import androidx.work.Worker;
import androidx.work.WorkerParameters; import androidx.work.WorkerParameters;
import com.topjohnwu.magisk.model.worker.DelegateWorker;
import java.lang.reflect.ParameterizedType;
public abstract class w<T extends DelegateWorker> extends Worker { public abstract class w<T extends DelegateWorker> extends Worker {
/* Wrapper class to workaround Proguard -keep class * extends Worker */ /* Wrapper class to workaround Proguard -keep class * extends Worker */
@ -22,7 +22,7 @@ public abstract class w<T extends DelegateWorker> extends Worker {
try { try {
base = ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()) base = ((Class<T>) ((ParameterizedType) getClass().getGenericSuperclass())
.getActualTypeArguments()[0]).newInstance(); .getActualTypeArguments()[0]).newInstance();
base.setActualWorker(this); base.attachWorker(this);
} catch (Exception ignored) {} } catch (Exception ignored) {}
} }

View File

@ -20,7 +20,6 @@ object ClassMap {
SuRequestActivity::class.java to a.m::class.java SuRequestActivity::class.java to a.m::class.java
) )
@JvmStatic
operator fun <T : Class<*>>get(c: Class<*>): T { operator fun <T : Class<*>>get(c: Class<*>): T {
return map.getOrElse(c) { throw IllegalArgumentException() } as T return map.getOrElse(c) { throw IllegalArgumentException() } as T
} }

View File

@ -113,7 +113,6 @@ object Config : PreferenceModel, DBConfig {
var darkTheme by preference(Key.DARK_THEME, true) var darkTheme by preference(Key.DARK_THEME, true)
var suReAuth by preference(Key.SU_REAUTH, false) var suReAuth by preference(Key.SU_REAUTH, false)
var checkUpdate by preference(Key.CHECK_UPDATES, true) var checkUpdate by preference(Key.CHECK_UPDATES, true)
@JvmStatic
var magiskHide by preference(Key.MAGISKHIDE, true) var magiskHide by preference(Key.MAGISKHIDE, true)
var coreOnly by preference(Key.COREONLY, false) var coreOnly by preference(Key.COREONLY, false)
var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false) var showSystemApp by preference(Key.SHOW_SYSTEM_APP, false)

View File

@ -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) {
}
}
}

View File

@ -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
}
}
}

View File

@ -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<String> getTags() {
return worker.getTags();
}
@NonNull
@RequiresApi(24)
public List<Uri> getTriggeredContentUris() {
return worker.getTriggeredContentUris();
}
@NonNull
@RequiresApi(24)
public List<String> getTriggeredContentAuthorities() {
return worker.getTriggeredContentAuthorities();
}
@Nullable
@RequiresApi(28)
public Network getNetwork() {
return worker.getNetwork();
}
public int getRunAttemptCount() {
return worker.getRunAttemptCount();
}
@NonNull
@MainThread
public ListenableFuture<ListenableWorker.Result> startWork() {
return worker.startWork();
}
public boolean isStopped() {
return worker.isStopped();
}
}

View File

@ -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<String>
get() = worker.tags
val triggeredContentUris: List<Uri>
@RequiresApi(24)
get() = worker.triggeredContentUris
val triggeredContentAuthorities: List<String>
@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<ListenableWorker.Result> {
return worker.startWork()
}
}

View File

@ -17,8 +17,8 @@ import com.topjohnwu.magisk.extensions.writeTo
import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.ui.base.MagiskActivity import com.topjohnwu.magisk.ui.base.MagiskActivity
import com.topjohnwu.magisk.ui.base.MagiskFragment import com.topjohnwu.magisk.ui.base.MagiskFragment
import com.topjohnwu.magisk.utils.ISafetyNetHelper
import com.topjohnwu.magisk.utils.DynamicClassLoader import com.topjohnwu.magisk.utils.DynamicClassLoader
import com.topjohnwu.magisk.utils.SafetyNetHelper
import com.topjohnwu.magisk.view.MarkDownWindow import com.topjohnwu.magisk.view.MarkDownWindow
import com.topjohnwu.magisk.view.dialogs.* import com.topjohnwu.magisk.view.dialogs.*
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
@ -26,7 +26,7 @@ import org.koin.androidx.viewmodel.ext.android.viewModel
import java.io.File import java.io.File
class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(), class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
ISafetyNetHelper.Callback { SafetyNetHelper.Callback {
override val layoutRes: Int = R.layout.fragment_magisk override val layoutRes: Int = R.layout.fragment_magisk
override val viewModel: HomeViewModel by viewModel() override val viewModel: HomeViewModel by viewModel()
@ -101,8 +101,8 @@ class HomeFragment : MagiskFragment<HomeViewModel, FragmentMagiskBinding>(),
val clazz = loader.loadClass("com.topjohnwu.snet.Snet") val clazz = loader.loadClass("com.topjohnwu.snet.Snet")
val helper = clazz.getMethod("newHelper", val helper = clazz.getMethod("newHelper",
Class::class.java, String::class.java, Activity::class.java, Any::class.java) Class::class.java, String::class.java, Activity::class.java, Any::class.java)
.invoke(null, ISafetyNetHelper::class.java, EXT_APK.path, .invoke(null, SafetyNetHelper::class.java, EXT_APK.path,
requireActivity(), this) as ISafetyNetHelper activity, this) as SafetyNetHelper
if (helper.version < Const.SNET_EXT_VER) if (helper.version < Const.SNET_EXT_VER)
throw Exception() throw Exception()
helper.attest() helper.attest()

View File

@ -12,7 +12,7 @@ import com.topjohnwu.magisk.extensions.toggle
import com.topjohnwu.magisk.model.events.* import com.topjohnwu.magisk.model.events.*
import com.topjohnwu.magisk.model.observer.Observer import com.topjohnwu.magisk.model.observer.Observer
import com.topjohnwu.magisk.ui.base.MagiskViewModel import com.topjohnwu.magisk.ui.base.MagiskViewModel
import com.topjohnwu.magisk.utils.ISafetyNetHelper import com.topjohnwu.magisk.utils.SafetyNetHelper
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
enum class SafetyNetState { enum class SafetyNetState {
@ -142,8 +142,8 @@ class HomeViewModel(
fun finishSafetyNetCheck(response: Int) = when { fun finishSafetyNetCheck(response: Int) = when {
response and 0x0F == 0 -> { response and 0x0F == 0 -> {
val hasCtsPassed = response and ISafetyNetHelper.CTS_PASS != 0 val hasCtsPassed = response and SafetyNetHelper.CTS_PASS != 0
val hasBasicIntegrityPassed = response and ISafetyNetHelper.BASIC_PASS != 0 val hasBasicIntegrityPassed = response and SafetyNetHelper.BASIC_PASS != 0
safetyNetTitle.value = R.string.safetyNet_check_success safetyNetTitle.value = R.string.safetyNet_check_success
ctsState.value = if (hasCtsPassed) { ctsState.value = if (hasCtsPassed) {
SafetyNetState.PASS SafetyNetState.PASS
@ -164,7 +164,7 @@ class HomeViewModel(
ctsState.value = SafetyNetState.IDLE ctsState.value = SafetyNetState.IDLE
basicIntegrityState.value = SafetyNetState.IDLE basicIntegrityState.value = SafetyNetState.IDLE
safetyNetTitle.value = when (response) { 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 else -> R.string.safetyNet_api_error
} }
} }

View File

@ -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);
}
}

View File

@ -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
}
}

View File

@ -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;
}

View File

@ -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()
}