mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-26 05:37:38 +00:00
Add SafetyNet check
This commit is contained in:
parent
3c33f7d294
commit
442e840a53
@ -2,7 +2,7 @@ apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion 25
|
||||
buildToolsVersion "25.0.1"
|
||||
buildToolsVersion "25.0.2"
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.topjohnwu.magisk"
|
||||
@ -49,9 +49,9 @@ repositories {
|
||||
|
||||
dependencies {
|
||||
compile fileTree(include: ['*.jar'], dir: 'libs')
|
||||
compile 'com.android.support:recyclerview-v7:25.0.1'
|
||||
compile 'com.android.support:cardview-v7:25.0.1'
|
||||
compile 'com.android.support:design:25.0.1'
|
||||
compile 'com.android.support:recyclerview-v7:25.1.0'
|
||||
compile 'com.android.support:cardview-v7:25.1.0'
|
||||
compile 'com.android.support:design:25.1.0'
|
||||
compile 'com.jakewharton:butterknife:8.4.0'
|
||||
compile 'com.google.code.gson:gson:2.8.0'
|
||||
compile 'com.github.clans:fab:1.6.4'
|
||||
@ -59,5 +59,6 @@ dependencies {
|
||||
compile 'com.madgag.spongycastle:prov:1.54.0.0'
|
||||
compile 'com.madgag.spongycastle:pkix:1.54.0.0'
|
||||
compile 'com.madgag.spongycastle:pg:1.54.0.0'
|
||||
compile 'com.google.android.gms:play-services-safetynet:10.0.1'
|
||||
annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
|
||||
}
|
||||
|
@ -52,6 +52,10 @@
|
||||
android:resource="@xml/file_paths" />
|
||||
</provider>
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version" />
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
|
@ -5,9 +5,11 @@ import android.content.SharedPreferences;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.topjohnwu.magisk.utils.Async;
|
||||
import com.topjohnwu.magisk.utils.Logger;
|
||||
import com.topjohnwu.magisk.utils.SafetyNetHelper;
|
||||
import com.topjohnwu.magisk.utils.Utils;
|
||||
|
||||
public class SplashActivity extends AppCompatActivity {
|
||||
@ -36,6 +38,24 @@ public class SplashActivity extends AppCompatActivity {
|
||||
.putBoolean("hosts", Utils.itemExist(false, "/magisk/.core/hosts"))
|
||||
.apply();
|
||||
|
||||
// Simple POC for checking SN status
|
||||
new SafetyNetHelper(getApplicationContext()) {
|
||||
@Override
|
||||
public void handleResults(int i) {
|
||||
switch (i) {
|
||||
case -1:
|
||||
Toast.makeText(mContext, "SN: Error", Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case 0:
|
||||
Toast.makeText(mContext, "SN: Fail", Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case 1:
|
||||
Toast.makeText(mContext, "SN: Success", Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}.requestTest();
|
||||
|
||||
new Async.CheckUpdates(prefs).exec();
|
||||
|
||||
new Async.LoadModules(prefs) {
|
||||
|
@ -178,10 +178,10 @@ public class Async {
|
||||
Logger.dev("FlashZip: File created successfully - " + mCachedFile.getPath());
|
||||
in.close();
|
||||
} catch (FileNotFoundException e) {
|
||||
Log.e(Logger.LOG_TAG, "FlashZip: Invalid Uri");
|
||||
Log.e(Logger.TAG, "FlashZip: Invalid Uri");
|
||||
throw e;
|
||||
} catch (IOException e) {
|
||||
Log.e(Logger.LOG_TAG, "FlashZip: Error in creating file");
|
||||
Log.e(Logger.TAG, "FlashZip: Error in creating file");
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
@ -4,23 +4,29 @@ import android.util.Log;
|
||||
|
||||
public class Logger {
|
||||
|
||||
public static final String LOG_TAG = "Magisk: DEV";
|
||||
public static final String TAG = "Magisk";
|
||||
public static final String DEV_TAG = "Magisk: DEV";
|
||||
public static final String DEBUG_TAG = "Magisk: DEBUG";
|
||||
|
||||
public static boolean logShell, devLog;
|
||||
|
||||
public static void debug(String msg) {
|
||||
Log.d(DEBUG_TAG, msg);
|
||||
}
|
||||
|
||||
public static void dev(String msg, Object... args) {
|
||||
if (devLog) {
|
||||
if (args.length == 1 && args[0] instanceof Throwable) {
|
||||
Log.d(LOG_TAG, msg, (Throwable) args[0]);
|
||||
Log.d(DEV_TAG, msg, (Throwable) args[0]);
|
||||
} else {
|
||||
Log.d(LOG_TAG, String.format(msg, args));
|
||||
Log.d(DEV_TAG, String.format(msg, args));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void dev(String msg) {
|
||||
if (devLog) {
|
||||
Log.d(LOG_TAG, msg);
|
||||
Log.d(DEV_TAG, msg);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,84 @@
|
||||
package com.topjohnwu.magisk.utils;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Base64;
|
||||
|
||||
import com.google.android.gms.common.ConnectionResult;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.google.android.gms.common.api.Status;
|
||||
import com.google.android.gms.safetynet.SafetyNet;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Arrays;
|
||||
|
||||
public abstract class SafetyNetHelper
|
||||
implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
|
||||
|
||||
private GoogleApiClient mGoogleApiClient;
|
||||
protected Context mContext;
|
||||
|
||||
public SafetyNetHelper(Context context) {
|
||||
mContext = context;
|
||||
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
|
||||
.addApi(SafetyNet.API)
|
||||
.addConnectionCallbacks(this)
|
||||
.addOnConnectionFailedListener(this)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionFailed(@NonNull ConnectionResult result) {
|
||||
Logger.dev("SN: Google API fail");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnected(@Nullable Bundle bundle) {
|
||||
Logger.dev("SN: Google API Connected");
|
||||
safetyNetCheck();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnectionSuspended(int i) {
|
||||
Logger.dev("SN: Google API Suspended");
|
||||
}
|
||||
|
||||
public void requestTest() {
|
||||
// Connect Google Service
|
||||
mGoogleApiClient.connect();
|
||||
}
|
||||
|
||||
private void safetyNetCheck() {
|
||||
// Create nonce
|
||||
byte[] nonce = new byte[24];
|
||||
new SecureRandom().nextBytes(nonce);
|
||||
|
||||
Logger.dev("SN: Check with nonce: " + Base64.encodeToString(nonce, Base64.DEFAULT));
|
||||
|
||||
// Call SafetyNet
|
||||
SafetyNet.SafetyNetApi.attest(mGoogleApiClient, nonce)
|
||||
.setResultCallback(result -> {
|
||||
Status status = result.getStatus();
|
||||
if (status.isSuccess()) {
|
||||
String json = new String(Base64.decode(result.getJwsResult().split("\\.")[1], Base64.DEFAULT));
|
||||
Logger.dev("SN: Response: " + json);
|
||||
try {
|
||||
JSONObject decoded = new JSONObject(json);
|
||||
handleResults(decoded.getBoolean("ctsProfileMatch") ? 1 : 0);
|
||||
} catch (JSONException ignored) {}
|
||||
} else {
|
||||
Logger.dev("SN: No response");
|
||||
handleResults(-1);
|
||||
}
|
||||
// Disconnect
|
||||
mGoogleApiClient.disconnect();
|
||||
});
|
||||
}
|
||||
|
||||
public abstract void handleResults(int i);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user