Permalink
Comparing changes
Choose two branches to see what’s changed or to start a new pull request.
If you need to, you can also or
learn more about diff comparisons.
Open a pull request
Create a new pull request by comparing changes across two branches. If you need to, you can also .
Learn more about diff comparisons here.
...
- 9 commits
- 8 files changed
- 1 contributor
Commits on Sep 6, 2021
Commits on Sep 14, 2021
Showing
with
80 additions
and 14 deletions.
- +12 −5 README.md
- +1 −6 java_module/.gitignore
- +13 −0 java_module/app/src/main/java/dev/kdrag0n/safetynetriru/BuildHooks.kt
- +2 −1 java_module/app/src/main/java/dev/kdrag0n/safetynetriru/EntryPoint.kt
- +2 −2 riru/module.gradle
- +3 −0 riru/template/magisk_module/customize.sh
- +28 −0 riru/template/magisk_module/service.sh
- +19 −0 riru/template/magisk_module/system.prop
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -4,20 +4,27 @@ This is a universal fix for SafetyNet on devices with hardware-backed attestatio | ||
|
|
||
| Passing basic attestation is out-of-scope for this module; this module is meant to defy hardware attestation, as well as reported "basic" attestation that actually uses hardware under-the-hood. Use [MagiskHide Props Config](https://github.com/Magisk-Modules-Repo/MagiskHidePropsConf) to spoof your CTS profile if you have trouble passing basic attestation. This is a common issue on old devices and custom ROMs. | ||
|
|
||
| Android versions 7–12 are supported, including OEM skins such as Samsung One UI and MIUI. This is a Riru module, so Riru must be installed in order for this to work. | ||
| Android versions 7–12 are supported, including OEM skins such as Samsung One UI and MIUI. **This is a Riru module, so Riru must be installed in order for it to work.** | ||
|
|
||
| ## Installation | ||
|
|
||
| Download and install the latest release from [GitHub Releases](https://github.com/kdrag0n/safetynet-fix/releases). The module must be installed using Magisk Manager, not TWRP or any other custom recovery. | ||
|
|
||
| Always make sure you have the **latest version of the module** installed before reporting any issues. | ||
|
|
||
| ## How does it work? | ||
|
|
||
| Google Play Services opportunistically uses hardware-backed attestation to enforce SafetyNet security (since January 12, 2021), regardless of the device. | ||
| Google Play Services opportunistically uses hardware-backed attestation to enforce SafetyNet security (since January 12, 2021), and enforces its usage based on the device model name (since September 2, 2021). | ||
|
|
||
| This module uses Riru to inject code into the Google Play Services process and then register a fake keystore provider that overrides the real one. When Play Services attempts to use key attestation, it throws an exception and pretends that the device lacks support for key attestation. This causes SafetyNet to fall back to basic attestation, which is much weaker and can be bypassed with existing methods. | ||
|
|
||
| Key attestation is only blocked specifically for SafetyNet in Google Play Services, | ||
| so no other features are broken. | ||
| However, blocking key attestation alone does not suffice because basic attestation fails on devices that are known by Google to support hardware-backed attestation. This module bypasses the check by appending a space character to the device model name. This has minimal impact on UX when only applied to Google Play Services, but it's sufficient for bypassing enforcement of hardware-backed attestation. | ||
|
|
||
| Unlike many other approaches, this doesn't break other features because key attestation is only blocked for Google Play Services, and even within Play Services, it is only blocked for SafetyNet code. As a result, other attestation-based features (such as using the device as a security key) will still work. | ||
|
|
||
| ## ROM integration | ||
|
|
||
| Ideally, this workaround should be incorporated in custom ROMs instead of injecting code with a Magisk module. | ||
| Ideally, this workaround should be incorporated in custom ROMs instead of injecting code with a Magisk module. **Please note that the following patches have not been updated for the new September 2 changes yet.** | ||
|
|
||
| Commits for the system framework version of the workaround: | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,12 +1,7 @@ | ||
| *.iml | ||
| .gradle | ||
| /local.properties | ||
| /.idea/caches | ||
| /.idea/libraries | ||
| /.idea/modules.xml | ||
| /.idea/workspace.xml | ||
| /.idea/navEditor.xml | ||
| /.idea/assetWizardSettings.xml | ||
| /.idea | ||
| .DS_Store | ||
| /build | ||
| /captures | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| package dev.kdrag0n.safetynetriru | ||
|
|
||
| import android.os.Build | ||
|
|
||
| internal object BuildHooks { | ||
| fun init() { | ||
| // Append a space to the device model name | ||
| Build::class.java.getDeclaredField("MODEL").let { field -> | ||
| field.isAccessible = true | ||
| field.set(null, Build.MODEL + " ") | ||
| } | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -5,8 +5,9 @@ object EntryPoint { | ||
| @JvmStatic | ||
| fun init() { | ||
| runCatching { | ||
| logDebug("Entry point: Initializing SafetyNet patch") | ||
| logDebug("Entry point: Initializing SafetyNet patches") | ||
| SecurityBridge.init() | ||
| BuildHooks.init() | ||
| }.recoverCatching { e -> | ||
| // Throwing an exception would require the JNI code to handle exceptions, so just catch | ||
| // everything here. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -25,6 +25,6 @@ ext { | ||
| moduleName = "Universal SafetyNet Fix" | ||
| moduleAuthor = "kdrag0n" | ||
| moduleDescription = "A universal fix for SafetyNet on Android 7–12 devices with hardware attestation and unlocked bootloaders. Requires MagiskHide and Riru $moduleMinRiruVersionName or newer." | ||
| moduleVersion = "v2.0.0" | ||
| moduleVersionCode = 20000 | ||
| moduleVersion = "v2.1.0" | ||
| moduleVersionCode = 20100 | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -37,7 +37,10 @@ fi | ||
| ui_print "- Extracting module files" | ||
|
|
||
| extract "$ZIPFILE" 'module.prop' "$MODPATH" | ||
| extract "$ZIPFILE" 'system.prop' "$MODPATH" | ||
| extract "$ZIPFILE" 'classes.dex' "$MODPATH" | ||
| extract "$ZIPFILE" 'service.sh' "$MODPATH" | ||
| chmod 755 "$MODPATH/service.sh" | ||
|
|
||
| # Riru v24+ load files from the "riru" folder in the Magisk module folder | ||
| # This "riru" folder is also used to determine if a Magisk module is a Riru module | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| #!/system/bin/sh | ||
|
|
||
| maybe_set_prop() { | ||
| local prop="$1" | ||
| local contains="$2" | ||
| local value="$3" | ||
|
|
||
| if [[ "$(getprop "$prop")" == *"$contains"* ]]; then | ||
| resetprop "$prop" "$value" | ||
| fi | ||
| } | ||
|
|
||
| # Magisk recovery mode | ||
| maybe_set_prop ro.bootmode recovery unknown | ||
| maybe_set_prop ro.boot.mode recovery unknown | ||
| maybe_set_prop vendor.boot.mode recovery unknown | ||
|
|
||
| # MIUI region | ||
| maybe_set_prop ro.boot.hwc CN GLOBAL | ||
| maybe_set_prop ro.boot.hwcountry China GLOBAL | ||
|
|
||
| resetprop --delete ro.build.selinux | ||
|
|
||
| # SELinux permissive | ||
| if [[ "$(cat /sys/fs/selinux/enforce)" == "0" ]]; then | ||
| chmod 640 /sys/fs/selinux/enforce | ||
| chmod 440 /sys/fs/selinux/policy | ||
| fi |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Show hidden characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| # RootBeer, Microsoft | ||
| ro.build.tags=release-keys | ||
|
|
||
| # SafetyNet | ||
| ro.boot.flash.locked=1 | ||
| ro.boot.verifiedbootstate=green | ||
| ro.boot.veritymode=enforcing | ||
| ro.boot.vbmeta.device_state=locked | ||
|
|
||
| # Additional properties from MagiskHide | ||
| ro.boot.warranty_bit=0 | ||
| ro.warranty_bit=0 | ||
| ro.debuggable=0 | ||
| ro.secure=1 | ||
| ro.build.type=user | ||
| ro.vendor.boot.warranty_bit=0 | ||
| ro.vendor.warranty_bit=0 | ||
| vendor.boot.vbmeta.device_state=locked | ||
| vendor.boot.verifiedbootstate=green |