mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-11-28 04:25:27 +00:00
Improve dynamic loading snet package
This commit is contained in:
parent
4956d826fb
commit
f5374a024e
@ -1,13 +1,13 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 26
|
compileSdkVersion 27
|
||||||
buildToolsVersion "26.0.2"
|
buildToolsVersion "27.0.0"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.topjohnwu.magisk"
|
applicationId "com.topjohnwu.magisk"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 26
|
targetSdkVersion 27
|
||||||
versionCode 57
|
versionCode 57
|
||||||
versionName "5.4.0"
|
versionName "5.4.0"
|
||||||
ndk {
|
ndk {
|
||||||
@ -45,10 +45,11 @@ android {
|
|||||||
disable 'MissingTranslation'
|
disable 'MissingTranslation'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
|
google()
|
||||||
maven { url "https://jitpack.io" }
|
maven { url "https://jitpack.io" }
|
||||||
maven { url "https://maven.google.com" }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -43,12 +43,13 @@ import butterknife.Unbinder;
|
|||||||
public class MagiskFragment extends Fragment
|
public class MagiskFragment extends Fragment
|
||||||
implements Topic.Subscriber, SwipeRefreshLayout.OnRefreshListener, ExpandableView {
|
implements Topic.Subscriber, SwipeRefreshLayout.OnRefreshListener, ExpandableView {
|
||||||
|
|
||||||
public static final int CAUSE_SERVICE_DISCONNECTED = 0x00001;
|
public static final int CAUSE_SERVICE_DISCONNECTED = 0x01;
|
||||||
public static final int CAUSE_NETWORK_LOST = 0x00010;
|
public static final int CAUSE_NETWORK_LOST = 0x02;
|
||||||
public static final int RESPONSE_ERR = 0x00100;
|
public static final int RESPONSE_ERR = 0x04;
|
||||||
|
public static final int CONNECTION_FAIL = 0x08;
|
||||||
|
|
||||||
public static final int BASIC_PASS = 0x01000;
|
public static final int BASIC_PASS = 0x10;
|
||||||
public static final int CTS_PASS = 0x10000;
|
public static final int CTS_PASS = 0x20;
|
||||||
|
|
||||||
private Container expandableContainer = new Container();
|
private Container expandableContainer = new Container();
|
||||||
|
|
||||||
@ -331,9 +332,7 @@ public class MagiskFragment extends Fragment
|
|||||||
private void updateSafetyNetUI(int response) {
|
private void updateSafetyNetUI(int response) {
|
||||||
safetyNetProgress.setVisibility(View.GONE);
|
safetyNetProgress.setVisibility(View.GONE);
|
||||||
safetyNetRefreshIcon.setVisibility(View.VISIBLE);
|
safetyNetRefreshIcon.setVisibility(View.VISIBLE);
|
||||||
if (response < 0) {
|
if ((response & 0x0F) == 0) {
|
||||||
safetyNetStatusText.setText(R.string.safetyNet_api_error);
|
|
||||||
} else if ((response & 0x111) == 0) {
|
|
||||||
safetyNetStatusText.setText(R.string.safetyNet_check_success);
|
safetyNetStatusText.setText(R.string.safetyNet_check_success);
|
||||||
|
|
||||||
boolean b;
|
boolean b;
|
||||||
@ -358,9 +357,12 @@ public class MagiskFragment extends Fragment
|
|||||||
resid = R.string.safetyNet_service_disconnected;
|
resid = R.string.safetyNet_service_disconnected;
|
||||||
break;
|
break;
|
||||||
case RESPONSE_ERR:
|
case RESPONSE_ERR:
|
||||||
default:
|
|
||||||
resid = R.string.safetyNet_res_invalid;
|
resid = R.string.safetyNet_res_invalid;
|
||||||
break;
|
break;
|
||||||
|
case CONNECTION_FAIL:
|
||||||
|
default:
|
||||||
|
resid = R.string.safetyNet_api_error;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
safetyNetStatusText.setText(resid);
|
safetyNetStatusText.setText(resid);
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package com.topjohnwu.magisk.asyncs;
|
package com.topjohnwu.magisk.asyncs;
|
||||||
|
|
||||||
import android.support.v4.app.FragmentActivity;
|
import android.app.Activity;
|
||||||
|
|
||||||
import com.topjohnwu.jarsigner.ByteArrayStream;
|
import com.topjohnwu.jarsigner.ByteArrayStream;
|
||||||
import com.topjohnwu.magisk.MagiskManager;
|
import com.topjohnwu.magisk.MagiskManager;
|
||||||
@ -18,15 +18,15 @@ import dalvik.system.DexClassLoader;
|
|||||||
|
|
||||||
public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
||||||
|
|
||||||
public static final int SNET_VER = 2;
|
public static final int SNET_VER = 3;
|
||||||
|
|
||||||
private static final String SNET_URL = "https://github.com/topjohnwu/MagiskManager/releases/download/v5.4.0/snet.apk";
|
private static final String SNET_URL = "https://www.dropbox.com/s/jg2yhcrn3l9fckc/snet.apk?dl=1";
|
||||||
private static final String PKG = "com.topjohnwu.snet";
|
private static final String PKG = "com.topjohnwu.snet";
|
||||||
|
|
||||||
private File dexPath;
|
private File dexPath;
|
||||||
private DexClassLoader loader;
|
private DexClassLoader loader;
|
||||||
|
|
||||||
public CheckSafetyNet(FragmentActivity activity) {
|
public CheckSafetyNet(Activity activity) {
|
||||||
super(activity);
|
super(activity);
|
||||||
dexPath = new File(activity.getCacheDir().getParent() + "/snet", "snet.apk");
|
dexPath = new File(activity.getCacheDir().getParent() + "/snet", "snet.apk");
|
||||||
}
|
}
|
||||||
@ -65,20 +65,21 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onPostExecute(Exception err) {
|
protected void onPostExecute(Exception err) {
|
||||||
|
MagiskManager mm = MagiskManager.get();
|
||||||
try {
|
try {
|
||||||
if (err != null) throw err;
|
if (err != null) throw err;
|
||||||
Class<?> helperClazz = loader.loadClass(PKG + ".SafetyNetHelper");
|
Class<?> helperClazz = loader.loadClass(PKG + ".SafetyNetHelper");
|
||||||
Class<?> callbackClazz = loader.loadClass(PKG + ".SafetyNetCallback");
|
Class<?> callbackClazz = loader.loadClass(PKG + ".SafetyNetCallback");
|
||||||
Object helper = helperClazz.getConstructors()[0].newInstance(
|
Object helper = helperClazz.getConstructors()[0].newInstance(
|
||||||
getActivity(), Proxy.newProxyInstance(
|
getActivity(), dexPath.getPath(), Proxy.newProxyInstance(
|
||||||
loader, new Class[] { callbackClazz }, (proxy, method, args) -> {
|
loader, new Class[] { callbackClazz }, (proxy, method, args) -> {
|
||||||
MagiskManager.get().safetyNetDone.publish(false, args[0]);
|
mm.safetyNetDone.publish(false, args[0]);
|
||||||
return null;
|
return null;
|
||||||
}));
|
}));
|
||||||
helperClazz.getMethod("attest").invoke(helper);
|
helperClazz.getMethod("attest").invoke(helper);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
MagiskManager.get().safetyNetDone.publish(false, -1);
|
mm.safetyNetDone.publish(false, -1);
|
||||||
}
|
}
|
||||||
super.onPostExecute(err);
|
super.onPostExecute(err);
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
package com.topjohnwu.magisk.components;
|
package com.topjohnwu.magisk.components;
|
||||||
|
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.support.annotation.Keep;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.support.v7.app.AppCompatActivity;
|
import android.support.v7.app.AppCompatActivity;
|
||||||
@ -14,7 +17,9 @@ import com.topjohnwu.magisk.utils.Topic;
|
|||||||
|
|
||||||
public class Activity extends AppCompatActivity {
|
public class Activity extends AppCompatActivity {
|
||||||
|
|
||||||
private Runnable permissionGrantCallback;
|
private Runnable permissionGrantCallback = null;
|
||||||
|
private AssetManager mAssetManager = null;
|
||||||
|
private Resources mResources = null;
|
||||||
|
|
||||||
public Activity() {
|
public Activity() {
|
||||||
super();
|
super();
|
||||||
@ -49,6 +54,16 @@ public class Activity extends AppCompatActivity {
|
|||||||
permissionGrantCallback = null;
|
permissionGrantCallback = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public AssetManager getAssets() {
|
||||||
|
return mAssetManager == null ? super.getAssets() : mAssetManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Resources getResources() {
|
||||||
|
return mResources == null ? super.getResources() : mResources;
|
||||||
|
}
|
||||||
|
|
||||||
public void setPermissionGrantCallback(Runnable callback) {
|
public void setPermissionGrantCallback(Runnable callback) {
|
||||||
permissionGrantCallback = callback;
|
permissionGrantCallback = callback;
|
||||||
}
|
}
|
||||||
@ -71,4 +86,25 @@ public class Activity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
public void swapResources(String dexPath) {
|
||||||
|
try {
|
||||||
|
AssetManager asset = AssetManager.class.newInstance();
|
||||||
|
AssetManager.class.getMethod("addAssetPath", String.class).invoke(asset, dexPath);
|
||||||
|
mAssetManager = asset;
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Resources res = super.getResources();
|
||||||
|
mResources = new Resources(mAssetManager, res.getDisplayMetrics(), res.getConfiguration());
|
||||||
|
mResources.newTheme().setTo(super.getTheme());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Keep
|
||||||
|
public void restoreResources() {
|
||||||
|
mAssetManager = null;
|
||||||
|
mResources = null;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
10
build.gradle
10
build.gradle
@ -3,8 +3,6 @@
|
|||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
jcenter()
|
jcenter()
|
||||||
mavenCentral()
|
|
||||||
maven { url "https://maven.google.com" }
|
|
||||||
google()
|
google()
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -15,14 +13,6 @@ buildscript {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
allprojects {
|
|
||||||
repositories {
|
|
||||||
jcenter()
|
|
||||||
maven { url "https://jitpack.io" }
|
|
||||||
google()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task clean(type: Delete) {
|
task clean(type: Delete) {
|
||||||
delete rootProject.buildDir
|
delete rootProject.buildDir
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 26
|
compileSdkVersion 27
|
||||||
buildToolsVersion "26.0.2"
|
buildToolsVersion "27.0.0"
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.topjohnwu.snet"
|
applicationId "com.topjohnwu.snet"
|
||||||
minSdkVersion 21
|
minSdkVersion 21
|
||||||
targetSdkVersion 26
|
targetSdkVersion 27
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
}
|
}
|
||||||
@ -18,7 +18,10 @@ android {
|
|||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
google()
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package com.topjohnwu.snet;
|
package com.topjohnwu.snet;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.app.Activity;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
import android.support.annotation.Nullable;
|
import android.support.annotation.Nullable;
|
||||||
import android.util.Base64;
|
import android.util.Base64;
|
||||||
|
|
||||||
import com.google.android.gms.common.ConnectionResult;
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
|
import com.google.android.gms.common.GoogleApiAvailability;
|
||||||
import com.google.android.gms.common.api.GoogleApiClient;
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
import com.google.android.gms.common.api.ResultCallback;
|
import com.google.android.gms.common.api.ResultCallback;
|
||||||
import com.google.android.gms.common.api.Status;
|
import com.google.android.gms.common.api.Status;
|
||||||
@ -16,49 +17,40 @@ import com.google.android.gms.safetynet.SafetyNetApi;
|
|||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
import java.lang.reflect.Method;
|
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
|
|
||||||
public class SafetyNetHelper
|
public class SafetyNetHelper
|
||||||
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
|
implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
|
||||||
|
|
||||||
public static final int CONNECTION_FAIL = -1;
|
public static final int CAUSE_SERVICE_DISCONNECTED = 0x01;
|
||||||
|
public static final int CAUSE_NETWORK_LOST = 0x02;
|
||||||
|
public static final int RESPONSE_ERR = 0x04;
|
||||||
|
public static final int CONNECTION_FAIL = 0x08;
|
||||||
|
|
||||||
public static final int CAUSE_SERVICE_DISCONNECTED = 0x00001;
|
public static final int BASIC_PASS = 0x10;
|
||||||
public static final int CAUSE_NETWORK_LOST = 0x00010;
|
public static final int CTS_PASS = 0x20;
|
||||||
public static final int RESPONSE_ERR = 0x00100;
|
|
||||||
|
|
||||||
public static final int BASIC_PASS = 0x01000;
|
|
||||||
public static final int CTS_PASS = 0x10000;
|
|
||||||
|
|
||||||
private GoogleApiClient mGoogleApiClient;
|
private GoogleApiClient mGoogleApiClient;
|
||||||
private Context mActivity;
|
private Activity mActivity;
|
||||||
private int responseCode;
|
private int responseCode;
|
||||||
private SafetyNetCallback cb;
|
private SafetyNetCallback cb;
|
||||||
|
private String dexPath;
|
||||||
|
|
||||||
public SafetyNetHelper(Context context, SafetyNetCallback cb) {
|
public SafetyNetHelper(Activity activity, String dexPath, SafetyNetCallback cb) {
|
||||||
mActivity = context;
|
mActivity = activity;
|
||||||
this.cb = cb;
|
this.cb = cb;
|
||||||
|
this.dexPath = dexPath;
|
||||||
responseCode = 0;
|
responseCode = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Entry point to start test
|
// Entry point to start test
|
||||||
public void attest() {
|
public void attest() {
|
||||||
// Connect Google Service
|
// Connect Google Service
|
||||||
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(mActivity);
|
mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
|
||||||
try {
|
.addApi(SafetyNet.API)
|
||||||
// Use reflection to workaround FragmentActivity crap
|
.addOnConnectionFailedListener(this)
|
||||||
Class<?> clazz = Class.forName("com.google.android.gms.common.api.GoogleApiClient$Builder");
|
.addConnectionCallbacks(this)
|
||||||
for (Method m : clazz.getMethods()) {
|
.build();
|
||||||
if (m.getName().equals("enableAutoManage")) {
|
|
||||||
m.invoke(builder, mActivity, this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
mGoogleApiClient = builder.addApi(SafetyNet.API).addConnectionCallbacks(this).build();
|
|
||||||
mGoogleApiClient.connect();
|
mGoogleApiClient.connect();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,7 +60,16 @@ public class SafetyNetHelper
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
|
public void onConnectionFailed(@NonNull ConnectionResult result) {
|
||||||
|
Class<? extends Activity> clazz = mActivity.getClass();
|
||||||
|
try {
|
||||||
|
// Use external resources
|
||||||
|
clazz.getMethod("swapResources", String.class).invoke(mActivity, dexPath);
|
||||||
|
GoogleApiAvailability.getInstance().getErrorDialog(mActivity, result.getErrorCode(), 0).show();
|
||||||
|
clazz.getMethod("restoreResources").invoke(mActivity);
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
cb.onResponse(CONNECTION_FAIL);
|
cb.onResponse(CONNECTION_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -92,22 +93,10 @@ public class SafetyNetHelper
|
|||||||
responseCode |= decoded.getBoolean("ctsProfileMatch") ? CTS_PASS : 0;
|
responseCode |= decoded.getBoolean("ctsProfileMatch") ? CTS_PASS : 0;
|
||||||
responseCode |= decoded.getBoolean("basicIntegrity") ? BASIC_PASS : 0;
|
responseCode |= decoded.getBoolean("basicIntegrity") ? BASIC_PASS : 0;
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
cb.onResponse(RESPONSE_ERR);
|
responseCode = RESPONSE_ERR;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Disconnect
|
// Disconnect
|
||||||
try {
|
|
||||||
// Use reflection to workaround FragmentActivity crap
|
|
||||||
Class<?> clazz = Class.forName("com.google.android.gms.common.api.GoogleApiClient");
|
|
||||||
for (Method m : clazz.getMethods()) {
|
|
||||||
if (m.getName().equals("stopAutoManage")) {
|
|
||||||
m.invoke(mGoogleApiClient, mActivity, this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
mGoogleApiClient.disconnect();
|
mGoogleApiClient.disconnect();
|
||||||
|
|
||||||
// Return results
|
// Return results
|
||||||
|
Loading…
Reference in New Issue
Block a user