Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in / Register
Toggle navigation
M
Magisk
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Administrator
Magisk
Commits
d2c19689
Commit
d2c19689
authored
Aug 22, 2018
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update snet extension
parent
e42b6084
Hide whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
149 additions
and
256 deletions
+149
-256
AndroidManifest.xml
app/src/full/AndroidManifest.xml
+1
-1
Const.java
app/src/full/java/com/topjohnwu/magisk/Const.java
+0
-2
Data.java
app/src/full/java/com/topjohnwu/magisk/Data.java
+2
-0
MagiskFragment.java
app/src/full/java/com/topjohnwu/magisk/MagiskFragment.java
+2
-8
CheckSafetyNet.java
...full/java/com/topjohnwu/magisk/asyncs/CheckSafetyNet.java
+7
-17
CheckUpdates.java
...c/full/java/com/topjohnwu/magisk/asyncs/CheckUpdates.java
+4
-0
ISafetyNetHelper.java
...ull/java/com/topjohnwu/magisk/utils/ISafetyNetHelper.java
+2
-4
fragment_magisk.xml
app/src/full/res/layout/fragment_magisk.xml
+1
-0
build.gradle
build.gradle
+1
-1
build.gradle
snet/build.gradle
+4
-7
proguard-rules.pro
snet/proguard-rules.pro
+0
-3
ModdedGPSUtil.java
snet/src/main/java/com/topjohnwu/snet/ModdedGPSUtil.java
+0
-148
SafetyNetHelper.java
snet/src/main/java/com/topjohnwu/snet/SafetyNetHelper.java
+86
-62
Snet.java
snet/src/main/java/com/topjohnwu/snet/Snet.java
+5
-3
SwapResContext.java
snet/src/main/java/com/topjohnwu/snet/SwapResContext.java
+34
-0
No files found.
app/src/full/AndroidManifest.xml
View file @
d2c19689
...
...
@@ -79,7 +79,7 @@
<!-- Hardcode GMS version -->
<meta-data
android:name=
"com.google.android.gms.version"
android:value=
"
7095
000"
/>
android:value=
"
12451
000"
/>
</application>
...
...
app/src/full/java/com/topjohnwu/magisk/Const.java
View file @
d2c19689
...
...
@@ -34,7 +34,6 @@ public class Const {
// Versions
public
static
final
int
UPDATE_SERVICE_VER
=
1
;
public
static
final
int
SNET_VER
=
10
;
public
static
int
MIN_MODULE_VER
()
{
return
Data
.
magiskVersionCode
>=
MAGISK_VER
.
REMOVE_LEGACY_LINK
?
1500
:
1400
;
...
...
@@ -76,7 +75,6 @@ public class Const {
public
static
class
Url
{
public
static
final
String
STABLE_URL
=
"https://raw.githubusercontent.com/topjohnwu/magisk_files/master/stable.json"
;
public
static
final
String
BETA_URL
=
"https://raw.githubusercontent.com/topjohnwu/magisk_files/master/beta.json"
;
public
static
final
String
SNET_URL
=
"https://github.com/topjohnwu/magisk_files/raw/a300521162587da23e45010797bfd8c9a03594f6/snet.apk"
;
public
static
final
String
REPO_URL
=
"https://api.github.com/users/Magisk-Modules-Repo/repos?per_page=100&sort=pushed&page=%d"
;
public
static
final
String
FILE_URL
=
"https://raw.githubusercontent.com/Magisk-Modules-Repo/%s/master/%s"
;
public
static
final
String
ZIP_URL
=
"https://github.com/Magisk-Modules-Repo/%s/archive/master.zip"
;
...
...
app/src/full/java/com/topjohnwu/magisk/Data.java
View file @
d2c19689
...
...
@@ -39,6 +39,8 @@ public class Data {
public
static
String
managerLink
;
public
static
String
managerNoteLink
;
public
static
String
uninstallerLink
;
public
static
int
snetVersionCode
;
public
static
String
snetLink
;
// Install flags
public
static
boolean
keepVerity
=
false
;
...
...
app/src/full/java/com/topjohnwu/magisk/MagiskFragment.java
View file @
d2c19689
...
...
@@ -226,11 +226,9 @@ public class MagiskFragment extends BaseFragment
boolean
hasNetwork
=
Download
.
checkNetworkStatus
(
mm
);
boolean
hasRoot
=
Shell
.
rootAccess
();
boolean
hasGms
=
hasGms
();
boolean
isUpToDate
=
Data
.
magiskVersionCode
>
Const
.
MAGISK_VER
.
UNIFIED
;
magiskUpdate
.
setVisibility
(
hasNetwork
?
View
.
VISIBLE
:
View
.
GONE
);
safetyNetCard
.
setVisibility
(
hasNetwork
&&
hasGms
?
View
.
VISIBLE
:
View
.
GONE
);
installOptionCard
.
setVisibility
(
hasNetwork
?
View
.
VISIBLE
:
View
.
GONE
);
uninstallButton
.
setVisibility
(
isUpToDate
&&
hasRoot
?
View
.
VISIBLE
:
View
.
GONE
);
coreOnlyNotice
.
setVisibility
(
mm
.
prefs
.
getBoolean
(
Const
.
Key
.
COREONLY
,
false
)
?
View
.
VISIBLE
:
View
.
GONE
);
...
...
@@ -254,6 +252,8 @@ public class MagiskFragment extends BaseFragment
private
void
updateCheckUI
()
{
int
image
,
color
;
safetyNetCard
.
setVisibility
(
hasGms
()
?
View
.
VISIBLE
:
View
.
GONE
);
if
(
Data
.
remoteMagiskVersionCode
<
0
)
{
color
=
colorNeutral
;
image
=
R
.
drawable
.
ic_help
;
...
...
@@ -312,12 +312,6 @@ public class MagiskFragment extends BaseFragment
}
else
{
@StringRes
int
resid
;
switch
(
response
)
{
case
ISafetyNetHelper
.
CAUSE_SERVICE_DISCONNECTED
:
resid
=
R
.
string
.
safetyNet_network_loss
;
break
;
case
ISafetyNetHelper
.
CAUSE_NETWORK_LOST
:
resid
=
R
.
string
.
safetyNet_service_disconnected
;
break
;
case
ISafetyNetHelper
.
RESPONSE_ERR
:
resid
=
R
.
string
.
safetyNet_res_invalid
;
break
;
...
...
app/src/full/java/com/topjohnwu/magisk/asyncs/CheckSafetyNet.java
View file @
d2c19689
...
...
@@ -2,7 +2,6 @@ package com.topjohnwu.magisk.asyncs;
import
android.app.Activity
;
import
com.topjohnwu.magisk.Const
;
import
com.topjohnwu.magisk.Data
;
import
com.topjohnwu.magisk.utils.ISafetyNetHelper
;
import
com.topjohnwu.magisk.utils.Topic
;
...
...
@@ -20,7 +19,7 @@ import java.net.HttpURLConnection;
import
dalvik.system.DexClassLoader
;
public
class
CheckSafetyNet
extends
ParallelTask
<
Void
,
Void
,
Exception
>
{
public
class
CheckSafetyNet
extends
ParallelTask
<
Void
,
Void
,
Void
>
{
public
static
final
File
dexPath
=
new
File
(
Data
.
MM
().
getFilesDir
().
getParent
()
+
"/snet"
,
"snet.apk"
);
...
...
@@ -33,7 +32,7 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
private
void
dlSnet
()
throws
Exception
{
Shell
.
sh
(
"rm -rf "
+
dexPath
.
getParent
()).
exec
();
dexPath
.
getParentFile
().
mkdir
();
HttpURLConnection
conn
=
WebService
.
mustRequest
(
Const
.
Url
.
SNET_URL
,
null
);
HttpURLConnection
conn
=
WebService
.
mustRequest
(
Data
.
snetLink
,
null
);
try
(
OutputStream
out
=
new
BufferedOutputStream
(
new
FileOutputStream
(
dexPath
));
InputStream
in
=
new
BufferedInputStream
(
conn
.
getInputStream
()))
{
...
...
@@ -52,13 +51,13 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
.
invoke
(
null
,
ISafetyNetHelper
.
class
,
dexPath
.
getPath
(),
getActivity
(),
(
ISafetyNetHelper
.
Callback
)
code
->
Topic
.
publish
(
false
,
Topic
.
SNET_CHECK_DONE
,
code
));
if
(
helper
.
getVersion
()
!=
Const
.
SNET_VER
)
{
if
(
helper
.
getVersion
()
<
Data
.
snetVersionCode
)
{
throw
new
Exception
();
}
}
@Override
protected
Exception
doInBackground
(
Void
...
voids
)
{
protected
Void
doInBackground
(
Void
...
voids
)
{
try
{
try
{
dyload
();
...
...
@@ -67,21 +66,12 @@ public class CheckSafetyNet extends ParallelTask<Void, Void, Exception> {
dlSnet
();
dyload
();
}
}
catch
(
Exception
e
)
{
return
e
;
}
return
null
;
}
@Override
protected
void
onPostExecute
(
Exception
e
)
{
if
(
e
==
null
)
{
// Run attestation
helper
.
attest
();
}
else
{
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
Topic
.
publish
(
false
,
Topic
.
SNET_CHECK_DONE
,
-
1
);
}
super
.
onPostExecute
(
e
)
;
return
null
;
}
}
app/src/full/java/com/topjohnwu/magisk/asyncs/CheckUpdates.java
View file @
d2c19689
...
...
@@ -78,6 +78,10 @@ public class CheckUpdates {
JSONObject
uninstaller
=
getJson
(
json
,
"uninstaller"
);
Data
.
uninstallerLink
=
getString
(
uninstaller
,
"link"
,
null
);
JSONObject
snet
=
getJson
(
json
,
"snet"
);
Data
.
snetVersionCode
=
getInt
(
snet
,
"versionCode"
,
-
1
);
Data
.
snetLink
=
getString
(
snet
,
"link"
,
null
);
}
public
static
void
check
(
Runnable
cb
)
{
...
...
app/src/full/java/com/topjohnwu/magisk/utils/ISafetyNetHelper.java
View file @
d2c19689
...
...
@@ -4,10 +4,8 @@ import android.support.annotation.Keep;
public
interface
ISafetyNetHelper
{
int
CAUSE_SERVICE_DISCONNECTED
=
0x01
;
int
CAUSE_NETWORK_LOST
=
0x02
;
int
RESPONSE_ERR
=
0x04
;
int
CONNECTION_FAIL
=
0x08
;
int
RESPONSE_ERR
=
0x01
;
int
CONNECTION_FAIL
=
0x02
;
int
BASIC_PASS
=
0x10
;
int
CTS_PASS
=
0x20
;
...
...
app/src/full/res/layout/fragment_magisk.xml
View file @
d2c19689
...
...
@@ -154,6 +154,7 @@
android:layout_marginEnd=
"5dp"
android:layout_marginStart=
"5dp"
android:layout_marginTop=
"4dp"
android:visibility=
"gone"
app:cardCornerRadius=
"@dimen/card_corner_radius"
app:cardElevation=
"@dimen/card_elevation"
>
...
...
build.gradle
View file @
d2c19689
...
...
@@ -25,7 +25,7 @@ allprojects {
ext
{
compileSdkVersion
=
28
buildToolsVersion
=
"28.0.
0
"
buildToolsVersion
=
"28.0.
2
"
supportLibVersion
=
"27.1.1"
}
...
...
snet/build.gradle
View file @
d2c19689
...
...
@@ -8,23 +8,20 @@ android {
applicationId
"com.topjohnwu.snet"
minSdkVersion
14
targetSdkVersion
rootProject
.
ext
.
compileSdkVersion
versionCode
1
versionName
"
1.0
"
versionCode
1
1
versionName
"
snet
"
}
buildTypes
{
release
{
minifyEnabled
true
shrinkResources
true
proguardFiles
getDefaultProguardFile
(
'proguard-android.txt'
),
'proguard-rules.pro'
proguardFiles
getDefaultProguardFile
(
'proguard-android
-optimize
.txt'
),
'proguard-rules.pro'
}
}
}
dependencies
{
implementation
fileTree
(
dir:
'libs'
,
include:
[
'*.jar'
])
/* The oldest version */
implementation
(
'com.google.android.gms:play-services-safetynet:7.0.0'
)
{
exclude
module:
'support-v4'
}
implementation
'com.google.android.gms:play-services-safetynet:15.0.1'
}
snet/proguard-rules.pro
View file @
d2c19689
...
...
@@ -20,7 +20,4 @@
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-
ignorewarnings
-
keep
class
com
.
topjohnwu
.
snet
.
Snet
{
*
;
}
-
dontwarn
java
.
lang
.
invoke
**
-
dontwarn
com
.
google
.
android
.
gms
.
common
.
GooglePlayServicesUtil
**
snet/src/main/java/com/topjohnwu/snet/ModdedGPSUtil.java
deleted
100644 → 0
View file @
e42b6084
package
com
.
topjohnwu
.
snet
;
import
android.app.Activity
;
import
android.app.AlertDialog
;
import
android.app.Dialog
;
import
android.content.Context
;
import
android.content.ContextWrapper
;
import
android.content.DialogInterface
;
import
android.content.Intent
;
import
android.content.pm.PackageManager
;
import
android.content.res.AssetManager
;
import
android.content.res.Resources
;
import
android.util.Log
;
import
com.google.android.gms.common.GooglePlayServicesUtil
;
import
com.google.android.gms.internal.zzlu
;
/* Decompiled and modified from GooglePlayServiceUtil.class */
public
class
ModdedGPSUtil
{
private
static
final
String
TAG
=
"GooglePlayServicesUtil"
;
static
String
dexPath
;
static
Dialog
getErrorDialog
(
int
errCode
,
final
Activity
activity
,
final
int
requestCode
)
{
SwapResContext
ctx
=
new
SwapResContext
(
activity
,
dexPath
);
Resources
res
=
ctx
.
getResources
();
if
(
zzlu
.
zzQ
(
ctx
)
&&
errCode
==
2
)
{
errCode
=
42
;
}
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
activity
);
builder
.
setMessage
(
GooglePlayServicesUtil
.
zze
(
ctx
,
errCode
));
String
btnMsg
=
GooglePlayServicesUtil
.
zzf
(
ctx
,
errCode
);
if
(
btnMsg
!=
null
)
{
final
Intent
intent
=
GooglePlayServicesUtil
.
zzan
(
errCode
);
builder
.
setPositiveButton
(
btnMsg
,
new
DialogInterface
.
OnClickListener
()
{
@Override
public
void
onClick
(
DialogInterface
dialog
,
int
i
)
{
PackageManager
pm
=
activity
.
getPackageManager
();
if
(
intent
!=
null
&&
intent
.
resolveActivity
(
pm
)
!=
null
)
activity
.
startActivityForResult
(
intent
,
requestCode
);
dialog
.
dismiss
();
}
});
}
switch
(
errCode
)
{
case
0
:
return
null
;
case
1
:
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_google_play_services_install_title
)).
create
();
case
2
:
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_google_play_services_update_title
)).
create
();
case
3
:
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_google_play_services_enable_title
)).
create
();
case
4
:
case
6
:
return
builder
.
create
();
case
5
:
Log
.
e
(
TAG
,
"An invalid account was specified when connecting. Please provide a valid account."
);
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_google_play_services_invalid_account_title
)).
create
();
case
7
:
Log
.
e
(
TAG
,
"Network error occurred. Please retry request later."
);
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_google_play_services_network_error_title
)).
create
();
case
8
:
Log
.
e
(
TAG
,
"Internal error occurred. Please see logs for detailed information"
);
return
builder
.
create
();
case
9
:
Log
.
e
(
TAG
,
"Google Play services is invalid. Cannot recover."
);
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_google_play_services_unsupported_title
)).
create
();
case
10
:
Log
.
e
(
TAG
,
"Developer error occurred. Please see logs for detailed information"
);
return
builder
.
create
();
case
11
:
Log
.
e
(
TAG
,
"The application is not licensed to the user."
);
return
builder
.
create
();
case
12
:
case
13
:
case
14
:
case
15
:
case
18
:
case
19
:
case
20
:
case
21
:
case
22
:
case
23
:
case
24
:
case
25
:
case
26
:
case
27
:
case
28
:
case
29
:
case
30
:
case
31
:
case
32
:
case
33
:
case
34
:
case
35
:
case
36
:
case
37
:
case
38
:
case
39
:
case
40
:
case
41
:
default
:
Log
.
e
(
TAG
,
"Unexpected error code "
+
errCode
);
return
builder
.
create
();
case
16
:
Log
.
e
(
TAG
,
"One of the API components you attempted to connect to is not available."
);
return
builder
.
create
();
case
17
:
Log
.
e
(
TAG
,
"The specified account could not be signed in."
);
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_google_play_services_sign_in_failed_title
)).
create
();
case
42
:
return
builder
.
setTitle
(
res
.
getString
(
com
.
google
.
android
.
gms
.
R
.
string
.
common_android_wear_update_title
)).
create
();
}
}
public
static
class
SwapResContext
extends
ContextWrapper
{
private
AssetManager
asset
;
private
Resources
resources
;
public
SwapResContext
(
Context
base
,
String
apk
)
{
super
(
base
);
try
{
asset
=
AssetManager
.
class
.
newInstance
();
AssetManager
.
class
.
getMethod
(
"addAssetPath"
,
String
.
class
).
invoke
(
asset
,
apk
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
Resources
res
=
base
.
getResources
();
resources
=
new
Resources
(
asset
,
res
.
getDisplayMetrics
(),
res
.
getConfiguration
());
}
@Override
public
Resources
getResources
()
{
return
resources
;
}
@Override
public
AssetManager
getAssets
()
{
return
asset
;
}
}
}
snet/src/main/java/com/topjohnwu/snet/SafetyNetHelper.java
View file @
d2c19689
package
com
.
topjohnwu
.
snet
;
import
android.app.Activity
;
import
android.os.Bundle
;
import
android.app.AlertDialog
;
import
android.app.Dialog
;
import
android.content.Context
;
import
android.content.Intent
;
import
android.support.annotation.NonNull
;
import
android.util.Base64
;
import
android.util.Log
;
import
com.google.android.gms.common.ConnectionResult
;
import
com.google.android.gms.common.GooglePlayServicesUtil
;
import
com.google.android.gms.common.api.GoogleApiClient
;
import
com.google.android.gms.common.api.ResultCallback
;
import
com.google.android.gms.common.GoogleApiAvailability
;
import
com.google.android.gms.common.api.ApiException
;
import
com.google.android.gms.common.internal.ConnectionErrorMessages
;
import
com.google.android.gms.common.internal.DialogRedirect
;
import
com.google.android.gms.safetynet.SafetyNet
;
import
com.google.android.gms.safetynet.SafetyNetApi
;
import
com.google.android.gms.safetynet.SafetyNetClient
;
import
com.google.android.gms.tasks.OnFailureListener
;
import
com.google.android.gms.tasks.OnSuccessListener
;
import
org.json.JSONException
;
import
org.json.JSONObject
;
...
...
@@ -18,89 +27,80 @@ import java.lang.reflect.InvocationHandler;
import
java.lang.reflect.Method
;
import
java.security.SecureRandom
;
public
class
SafetyNetHelper
implements
InvocationHandler
,
GoogleApiClient
.
ConnectionCallbacks
,
GoogleApiClient
.
OnConnectionFailedListener
,
ResultCallback
<
SafetyNetApi
.
AttestationResult
>
{
public
class
SafetyNetHelper
implements
InvocationHandler
,
OnSuccessListener
<
SafetyNetApi
.
AttestationResponse
>,
OnFailureListener
{
p
ublic
static
final
int
CAUSE_SERVICE_DISCONNECTED
=
0x01
;
p
ublic
static
final
int
CAUSE_NETWORK_LOST
=
0x02
;
p
ublic
static
final
int
RESPONSE_ERR
=
0x04
;
p
ublic
static
final
int
CONNECTION_FAIL
=
0x08
;
p
rivate
static
final
int
RESPONSE_ERR
=
0x01
;
p
rivate
static
final
int
CONNECTION_FAIL
=
0x02
;
p
rivate
static
final
int
BASIC_PASS
=
0x10
;
p
rivate
static
final
int
CTS_PASS
=
0x20
;
public
static
final
int
BASIC_PASS
=
0x10
;
public
static
final
int
CTS_PASS
=
0x20
;
private
static
final
GoogleApiAvailability
API_AVAIL
=
GoogleApiAvailability
.
getInstance
();
private
static
final
SecureRandom
RANDOM
=
new
SecureRandom
();
private
static
final
String
TAG
=
"SNET"
;
public
static
final
int
SNET_EXT_VER
=
10
;
/* Insert the magic API key here :) */
private
static
final
String
API_KEY
=
""
;
private
GoogleApiClient
mGoogleApiClient
;
private
Activity
mActivity
;
private
Object
callback
;
private
final
Activity
mActivity
;
private
final
Object
callback
;
SafetyNetHelper
(
Activity
activity
,
Object
cb
)
{
mActivity
=
activity
;
callback
=
cb
;
}
private
void
invokeCallback
(
int
code
)
{
Class
<?>
clazz
=
callback
.
getClass
();
try
{
clazz
.
getMethod
(
"onResponse"
,
int
.
class
).
invoke
(
callback
,
code
);
}
catch
(
Exception
ignored
)
{}
}
/* Override ISafetyNetHelper.getVersion */
private
int
getVersion
()
{
return
SNET_EXT_VER
;
return
BuildConfig
.
VERSION_CODE
;
}
/* Override ISafetyNetHelper.attest */
private
void
attest
()
{
// Connect Google Service
mGoogleApiClient
=
new
GoogleApiClient
.
Builder
(
mActivity
)
.
addApi
(
SafetyNet
.
API
)
.
addOnConnectionFailedListener
(
this
)
.
addConnectionCallbacks
(
this
)
.
build
();
mGoogleApiClient
.
connect
();
}
@Override
public
Object
invoke
(
Object
o
,
Method
method
,
Object
[]
args
)
{
if
(
method
.
getName
().
equals
(
"attest"
))
{
attest
();
}
else
if
(
method
.
getName
().
equals
(
"getVersion"
))
{
return
getVersion
();
int
code
=
API_AVAIL
.
isGooglePlayServicesAvailable
(
mActivity
);
if
(
code
!=
ConnectionResult
.
SUCCESS
)
{
if
(
API_AVAIL
.
isUserResolvableError
(
code
))
getErrorDialog
(
code
,
0
).
show
();
invokeCallback
(
CONNECTION_FAIL
);
return
;
}
return
null
;
}
// Create nonce
byte
[]
nonce
=
new
byte
[
24
];
RANDOM
.
nextBytes
(
nonce
);
private
void
invokeCallback
(
int
code
)
{
Class
<?>
clazz
=
callback
.
getClass
();
try
{
clazz
.
getMethod
(
"onResponse"
,
int
.
class
).
invoke
(
callback
,
code
);
}
catch
(
Exception
ignored
)
{}
SafetyNetClient
client
=
SafetyNet
.
getClient
(
mActivity
.
getBaseContext
());
client
.
attest
(
nonce
,
API_KEY
).
addOnSuccessListener
(
this
).
addOnFailureListener
(
this
);
}
@Override
public
void
onConnectionSuspended
(
int
i
)
{
invokeCallback
(
i
);
}
private
Dialog
getErrorDialog
(
int
errorCode
,
int
requestCode
)
{
AlertDialog
.
Builder
builder
=
new
AlertDialog
.
Builder
(
mActivity
);
Context
swapCtx
=
new
SwapResContext
(
mActivity
,
Snet
.
dexPath
);
Intent
intent
=
API_AVAIL
.
getErrorResolutionIntent
(
swapCtx
,
errorCode
,
"d"
);
@Override
public
void
onConnectionFailed
(
ConnectionResult
result
)
{
if
(
GooglePlayServicesUtil
.
isUserRecoverableError
(
result
.
getErrorCode
()))
ModdedGPSUtil
.
getErrorDialog
(
result
.
getErrorCode
(),
mActivity
,
0
).
show
();
invokeCallback
(
CONNECTION_FAIL
);
}
builder
.
setMessage
(
ConnectionErrorMessages
.
getErrorMessage
(
swapCtx
,
errorCode
));
builder
.
setPositiveButton
(
ConnectionErrorMessages
.
getErrorDialogButtonMessage
(
swapCtx
,
errorCode
),
DialogRedirect
.
getInstance
(
mActivity
,
intent
,
requestCode
));
@Override
public
void
onConnected
(
Bundle
bundle
)
{
// Create nonce
byte
[]
nonce
=
new
byte
[
24
];
new
SecureRandom
().
nextBytes
(
nonce
);
String
title
;
if
((
title
=
ConnectionErrorMessages
.
getErrorTitle
(
swapCtx
,
errorCode
))
!=
null
)
{
builder
.
setTitle
(
title
);
}
// Call SafetyNet
SafetyNet
.
SafetyNetApi
.
attest
(
mGoogleApiClient
,
nonce
).
setResultCallback
(
this
);
return
builder
.
create
();
}
@Override
public
void
on
Result
(
SafetyNetApi
.
AttestationResult
result
)
{
public
void
on
Success
(
SafetyNetApi
.
AttestationResponse
result
)
{
int
code
=
0
;
try
{
if
(!
result
.
getStatus
().
isSuccess
())
throw
new
JSONException
(
""
);
String
jsonStr
=
new
String
(
Base64
.
decode
(
result
.
getJwsResult
().
split
(
"\\."
)[
1
],
Base64
.
DEFAULT
));
JSONObject
json
=
new
JSONObject
(
jsonStr
);
...
...
@@ -110,10 +110,34 @@ public class SafetyNetHelper implements InvocationHandler, GoogleApiClient.Conne
code
=
RESPONSE_ERR
;
}
// Disconnect
mGoogleApiClient
.
disconnect
();
// Return results
invokeCallback
(
code
);
}
@Override
public
void
onFailure
(
@NonNull
Exception
e
)
{
if
(
e
instanceof
ApiException
)
{
int
errCode
=
((
ApiException
)
e
).
getStatusCode
();
if
(
API_AVAIL
.
isUserResolvableError
(
errCode
))
getErrorDialog
(
errCode
,
0
).
show
();
else
Log
.
e
(
TAG
,
"Cannot resolve: "
+
e
.
getMessage
());
}
else
{
Log
.
e
(
TAG
,
"Unknown: "
+
e
.
getMessage
());
}
invokeCallback
(
CONNECTION_FAIL
);
}
@Override
public
Object
invoke
(
Object
proxy
,
Method
method
,
Object
[]
args
)
{
switch
(
method
.
getName
())
{
case
"attest"
:
attest
();
return
null
;
case
"getVersion"
:
return
getVersion
();
default
:
return
null
;
}
}
}
snet/src/main/java/com/topjohnwu/snet/Snet.java
View file @
d2c19689
...
...
@@ -5,9 +5,11 @@ import android.app.Activity;
import
java.lang.reflect.Proxy
;
public
class
Snet
{
public
static
Object
newHelper
(
Class
<?>
clazz
,
String
dexPath
,
Activity
activity
,
Object
cb
)
{
ModdedGPSUtil
.
dexPath
=
dexPath
;
static
String
dexPath
;
public
static
Object
newHelper
(
Class
<?>
interfaceClass
,
String
dexPath
,
Activity
activity
,
Object
cb
)
{
Snet
.
dexPath
=
dexPath
;
return
Proxy
.
newProxyInstance
(
SafetyNetHelper
.
class
.
getClassLoader
(),
new
Class
[]
{
clazz
},
new
SafetyNetHelper
(
activity
,
cb
));
new
Class
[]
{
interfaceClass
},
new
SafetyNetHelper
(
activity
,
cb
));
}
}
snet/src/main/java/com/topjohnwu/snet/SwapResContext.java
0 → 100644
View file @
d2c19689
package
com
.
topjohnwu
.
snet
;
import
android.content.Context
;
import
android.content.ContextWrapper
;
import
android.content.res.AssetManager
;
import
android.content.res.Resources
;
public
class
SwapResContext
extends
ContextWrapper
{
private
AssetManager
asset
;
private
Resources
resources
;
public
SwapResContext
(
Context
base
,
String
apk
)
{
super
(
base
);
try
{
asset
=
AssetManager
.
class
.
newInstance
();
AssetManager
.
class
.
getMethod
(
"addAssetPath"
,
String
.
class
).
invoke
(
asset
,
apk
);
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
Resources
res
=
base
.
getResources
();
resources
=
new
Resources
(
asset
,
res
.
getDisplayMetrics
(),
res
.
getConfiguration
());
}
@Override
public
Resources
getResources
()
{
return
resources
;
}
@Override
public
AssetManager
getAssets
()
{
return
asset
;
}
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment