Snapchat detection on Android

Snapchat is a really populair app to modify with Xposed, because this allows the user for example to save received snaps. In this post I will explain why you are getting banned.

If you are unfamiliar with Xposed, it’s a framework created by rovo89 allowing others to write Android Apps that hook into applications. It’s not maintained anymore by rovo89, but there is an unofficial fork called EdXposed that supports Android 8.0, 8.1 and 9.0.

Ban Message

It seems that lately the ban ratios have gone up on recent Snapchat versions (v10.5x.xx.xx). It does not matter what version / release of Xposed you use, the ban will still happen.

  • Xposed Framework (rovo89), packaged by topjohnwu
  • Riru - EdXposed (YAHFA)
  • Riru - EdXposed (SandHook)

There have been a lot of assumptions on what information Snapchat collects about your device but I haven’t seen any facts yet. I will first explain what has been tried so far to avoid bans and then show why this fails.

Avoiding bans

From googling a little bit, this is all I could find.

  1. XPrivacyLua (Xposed Module)
  2. MagiskHide
  3. Removing Xposed during login, re-installing after logging in
  4. Titaniumbackup
  5. Restore titaniumbackup on Bluestacks (or another emulator)

Most of these solutions only stop SafetyNet from failing during login (2 - 5) and XPrivacyLua only spoofs your device as another one. None of these “solutions” actually attempt to hide Xposed during daily usage, which is what causes the bans.

SafetyNet

This is the most obvious one and happens when you login. Having Xposed installed will trip SafetyNet and fail your login attempt. This is an easy fix. Remove Xposed, login, install Xposed. This will get you signed in, but you will still get banned later.

Snapchat detections

When your device sends an HTTP request to the Snapchat servers, it requires a signed token in a HTTP Header called X-Snapchat-Client-Auth. This token is generated by a native library called libscplugin.so, which has this method implemented.

native String signRequest(String[] keys, String[] values, String requestPath, byte[] dustToken);

The first time this method is ran, it runs a ton of checks against your device and stores the results to be used later in the request token. I have tried to put all these checks in a category. These were obtained from Snapchat v10.57.0.0.

All the things listed below happen in the native library.

Integrity checks

  • Checks ApplicationInfo.flags
  • Checks flag FLAG_DEBUGGABLE
  • Checks flag ALLOW_MOCK_LOCATION
  • PackageManager.getPackageInfo(getPackageName(), GET_SIGNATURES);
  • PackageManager.getInstallerPackageName("com.snapchat.android");
  • Compares ZipEntry.getCrc of every classesX.dex in /data/app/com.snapchat.android-XXXX/base.apk, which is obtained using ApplicationInfo.sourceDir
  • Uses PackageInfo.versionName (probably in the token)
  • Uses SCPluginWrapper.DATA (token)

Device information

The following properties are obtained using __system_property_get.

  • ro.product.model
  • ro.build.version.release
  • ro.build.version.sdk
  • ro.build.version.incremental

It also gathers the following.

  • A device token generated by Snapchat servers, you receive a new one if you fully wipe Snapchat data from your device. The method to fetch the stored token is oig.zga.a().
  • The android_id token from Settings.Secure.
    For more information on this token, read the docs.

Java integrity checks

This is one of the checks where Snapchat knows if you have hooked. Some of these will be triggered if you just have Xposed installed, it does not matter if you have a Snapchat related module installed. Even with EdXposed whitelist/blacklist.

It grabs uses the following reflection tools to do this.

  • java.lang.reflect.Method
    • int slot;
    • Class declaringClass;
    • static int getMethodModifiers(Class);
  • java.lang.reflect.Constructor
    • int slot;
    • Class declaringClass;
  • java.lang.reflect.Executable
    • int accessFlags;
  • java.lang.reflect.AbstractMethod
    • ArtMethod artMethod;
    • int accessFlags;
  • java.lang.reflect.MethodArt
    • int accessFlags;
  • java.lang.reflect.Field
    • int slot;
    • Class declaringClass;
    • ArtField artField;
    • int accessFlags;
  • java.lang.reflect.ArtField
    • int accessFlags;

Not everything is available on every device. For example, if Method.getMethodModifiers is missing, it uses Executable.accessFlags. It checks the following methods and fields.

  • android.app.ActivityThread
    • void handleBindApplication(AppBindData);
    • ActivityThread currentActivityThread();
    • ContextImpl getSystemContext();
  • android.app.ApplicationPackageManager
    • Resources getResourcesForApplication(ApplicationInfo);
    • PackageInfo getPackageInfo(String);
  • android.app.Application
    • void attach(Context);
  • com.snapchat.android.LandingPageActivityV1 (Does not exist in 10.57.0.0)
    • void onCreate(Bundle);
  • com.snapchat.android.framework.crypto.CbcEncryptionAlgorithm (Does not exist in 10.57.0.0)
    • InputStream b(InputStream);
  • com.snap.opera.shared.view.TextureVideoView
    • void start();
    • void setLooping(boolean); (Does not exist in 10.57.0.0)
  • com.snapchat.android.framework.misc.AppContext
    • Application get();
  • android.app.ContextImpl
    • PackageManager getPackageManager();
    • String getPackageName();
    • ApplicationInfo getApplicationInfo();
  • java.util.zip.ZipFile
    • <init>(String);
    • ZipEntry getEntry(String);
  • java.util.zip.ZipEntry
    • long getCrc();

Xposed

Checks if the following classes exist using JNI FindClass.

  • xposed/dummy/XResourcesSuperClass
  • de/robv/android/xposed/XposedBridge

Checks if the following files / directories exist using fstatat64 syscall.

  • /xposed.prop
  • /system/bin/app_process.orig
  • /system/lib/libxposed_art.so
  • /system/lib64/libxposed_art.so
  • /system/bin/app_process32_xposed
  • /system/bin/app_process64_xposed
  • /data/data/de.robv.android.xposed.installer
  • /data/user/0/de.robv.android.xposed.installer
  • /data/user_de/0/de.robv.android.xposed.installer

Attempts to open the following files using open syscall.

  • /data/user_de/0/de.robv.android.xposed.installer/conf/modules.list
  • /data/user/0/de.robv.android.xposed.installer/conf/modules.list
  • /data/data/de.robv.android.xposed.installer/conf/modules.list

If this succeeds, it tries to check if they contain the following.

  • snaptools
  • snapprefs

Xposed modules

Checks if the following files / directories exist using fstatat64 syscall.

  • /data/data/com.ljmu.andre.snaptools
  • /data/user/0/com.ljmu.andre.snaptools
  • /data/user_de/0/com.ljmu.andre.snaptools
  • /data/data/local.interceptmod
  • /data/user/0/local.interceptmod
  • /data/user_de/0/local.interceptmod
  • /data/data/local.snapintercept
  • /data/user/0/local.snapintercept
  • /data/user_de/0/local.snapintercept
  • /data/data/com.marz.snapprefs
  • /data/user/0/com.marz.snapprefs
  • /data/user_de/0/com.marz.snapprefs

Magisk

I don’t think you get banned for just having Magisk, but they do check for it. I believe all of these can be avoided by turning MagiskHide on for Snapchat and repackaging Magisk.

Checks if the following files / directories exist using fstatat64 syscall.

  • /data/data/com.topjohnwu.magisk
  • /data/user/0/com.topjohnwu.magisk
  • /data/user_de/0/com.topjohnwu.magisk
  • /sbin/magisk
  • /sbin/magiskhide
  • /init.magisk.rc
  • /dev/magisk/bin/busybox
  • /system/addon.d/99-magisk.sh
  • /data/user/0/magisk.db
  • /data/user_de/0/magisk.db
  • /root/magisk
  • /magisk
  • /sbin_orig
  • /data/magisk
  • /sbin/.core

Reads the following files using read syscall.

  • /proc/self/mounts, checks for magisk

Superuser

Checks if the following files / directories exist using fstatat64 syscall.

  • /system/app/Superuser.apk
  • /system/app/Superuser/Superuser.apk
  • /init.supersu.rc
  • /system/.supersu
  • /data/.supersu
  • /dev/block/supersu/su
  • /sbin/daemonsu
  • /dev/__properties__/u:object_r:supersu_prop:s0
  • /data/data/eu.chainfire.supersu
  • /data/user/0/eu.chainfire.supersu
  • /data/user_de/0/eu.chainfire.supersu
  • /data/data/eu.chainfire.suhide
  • /data/user/0/eu.chainfire.suhide
  • /data/user_de/0/eu.chainfire.suhide
  • /sbin/su
  • /system/bin/su
  • /system/xbin/su
  • /data/local/xbin/su
  • /data/local/bin/su
  • /system/sd/xbin/su
  • /system/bin/failsafe/su
  • /data/local/su
  • /su/bin/su
  • /su

TitaniumBackup

Checks if the following files / directories exist using fstatat64 syscall.

  • /data/data/com.keramidas.TitaniumBackup
  • /data/user/0/com.keramidas.TitaniumBackup
  • /data/user_de/0/com.keramidas.TitaniumBackup

Nox App Player

Checks if the following files / directories exist using fstatat64 syscall.

  • /fstab.nox
  • /system/bin/noxd
  • /ueventd.nox.rc
  • /system/bin/noxscreen
  • /etc/init.nox.sh

Genymotion

Checks if the following files / directories exist using fstatat64 syscall.

  • /dev/socket/genyd
  • /dev/socket/baseband_genyd
  • /data/data/com.genymotion.superuser
  • /data/user/0/com.genymotion.superuser
  • /data/user_de/0/com.genymotion.superuser
  • /system/genymotion

YouWave

Checks if the following files / directories exist using fstatat64 syscall.

  • /data/youwave_id

VirtualBox

Checks if the following files / directories exist using fstatat64 syscall.

  • /system/bin/androVM-prop
  • /dev/vboxuser
  • /sys/module/vboxguest
  • /sys/bus/pci/drivers/vboxguest

Misc

Reads the following files using read syscall.

  • /proc/self/status
  • /proc/self/maps
  • /proc/self/cmdline
  • /proc/bus/input/devices, check for VirtualBox and BlueStacks
  • /proc/bus/pci/devices, check for bstinput and nox_gpio
  • /proc/mounts, check for supersu

Checks if the following files / directories exist using fstatat64 syscall.

  • /dev/socket/bstfolderd
  • /boot/bstmods
  • /mnt/prebundledapps

Tools used

The tools used to gather this information are listed below.

Conclusion

As you can see, there are a lot of checks you fail just by having Xposed installed. I hope this clears up the confusion around getting banned. The best way avoid getting banned is to not use Xposed.

Written on June 3, 2019