diff --git a/README.md b/README.md index c006085..fc07ed4 100644 --- a/README.md +++ b/README.md @@ -7,10 +7,10 @@ These are the current checks/tricks we are using to give an indication of root. **Java checks** -* CheckRootManagementApps -* CheckPotentiallyDangerousApps -* CheckRootCloakingApps -* CheckTestKeys +* checkRootManagementApps +* checkPotentiallyDangerousApps +* checkRootCloakingApps +* checkTestKeys * checkForDangerousProps * checkForBusyBoxBinary * checkForSuBinary @@ -56,10 +56,12 @@ You can also call each of the checks individually as the sample app does. ### False positives -Note that sometimes the `isRooted()` method can return a false positive. This is often because the manufacturer of the device rom has left the busybox binary. This alone doesn't mean that the device is rooted, if you wish to avoid this but still use a convenience method to you can use the following: +Manufacturers often leave the busybox binary in production builds and this doesn't always mean that a device is root. We have removed the busybox check we used to include as standard in the isRooted() method to avoid these false positives. + +If you want to detect the busybox binary in your app you can use `checkForBinary(BINARY_BUSYBOX)` to detect it alone, or as part of the complete root detection method: ```java -rootBeer.isRootedWithoutBusyBoxCheck() +rootBeer.isRootedWithBusyBoxCheck(); ``` The following devices are known the have the busybox binary present on the stock rom: diff --git a/rootbeerlib/src/main/java/com/scottyab/rootbeer/RootBeer.java b/rootbeerlib/src/main/java/com/scottyab/rootbeer/RootBeer.java index 7f51971..92793d1 100644 --- a/rootbeerlib/src/main/java/com/scottyab/rootbeer/RootBeer.java +++ b/rootbeerlib/src/main/java/com/scottyab/rootbeer/RootBeer.java @@ -44,19 +44,28 @@ public RootBeer(Context context) { public boolean isRooted() { return detectRootManagementApps() || detectPotentiallyDangerousApps() || checkForBinary(BINARY_SU) - || checkForBinary(BINARY_BUSYBOX) || checkForDangerousProps() || checkForRWPaths() + || checkForDangerousProps() || checkForRWPaths() || detectTestKeys() || checkSuExists() || checkForRootNative() || checkForMagiskBinary(); } /** - * Run all the checks apart from checking for the busybox binary. This is because it can sometimes be a false positive - * as some manufacturers leave the binary in production builds. - * @return true, we think there's a good *indication* of root | false good *indication* of no root (could still be cloaked) + * @deprecated This method is deprecated as checking without the busybox binary is now the + * default. This is because many manufacturers leave this binary on production devices. */ public boolean isRootedWithoutBusyBoxCheck() { + return isRooted(); + } + + /** + * Run all the checks apart including checking for the busybox binary. + * Warning: Busybox binary is not always an indication of root, many manufacturers leave this + * binary on production devices + * @return true, we think there's a good *indication* of root | false good *indication* of no root (could still be cloaked) + */ + public boolean isRootedWithBusyBoxCheck() { return detectRootManagementApps() || detectPotentiallyDangerousApps() || checkForBinary(BINARY_SU) - || checkForDangerousProps() || checkForRWPaths() + || checkForBinary(BINARY_BUSYBOX) || checkForDangerousProps() || checkForRWPaths() || detectTestKeys() || checkSuExists() || checkForRootNative() || checkForMagiskBinary(); } @@ -163,7 +172,7 @@ public boolean checkForSuBinary(){ * @return true if found */ public boolean checkForBusyBoxBinary(){ - return checkForBinary("busybox"); + return checkForBinary(BINARY_BUSYBOX); } /** diff --git a/rootbeerlib/src/test/java/com/scottyab/rootbeer/RootBeerTest.java b/rootbeerlib/src/test/java/com/scottyab/rootbeer/RootBeerTest.java index 64c1b2d..ab6efc4 100644 --- a/rootbeerlib/src/test/java/com/scottyab/rootbeer/RootBeerTest.java +++ b/rootbeerlib/src/test/java/com/scottyab/rootbeer/RootBeerTest.java @@ -31,7 +31,6 @@ public void testIsRooted() { when(rootBeer.detectRootManagementApps()).thenReturn(false); when(rootBeer.detectPotentiallyDangerousApps()).thenReturn(false); - when(rootBeer.checkForBinary(Const.BINARY_BUSYBOX)).thenReturn(false); when(rootBeer.checkForBinary(Const.BINARY_SU)).thenReturn(false); when(rootBeer.checkForDangerousProps()).thenReturn(false); when(rootBeer.checkForRWPaths()).thenReturn(false); @@ -40,7 +39,7 @@ public void testIsRooted() { when(rootBeer.checkForRootNative()).thenReturn(false); // Test we return false when all methods return false - assertTrue(!rootBeer.isRooted()); + assertFalse(rootBeer.isRooted()); when(rootBeer.checkForRootNative()).thenReturn(true); @@ -49,13 +48,11 @@ public void testIsRooted() { } @Test - public void testIsRootedWithoutBusyBoxCheck() { + public void testIsRootedWithBusyBoxCheck() { RootBeer rootBeer = Mockito.mock(RootBeer.class); when(rootBeer.isRooted()).thenCallRealMethod(); - when(rootBeer.isRootedWithoutBusyBoxCheck()).thenCallRealMethod(); - when(rootBeer.detectRootManagementApps()).thenReturn(false); when(rootBeer.detectPotentiallyDangerousApps()).thenReturn(false); when(rootBeer.checkForBinary(Const.BINARY_BUSYBOX)).thenReturn(true); @@ -66,12 +63,11 @@ public void testIsRootedWithoutBusyBoxCheck() { when(rootBeer.checkSuExists()).thenReturn(false); when(rootBeer.checkForRootNative()).thenReturn(false); - // Test we return false when all methods return false - assertTrue(rootBeer.isRooted()); - - // Test it doesn't matter what checkForBinary("busybox") returns - assertTrue(!rootBeer.isRootedWithoutBusyBoxCheck()); + // Test we return false as busybox binary presence is ignored + assertFalse(rootBeer.isRooted()); + // Check busybox present is detected + assertTrue(rootBeer.checkForBinary(Const.BINARY_BUSYBOX)); } @Test