Closed Ingan121 closed 5 years ago
UDS is Unix Domain Socket, and it detects magisk by checking if there is a random string of 32 (or more) digits starting with @ in /proc/net/unix (It may have some more ways to detect Magisk.)
A screenshot of non-root terminal that shows why it works: (It doesn't matter whether MagiskHide is enabled for terminal app.)
NDK C++ Source of UDS detecting part (Full):
* Description: Check the Unix Domain Socket used by Magisk
*
* Parameters: none
*
* Return value: 0 - non-existant / not visible, 1 or more - exists
*
*****************************************************************************/
int Java_com_kimchangyoun_rootbeerFresh_RootBeerNative_checkForMagiskUDS( JNIEnv* env, jobject thiz )
{
int uds_detect_count = 0;
int magisk_file_detect_count = 0;
int result = 0;
// Magisk UDS(Unix Domain Socket) Detection Method.
// The unix domain socket is typically used for local communications, ie IPC.
// At least Android 8.0 can look up unix domain sockets.
// You need to be sure that you can query the unix domain socket on Android 9.0 or later.
FILE *fh = fopen("/proc/net/unix", "r");
if (fh) {
for (;;) {
char filename[BUFSIZE] = {0};
uint32_t a, b, c, d, e, f, g;
int count = fscanf(fh, "%x: %u %u %u %u %u %u ",
&a, &b, &c, &d, &e, &f, &g);
if (count == 0) {
if (!fgets(filename, BUFSIZE, fh)) {
break;
}
continue;
} else if (count == -1) {
break;
} else if (!fgets(filename, BUFSIZE, fh)) {
break;
}
LOGD("%s", filename);
magisk_file_detect_count += checkFileStat("/dev/.magisk.unblock");
magisk_file_detect_count += checkFileStat("/sbin/magiskinit");
magisk_file_detect_count += checkFileStat("/sbin/magisk");
magisk_file_detect_count += checkFileStat("/sbin/.magisk");
magisk_file_detect_count += checkFileStat("/data/adb/magisk.img");
magisk_file_detect_count += checkFileStat("/data/adb/magisk.db");
magisk_file_detect_count += checkFileStat("/data/adb/.boot_count");
magisk_file_detect_count += checkFileStat("/data/adb/magisk_simple");
magisk_file_detect_count += checkFileStat("/data/adb/magisk");
magisk_file_detect_count += checkFileStat("/cache/.disable_magisk");
magisk_file_detect_count += checkFileStat("/cache/magisk.log");
magisk_file_detect_count += checkFileStat("/init.magisk.rc");
/*
/overlay/sbin/magisk
/data/adb/magisk/magisk.apk
/data/adb/magisk_debug.log
/data/adb/magisk_merge.img
/dev/.magisk.patch.done
/data/data/com.topjohnwu.magisk/install
/data/user_de/0/com.topjohnwu.magisk/install
*/
// The name of the unix domain socket created by the daemon is prefixed with an @ symbol.
char *ptr = strtok(filename, "@");
if(ptr) {
// On Android, the / character, space, and dot characters are the names of the normal unix domain sockets.
if(strstr(ptr, "/")) {
;
} else if(strstr(ptr, " ")) {
;
} else if(strstr(ptr, ".")) {
;
} else { // Magisk replaces the name of the unix domain socket with a random string of 32 digits.
int len = strlen(ptr);
if (len >= 32) {
// Magisk was detected.
LOGD("[Detect Magisk UnixDomainSocket] %s", ptr);
uds_detect_count++;
}
}
}
}
fclose(fh);
}
if(uds_detect_count == 0 || magisk_file_detect_count == 0) {
result = 0;
} else {
result = 1;
}
return result;
}```
It's a really fuzzy (still smart!) way to detect Magisk though if I got this correctly. I mean just because Magisk uses abstract namespace doesn't mean that only magisk does it. 🤔
Well this is not a good solution, I can rename it to any length and maybe some other weird strings. People should come up with better ideas to overcome this....
Rootbeer's solution is naive though effective.
/
in socket name, rootbeer can update accordingly.
in socket name, rootbeer can update accordinglyspace
in socket name, rootbeer can update accordinglyAlso, once another legitimate app/service creates a 32 bytes long socket name, it will create a false positive. Shortening the socket name to 7 or 10 characters will likely force rootbeer to update its detection, thus increase the false positive rate.
Personally I would not chase rootbeer's detection algorithm but rather focus on Play Services.
(beucase Play Services prevents us from NFC payments)
@djechelon Yeah, it is really a dumb way to detect, but the problem is that some anti-root solutions started to implement this method. I think no one will try to detect 10-20 digit socket names since it's very common. (And , it is almost impossible to detect its "randomity" itself.)
It's "MAGISK UDS AND STAT" process detects Magisk even if MagiskHide is being used. Its source is available here: https://github.com/kimchangyoun/rootbeerFresh Also, sample app is available here: https://play.google.com/store/apps/details?id=com.kimchangyoun.rootbeerFresh.sample Tested on Samsung Galaxy S7 (SM-G930L) with 8.0 Oreo