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
4bbd7989
Commit
4bbd7989
authored
Jun 30, 2020
by
topjohnwu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update snet extension
Receive full snet payload from extension
parent
a0b47f3c
Show whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
87 additions
and
71 deletions
+87
-71
Const.kt
app/src/main/java/com/topjohnwu/magisk/core/Const.kt
+2
-2
SafetyNetHelper.kt
...n/java/com/topjohnwu/magisk/core/utils/SafetyNetHelper.kt
+3
-10
RxEvents.kt
...c/main/java/com/topjohnwu/magisk/model/events/RxEvents.kt
+5
-1
ViewEvents.kt
...main/java/com/topjohnwu/magisk/model/events/ViewEvents.kt
+30
-27
SafetynetViewModel.kt
...a/com/topjohnwu/magisk/ui/safetynet/SafetynetViewModel.kt
+31
-31
build.py
build.py
+16
-0
No files found.
app/src/main/java/com/topjohnwu/magisk/core/Const.kt
View file @
4bbd7989
...
...
@@ -12,8 +12,8 @@ object Const {
const
val
MAGISK_LOG
=
"/cache/magisk.log"
// Versions
const
val
SNET_EXT_VER
=
1
3
const
val
SNET_REVISION
=
"
a6c47f86f10b310358afa9dbe837037dd5d561df
"
const
val
SNET_EXT_VER
=
1
4
const
val
SNET_REVISION
=
"
5e28617412bdad2396eab87fa786094d8242e568
"
const
val
BOOTCTL_REVISION
=
"a6c47f86f10b310358afa9dbe837037dd5d561df"
// Misc
...
...
app/src/main/java/com/topjohnwu/magisk/core/utils/SafetyNetHelper.kt
View file @
4bbd7989
package
com.topjohnwu.magisk.core.utils
import
org.json.JSONObject
interface
SafetyNetHelper
{
val
version
:
Int
...
...
@@ -7,15 +9,6 @@ interface SafetyNetHelper {
fun
attest
()
interface
Callback
{
fun
onResponse
(
responseCode
:
Int
)
}
companion
object
{
const
val
RESPONSE_ERR
=
0
x01
const
val
CONNECTION_FAIL
=
0
x02
const
val
BASIC_PASS
=
0
x10
const
val
CTS_PASS
=
0
x20
fun
onResponse
(
response
:
JSONObject
?)
}
}
app/src/main/java/com/topjohnwu/magisk/model/events/RxEvents.kt
View file @
4bbd7989
...
...
@@ -2,10 +2,14 @@ package com.topjohnwu.magisk.model.events
import
com.topjohnwu.magisk.core.model.MagiskPolicy
import
com.topjohnwu.magisk.utils.RxBus
import
org.json.JSONObject
sealed
class
PolicyUpdateEvent
(
val
item
:
MagiskPolicy
)
:
RxBus
.
Event
{
class
Notification
(
item
:
MagiskPolicy
)
:
PolicyUpdateEvent
(
item
)
class
Log
(
item
:
MagiskPolicy
)
:
PolicyUpdateEvent
(
item
)
}
data class
SafetyNetResult
(
val
responseCode
:
Int
)
:
RxBus
.
Event
data class
SafetyNetResult
(
val
response
:
JSONObject
?
=
null
,
val
dismiss
:
Boolean
=
false
)
:
RxBus
.
Event
app/src/main/java/com/topjohnwu/magisk/model/events/ViewEvents.kt
View file @
4bbd7989
...
...
@@ -10,6 +10,7 @@ import com.topjohnwu.magisk.core.model.module.Repo
import
com.topjohnwu.magisk.core.utils.SafetyNetHelper
import
com.topjohnwu.magisk.data.repository.MagiskRepository
import
com.topjohnwu.magisk.extensions.DynamicClassLoader
import
com.topjohnwu.magisk.extensions.OnErrorListener
import
com.topjohnwu.magisk.extensions.subscribeK
import
com.topjohnwu.magisk.extensions.writeTo
import
com.topjohnwu.magisk.utils.RxBus
...
...
@@ -19,8 +20,10 @@ import com.topjohnwu.superuser.Shell
import
dalvik.system.DexFile
import
io.reactivex.Completable
import
io.reactivex.subjects.PublishSubject
import
org.json.JSONObject
import
org.koin.core.KoinComponent
import
org.koin.core.inject
import
timber.log.Timber
import
java.io.File
import
java.lang.reflect.InvocationHandler
...
...
@@ -40,18 +43,25 @@ class UpdateSafetyNetEvent : ViewEvent(), ContextExecutor, KoinComponent, Safety
private
val
magiskRepo
by
inject
<
MagiskRepository
>()
private
val
rxBus
by
inject
<
RxBus
>()
private
lateinit
var
EXT_APK
:
File
private
lateinit
var
EXT_DEX
:
File
private
lateinit
var
apk
:
File
private
lateinit
var
dex
:
File
override
fun
invoke
(
context
:
Context
)
{
val
die
=
::
EXT_APK
.
isInitialized
apk
=
File
(
"${context.filesDir.parent}/snet"
,
"snet.jar"
)
dex
=
File
(
apk
.
parent
,
"snet.dex"
)
EXT_APK
=
File
(
"${context.filesDir.parent}/snet"
,
"snet.jar"
)
EXT_DEX
=
File
(
EXT_APK
.
parent
,
"snet.dex"
)
attest
(
context
)
{
// Download and retry
Shell
.
sh
(
"rm -rf "
+
apk
.
parent
).
exec
()
apk
.
parentFile
?.
mkdir
()
download
(
context
,
true
)
}
}
private
fun
attest
(
context
:
Context
,
onError
:
OnErrorListener
)
{
Completable
.
fromAction
{
val
loader
=
DynamicClassLoader
(
EXT_APK
)
val
dex
=
DexFile
.
loadDex
(
EXT_APK
.
path
,
EXT_DEX
.
path
,
0
)
val
loader
=
DynamicClassLoader
(
apk
)
val
dex
=
DexFile
.
loadDex
(
apk
.
path
,
dex
.
path
,
0
)
// Scan through the dex and find our helper class
var
helperClass
:
Class
<*>?
=
null
...
...
@@ -66,32 +76,25 @@ class UpdateSafetyNetEvent : ViewEvent(), ContextExecutor, KoinComponent, Safety
}
helperClass
?:
throw
Exception
()
val
helper
=
helperClass
.
getMethod
(
"get"
,
Class
::
class
.
java
,
Context
::
class
.
java
,
Any
::
class
.
java
)
val
helper
=
helperClass
.
getMethod
(
"get"
,
Class
::
class
.
java
,
Context
::
class
.
java
,
Any
::
class
.
java
)
.
invoke
(
null
,
SafetyNetHelper
::
class
.
java
,
context
,
this
)
as
SafetyNetHelper
if
(
helper
.
version
<
Const
.
SNET_EXT_VER
)
throw
Exception
()
helper
.
attest
()
}.
subscribeK
(
onError
=
{
if
(
die
)
{
rxBus
.
post
(
SafetyNetResult
(-
1
))
}
else
{
Shell
.
sh
(
"rm -rf "
+
EXT_APK
.
parent
).
exec
()
EXT_APK
.
parentFile
?.
mkdir
()
download
(
context
,
true
)
}
})
}.
subscribeK
(
onError
=
onError
)
}
@Suppress
(
"SameParameterValue"
)
private
fun
download
(
context
:
Context
,
askUser
:
Boolean
)
{
fun
downloadInternal
()
=
magiskRepo
.
fetchSafetynet
()
.
map
{
it
.
byteStream
().
writeTo
(
EXT_APK
)
}
.
subscribeK
{
invoke
(
context
)
}
.
map
{
it
.
byteStream
().
writeTo
(
apk
)
}
.
subscribeK
{
attest
(
context
)
{
Timber
.
e
(
it
)
rxBus
.
post
(
SafetyNetResult
())
}
}
if
(!
askUser
)
{
downloadInternal
()
...
...
@@ -107,14 +110,14 @@ class UpdateSafetyNetEvent : ViewEvent(), ContextExecutor, KoinComponent, Safety
onClick
{
downloadInternal
()
}
}
.
applyButton
(
MagiskDialog
.
ButtonType
.
NEGATIVE
)
{
titleRes
=
android
.
R
.
string
.
no
onClick
{
rxBus
.
post
(
SafetyNetResult
(
-
2
))
}
titleRes
=
android
.
R
.
string
.
cancel
onClick
{
rxBus
.
post
(
SafetyNetResult
(
dismiss
=
true
))
}
}
.
reveal
()
}
override
fun
onResponse
(
response
Code
:
Int
)
{
rxBus
.
post
(
SafetyNetResult
(
response
Code
))
override
fun
onResponse
(
response
:
JSONObject
?
)
{
rxBus
.
post
(
SafetyNetResult
(
response
))
}
}
...
...
app/src/main/java/com/topjohnwu/magisk/ui/safetynet/SafetynetViewModel.kt
View file @
4bbd7989
...
...
@@ -3,7 +3,6 @@ package com.topjohnwu.magisk.ui.safetynet
import
androidx.databinding.Bindable
import
com.topjohnwu.magisk.BR
import
com.topjohnwu.magisk.R
import
com.topjohnwu.magisk.core.utils.SafetyNetHelper
import
com.topjohnwu.magisk.extensions.subscribeK
import
com.topjohnwu.magisk.model.events.SafetyNetResult
import
com.topjohnwu.magisk.model.events.UpdateSafetyNetEvent
...
...
@@ -11,6 +10,7 @@ import com.topjohnwu.magisk.ui.base.BaseViewModel
import
com.topjohnwu.magisk.ui.safetynet.SafetyNetState.*
import
com.topjohnwu.magisk.utils.KObservableField
import
com.topjohnwu.magisk.utils.RxBus
import
org.json.JSONObject
enum
class
SafetyNetState
{
LOADING
,
PASS
,
FAILED
,
IDLE
...
...
@@ -35,14 +35,12 @@ class SafetynetViewModel(
init
{
rxBus
.
register
<
SafetyNetResult
>()
.
subscribeK
{
resolveResponse
(
it
.
responseCode
)
}
.
subscribeK
{
resolveResponse
(
it
)
}
.
add
()
if
(
safetyNetResult
>=
0
)
{
resolveResponse
(
safetyNetResult
)
}
else
{
attest
()
}
cachedResult
?.
also
{
resolveResponse
(
SafetyNetResult
(
it
))
}
?:
attest
()
}
override
fun
notifyStateChanged
()
{
...
...
@@ -59,38 +57,40 @@ class SafetynetViewModel(
fun
reset
()
=
attest
()
private
fun
resolveResponse
(
response
:
Int
)
=
when
{
response
and
0
x0F
==
0
->
{
val
hasCtsPassed
=
response
and
SafetyNetHelper
.
CTS_PASS
!=
0
val
hasBasicIntegrityPassed
=
response
and
SafetyNetHelper
.
BASIC_PASS
!=
0
val
result
=
hasCtsPassed
&&
hasBasicIntegrityPassed
safetyNetResult
=
response
ctsState
.
value
=
hasCtsPassed
basicIntegrityState
.
value
=
hasBasicIntegrityPassed
private
fun
resolveResponse
(
response
:
SafetyNetResult
)
{
if
(
response
.
dismiss
)
{
back
()
return
}
response
.
response
?.
apply
{
runCatching
{
val
cts
=
getBoolean
(
"ctsProfileMatch"
)
val
basic
=
getBoolean
(
"basicIntegrity"
)
val
result
=
cts
&&
basic
cachedResult
=
this
ctsState
.
value
=
cts
basicIntegrityState
.
value
=
basic
currentState
=
if
(
result
)
PASS
else
FAILED
safetyNetTitle
.
value
=
if
(
result
)
R
.
string
.
safetynet_attest_success
else
R
.
string
.
safetynet_attest_failure
}
response
==
-
2
->
{
}.
onFailure
{
currentState
=
FAILED
ctsState
.
value
=
false
basicIntegrityState
.
value
=
false
back
()
safetyNetTitle
.
value
=
R
.
string
.
safetynet_res_invalid
}
else
->
{
}
?:
{
currentState
=
FAILED
ctsState
.
value
=
false
basicIntegrityState
.
value
=
false
safetyNetTitle
.
value
=
when
(
response
)
{
SafetyNetHelper
.
RESPONSE_ERR
->
R
.
string
.
safetynet_res_invalid
else
->
R
.
string
.
safetynet_api_error
}
}
safetyNetTitle
.
value
=
R
.
string
.
safetynet_api_error
}()
}
companion
object
{
private
var
safetyNetResult
=
-
1
private
var
cachedResult
:
JSONObject
?
=
null
}
}
build.py
View file @
4bbd7989
...
...
@@ -398,6 +398,22 @@ def build_stub(args):
header
(
'* Building Magisk Manager stub'
)
build_apk
(
args
,
'stub'
)
# Bind mount snet package on top of the stub folder
def
build_snet
(
args
):
header
(
'* Building snet extension'
)
proc
=
execv
([
gradlew
,
'stub:assembleRelease'
])
if
proc
.
returncode
!=
0
:
error
(
'Build snet extention failed!'
)
source
=
op
.
join
(
'stub'
,
'build'
,
'outputs'
,
'apk'
,
'release'
,
'stub-release.apk'
)
target
=
op
.
join
(
config
[
'outdir'
],
'snet.jar'
)
# Extract classes.dex
with
zipfile
.
ZipFile
(
target
,
'w'
,
compression
=
zipfile
.
ZIP_DEFLATED
,
allowZip64
=
False
)
as
zout
:
with
zipfile
.
ZipFile
(
source
)
as
zin
:
zout
.
writestr
(
'classes.dex'
,
zin
.
read
(
'classes.dex'
))
rm
(
source
)
header
(
'Output: '
+
target
)
def
zip_main
(
args
):
header
(
'* Packing Flashable Zip'
)
...
...
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