[Magisk] ScottIsMyName:
I've been researching the InTune portal apk and it clearly doesn't use SafetyNet checks, because my device is passing safetynet just fine.

I believe the culprit is that it's simply checking for the su binary in the $PATH variable, but I'm not 100% sure why suhide isn't blocking it exactly. [MENTION=4470081]topjohnwu[/MENTION] do you have any idea why suhide doesn't block this program from seeing the su binary?

However, just to be verbose, I'll run through all of the smali code from the decompiled apk. All of the root checks seem to be executed in the following package:

com.microsoft.omadm.rootdetection

Inside it are the following modules:

DeviceRooted.smali
DeviceRooted_Factory.smali
FolderPermissionModified.smali
FolderPermissionModified_Factory.smali
IRootTest.smali
RootCloakInstalledRootTest.smali
RootCloakInstalledRootTest_Factory.smali
SuExistsRootTest.smali
SuExistsRootTest_Factory.smali
SuperUserPackageInstalledRootTest.smali
SuperUserPackageInstalledRootTest_Factory.smali
UsingTestKeysRootTest.smali
UsingTestKeysRootTest_Factory.smali

It seems to be doing the following checks:

.field public static final MODIFIED_DIRECTORY_PERM_BIT:I = 0x10
.field public static final ROOT_CLOAK_INSTALLED_BIT:I = 0x20
.field public static final SUPERUSER_EXISTS_BIT:I = 0x2
.field public static final SU_BINARY_BIT:I = 0x1
.field public static final TEST_KEY_BUILD_BIT:I = 0x8
.field public static final XPOSED_CLASS_FOUND_BIT:I = 0x40

MODIFIED_DIRECTORY_PERM_BIT

First, it looks like it's checking the permissions of /data. Looks like it's checking for rwxrwx--x (actually just checking to make sure last set of permissions are --x (or 1).

const-string v0, "data"

const-string v1, ".*d[r-][w-][x-][r-][w-][x-]--[x-].*"

I checked my phone and it should pass this test:

drwxrwx--x 40 system system 4096 2017-11-08 15:22 data

Next, it checks the permissions of /system. It's basically making sure group/global don't have write permissions (so something like 755).

const-string/jumbo v0, "system"

const-string v1, ".*d[r-][w-][x-][r-]-[x-][r-]-[x-].*"

My phone seems to pass this test:

drwxr-xr-x 14 root root 4096 2009-01-01 00:00 system

ROOT_CLOAK_INSTALLED_BIT

Here it appears to be checking for xposed bridge. In RootCloakInstalledRootTest.smali. Note, that the name of the constant seems wrong, and this appears to be checking for XPOSED_CLASS_FOUND_BIT instead. In any case....

.field protected static final XPOSED_BRIGE_CLASS:Ljava/lang/String; = "de.robv.android.xposed.XposedBridge"
.field protected static final XPOSED_METHOD_REPLACEMENT_CLASS:Ljava/lang/String; = "de.robv.android.xposed.XC_MethodReplacement"

It's looking for those package names. I never installed Xposed for my device, so those should definitely not be there....

SUPERUSER_EXISTS_BIT

This tests for a few different SuperUser packages as being installed. From SuperUserPackageInstalledRootTest.smali:

.field private static final SUPERUSER_PACKAGE_FILENAME:Ljava/lang/String; = "Superuser.apk"
.field private static final SYSTEM_APP_DIRECTORY:Ljava/lang/String; = "/system/app"

new-array v0, v0, [Ljava/lang/String;
const/4 v1, 0x0
const-string v2, "eu.chainfire.supersu"
aput-object v2, v0, v1
const/4 v1, 0x1
const-string v2, "com.noshufou.android.su"
aput-object v2, v0, v1
const/4 v1, 0x2
const-string v2, "com.koushikdutta.superuser"

None of these are installed on my phone. The following grep statement returns nothing

1|taimen:/system/app $ find . | grep su

SU_BINARY_BIT

From SuExistsRootTest.smali, we see the following. This looks to check the $PATH variable to see if "su" is in your path. Looking further into the PathSearchUtil code, it also hardcodes /system/bin and /system/xbin even if they're not in your path. However, that does not matter in the case of magisk.

.field private static final SU_BINARY_FILENAME:Ljava/lang/String; = "su"
const-string/jumbo v0, "su"

invoke-static {v0}, Lcom/microsoft/omadm/utils/PathSearchUtil;->fileExistsInPath(Ljava/lang/String;)Z

Testing on my phone, we can see that it does immediately detect the su binary (even ran as a normal user, not root). I tried hiding root from com.android.shell but this does not work.

taimen:/ $ whoami
shell
taimen:/ $ echo $PATH
/sbin:/system/sbin:/system/bin:/system/xbin:/vendor/bin:/vendor/xbin
taimen:/ $ which su
/sbin/su

TEST_KEY_BUILD_BIT

From UsingTestKeysRootTest.smali, we can see the following:

.param p1, "buildTags" # Ljava/lang/String;
const-string/jumbo v0, "test-keys"
invoke-virtual {p1, v0}, Ljava/lang/String;->contains(Ljava/lang/CharSequence;)Z

So it looks like it's looking test-keys in the build.prop entry. Checking my phone, this is not the case:

taimen:/ $ getprop | grep build.tags
[ro.build.tags]: [release-keys]

XPOSED_CLASS_FOUND_BIT

Finally, in RootCloakInstalledRootTest.smali, we see the following code. (Note, this is likely swapped with the ROOT_CLOAK_INSTALLED_BIT static values, but it doesn't matter. If any of the checks return non 0, the device will be considered rooted).

new-array v0, v0, [Ljava/lang/String;
const/4 v1, 0x0
const-string v2, "devadvance"
aput-object v2, v0, v1
const/4 v1, 0x1
const-string/jumbo v2, "rootcloak"

Note, since this seems to be a weird one, here is the full contents of RootCloakInstalledRootTest.smali:

.class public Lcom/microsoft/omadm/rootdetection/RootCloakInstalledRootTest;
.super Ljava/lang/Object;
.source "RootCloakInstalledRootTest.java"

# interfaces
.implements Lcom/microsoft/omadm/rootdetection/IRootTest;

# static fields
.field private static final ROOT_CLOAK_PACKAGE_SIGNATURES:[Ljava/lang/String;

.field protected static final XPOSED_BRIGE_CLASS:Ljava/lang/String; = "de.robv.android.xposed.XposedBridge"

.field protected static final XPOSED_METHOD_REPLACEMENT_CLASS:Ljava/lang/String; = "de.robv.android.xposed.XC_MethodReplacement"

# direct methods
.method static constructor <clinit>()V
.locals 3

.prologue
.line 20
const/4 v0, 0x2

new-array v0, v0, [Ljava/lang/String;

const/4 v1, 0x0

const-string v2, "devadvance"

aput-object v2, v0, v1

const/4 v1, 0x1

const-string/jumbo v2, "rootcloak"

aput-object v2, v0, v1

sput-object v0, Lcom/microsoft/omadm/rootdetection/RootCloakInstalledRootTest;->ROOT_CLOAK_PACKAGE_SIGNATURES:[Ljava/lang/String;

return-void
.end method

.method public constructor <init>()V
.locals 0

.prologue
.line 29
invoke-direct {p0}, Ljava/lang/Object;-><init>()V

.line 30
return-void
.end method

.method private checkClassForName(Ljava/lang/String;)I
.locals 6
.param p1, "className" # Ljava/lang/String;

.prologue
const/4 v3, 0x0

.line 46
const/4 v2, 0x0

.line 48
.local v2, "xposedClass":Ljava/lang/Class;, "Ljava/lang/Class<*>;"
const/4 v4, 0x0

:try_start_0
invoke-virtual {p0}, Ljava/lang/Object;->getClass()Ljava/lang/Class;

move-result-object v5

invoke-virtual {v5}, Ljava/lang/Class;->getClassLoader()Ljava/lang/ClassLoader;

move-result-object v5

invoke-static {p1, v4, v5}, Ljava/lang/Class;->forName(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;
:try_end_0
.catch Ljava/lang/ClassNotFoundException; {:try_start_0 .. :try_end_0} :catch_0

move-result-object v2

.line 55
:cond_0
if-eqz v2, :cond_1

const/16 v3, 0x40

:cond_1
:goto_0
return v3

.line 49
:catch_0
move-exception v0

.line 50
.local v0, "e":Ljava/lang/ClassNotFoundException;
invoke-static {v0}, Lorg/apache/commons/lang3/exception/ExceptionUtils;->getStackTrace(Ljava/lang/Throwable;)Ljava/lang/String;

move-result-object v1

.line 51
.local v1, "trace":Ljava/lang/String;
sget-object v4, Lcom/microsoft/omadm/rootdetection/RootCloakInstalledRootTest;->ROOT_CLOAK_PACKAGE_SIGNATURES:[Ljava/lang/String;

invoke-static {v1, v4}, Lorg/apache/commons/lang3/StringUtils;->indexOfAny(Ljava/lang/CharSequence;[Ljava/lang/CharSequence;)I

move-result v4

const/4 v5, -0x1

if-eq v4, v5, :cond_0

.line 52
const/16 v3, 0x20

goto :goto_0
.end method

# virtual methods
.method public executeTest()I
.locals 2

.prologue
.line 34
const-string v0, "de.robv.android.xposed.XposedBridge"

invoke-direct {p0, v0}, Lcom/microsoft/omadm/rootdetection/RootCloakInstalledRootTest;->checkClassForName(Ljava/lang/String;)I

move-result v0

const-string v1, "de.robv.android.xposed.XC_MethodReplacement"

invoke-direct {p0, v1}, Lcom/microsoft/omadm/rootdetection/RootCloakInstalledRootTest;->checkClassForName(Ljava/lang/String;)I

move-result v1

or-int/2addr v0, v1

return v0
.end method