Reversing DetectMagisk.apk and Evading Him-Part 1
Hola Mates,
Been a while since I dropped a new write-up. IDY today I am slightly having that little pump on my body to come up with a new story.
Btw Let’s dive right into the matter without any of the usual yawns.
So what is DetectMagisk.apk?:
DetectMagiskhide is an android app from darvinsec GitHub — darvincisec/DetectMagiskHide: A way to detect magisk hide using an Android feature , that demonstrate the detection of the Magisk and it’s module “MagiskHide” on a android device.
Time to Analyze the Code
We can download the APK’s source code from the GitHub Repo and I am Opening the code files in my Sublime
Now it’s time to find the target files in which the MagiskHide detection code is present.
We can find the files by searching certain keywords such as /sbin, /busybox , magisk, /mounts, etc.
That’s enough I guess, we got our target files (our playground) from the search results.
Target file 1: \DetectMagisk Bypass\DetectMagiskHide-master\app\src\main\c\native-lib.c
Take a peek at this pic! It’s a C file, hanging out with the native libraries gang. When it’s time to build the app, this file gets compiled into a Shared Object file (.so)
So let’s check what's the deal with this C file.
we’ve got a couple of Boolean functions chilling at the top of the code. Pretty intriguing, huh?
Let’s analyze the functions one by one
- is_mountpaths_detected()
Have a look at the screenshot, here the function is trying to identify whether there are any mount paths associated with the Magisk is exist or not (When Magisk is installed on an Android device, it typically creates its own mount points within the file system to perform its functions. These mount points are used to dynamically modify the system partition at runtime without permanently altering the system files.)
Btw from the code, we can see that the validation taking place by cross checking with an array variable blacklistedMountPaths[].
So what the hell is that!! let’s pull this thing out..
So here they are.., as I already mentioned, they are the default mount paths of Magisk. Hence, the function is_mountpaths_detected() will return TRUE if it found any of the Magisk mount paths in the installed device.
Time to jump on to the next function.
2. is_supath_detected()
The same logic goes here too, The function is trying to identify some default Super User (su) paths which may resides within a rooted android device.
They are the common paths usually available on a rooted android device.
So the function is_supath_detected() will return TRUE if it found any of them.
Hmm…we are not done yet, there is an another fish we need to catch!
There is one more Boolean type function? Hmmm, slight correction, it is a JNI boolean function (jboolean).
JNI(Java Native Interface) functions are something that can be accessed/called from the Java code.
So now let’s check what’s the heck is happening here …
There is a boolean variable can be seen within the function
This boolean function, bRet
, will return TRUE
if any of the preceding functions (is_supath_detected()
or is_mountpaths_detected()
), had returned TRUE
. And the JNIEXPORT will export the bRet function to the application’s Java code so that the Java code can perform the required security actions when it identifies the Rooted state.
Ah, wrapping up for today. We’re done with the native C file, but I’ll admit, I don’t delve too deep into the code. becuase, I’m not a programmer, so there’s a chance I might end up spouting foolishness, Lol xD
Ok Bella Ciao.. : )