├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── xposed_init │ ├── java │ └── github │ │ └── ryuunoakaihitomi │ │ └── tetheringdetectiondeceiver │ │ ├── C.java │ │ ├── HookHelper.java │ │ ├── MainActivity.java │ │ ├── MainHook.java │ │ └── TetherHelper.java │ └── res │ ├── values-v23 │ └── styles.xml │ └── values │ ├── strings.xml │ └── styles.xml ├── build.gradle └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | # Built application files 2 | *.apk 3 | *.ap_ 4 | *.aab 5 | 6 | # Files for the ART/Dalvik VM 7 | *.dex 8 | 9 | # Java class files 10 | *.class 11 | 12 | # Generated files 13 | bin/ 14 | gen/ 15 | out/ 16 | release/ 17 | 18 | # Gradle files 19 | .gradle/ 20 | build/ 21 | 22 | # Local configuration file (sdk path, etc) 23 | local.properties 24 | 25 | # Proguard folder generated by Eclipse 26 | proguard/ 27 | 28 | # Log Files 29 | *.log 30 | 31 | # Android Studio Navigation editor temp files 32 | .navigation/ 33 | 34 | # Android Studio captures folder 35 | captures/ 36 | 37 | # IntelliJ 38 | *.iml 39 | .idea/workspace.xml 40 | .idea/tasks.xml 41 | .idea/gradle.xml 42 | .idea/assetWizardSettings.xml 43 | .idea/dictionaries 44 | .idea/libraries 45 | # Android Studio 3 in .gitignore file. 46 | .idea/caches 47 | .idea/modules.xml 48 | # Comment next line if keeping position of elements in Navigation Editor is relevant for you 49 | .idea/navEditor.xml 50 | 51 | # Keystore files 52 | # Uncomment the following lines if you do not want to check your keystore files in. 53 | #*.jks 54 | #*.keystore 55 | 56 | # External native build folder generated in Android Studio 2.2 and later 57 | .externalNativeBuild 58 | 59 | # Google Services (e.g. APIs or Firebase) 60 | # google-services.json 61 | 62 | # Freeline 63 | freeline.py 64 | freeline/ 65 | freeline_project_description.json 66 | 67 | # fastlane 68 | fastlane/report.xml 69 | fastlane/Preview.html 70 | fastlane/screenshots 71 | fastlane/test_output 72 | fastlane/readme.md 73 | 74 | # Version control 75 | vcs.xml 76 | 77 | # lint 78 | lint/intermediates/ 79 | lint/generated/ 80 | lint/outputs/ 81 | lint/tmp/ 82 | # lint/reports/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # TetheringDetectionDeceiver 2 | 3 | `Developed for some campus network client.` -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | build/ -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 28 5 | defaultConfig { 6 | applicationId "github.ryuunoakaihitomi.tetheringdetectiondeceiver" 7 | minSdkVersion 19 8 | targetSdkVersion 28 9 | versionCode 2 10 | versionName "1.1" 11 | } 12 | buildTypes { 13 | release { 14 | minifyEnabled false 15 | } 16 | } 17 | } 18 | 19 | dependencies { 20 | compileOnly 'de.robv.android.xposed:api:82' 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20 | 23 | 26 | 27 | 28 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /app/src/main/assets/xposed_init: -------------------------------------------------------------------------------- 1 | github.ryuunoakaihitomi.tetheringdetectiondeceiver.MainHook -------------------------------------------------------------------------------- /app/src/main/java/github/ryuunoakaihitomi/tetheringdetectiondeceiver/C.java: -------------------------------------------------------------------------------- 1 | package github.ryuunoakaihitomi.tetheringdetectiondeceiver; 2 | 3 | class C { 4 | static final String TAG = "TetherDetectionDeceiver"; 5 | static final String LS = System.lineSeparator(); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/github/ryuunoakaihitomi/tetheringdetectiondeceiver/HookHelper.java: -------------------------------------------------------------------------------- 1 | package github.ryuunoakaihitomi.tetheringdetectiondeceiver; 2 | 3 | class HookHelper { 4 | static boolean isXposedActive; 5 | } 6 | -------------------------------------------------------------------------------- /app/src/main/java/github/ryuunoakaihitomi/tetheringdetectiondeceiver/MainActivity.java: -------------------------------------------------------------------------------- 1 | package github.ryuunoakaihitomi.tetheringdetectiondeceiver; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | import android.view.Gravity; 6 | import android.widget.Toast; 7 | 8 | import java.util.Arrays; 9 | 10 | public class MainActivity extends Activity { 11 | 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | 16 | Toast toast = Toast.makeText(this, debugMsg(), Toast.LENGTH_LONG); 17 | toast.setGravity(Gravity.CENTER, 0, 0); 18 | toast.show(); 19 | 20 | finish(); 21 | } 22 | 23 | private String debugMsg() { 24 | return "debugMsg" + C.LS + 25 | "Log Tag: " + C.TAG + C.LS + 26 | "XHook Enable: " + HookHelper.isXposedActive + C.LS + 27 | "isTethering: " + TetherHelper.isTethering(this) + C.LS + 28 | "getTetheredFaces: " + Arrays.toString(TetherHelper.getTetheredFaces(this)); 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/github/ryuunoakaihitomi/tetheringdetectiondeceiver/MainHook.java: -------------------------------------------------------------------------------- 1 | package github.ryuunoakaihitomi.tetheringdetectiondeceiver; 2 | 3 | import android.content.pm.ApplicationInfo; 4 | import android.net.ConnectivityManager; 5 | import android.util.Log; 6 | 7 | import de.robv.android.xposed.IXposedHookLoadPackage; 8 | import de.robv.android.xposed.XC_MethodHook; 9 | import de.robv.android.xposed.XposedHelpers; 10 | import de.robv.android.xposed.callbacks.XC_LoadPackage; 11 | 12 | import static github.ryuunoakaihitomi.tetheringdetectiondeceiver.C.TAG; 13 | 14 | public class MainHook implements IXposedHookLoadPackage { 15 | 16 | @Override 17 | public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { 18 | 19 | if (lpparam.packageName.equals(BuildConfig.APPLICATION_ID)) { 20 | XposedHelpers.setStaticBooleanField( 21 | XposedHelpers.findClass(BuildConfig.APPLICATION_ID + ".HookHelper", lpparam.classLoader), 22 | "isXposedActive", true); 23 | return; 24 | } 25 | 26 | XposedHelpers.findAndHookMethod(ConnectivityManager.class, "getTetheredIfaces", new XC_MethodHook() { 27 | 28 | @Override 29 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable { 30 | 31 | if ((lpparam.appInfo.flags & ApplicationInfo.FLAG_SYSTEM) > 0) { 32 | Log.d(TAG, "beforeHookedMethod: " + lpparam.packageName + " is a system app.Skipping..."); 33 | return; 34 | } 35 | 36 | Log.i(TAG, "beforeHookedMethod: ConnectivityManager.getTetheredIfaces() intercepted! " + 37 | "pkg=" + lpparam.packageName); 38 | param.setResult(new String[0]); 39 | } 40 | }); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/github/ryuunoakaihitomi/tetheringdetectiondeceiver/TetherHelper.java: -------------------------------------------------------------------------------- 1 | package github.ryuunoakaihitomi.tetheringdetectiondeceiver; 2 | 3 | import android.content.Context; 4 | import android.net.ConnectivityManager; 5 | import android.util.Log; 6 | 7 | import java.lang.reflect.InvocationTargetException; 8 | import java.lang.reflect.Method; 9 | 10 | import static github.ryuunoakaihitomi.tetheringdetectiondeceiver.C.TAG; 11 | 12 | class TetherHelper { 13 | 14 | static String[] getTetheredFaces(Context context) { 15 | ConnectivityManager manager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 16 | try { 17 | @SuppressWarnings("JavaReflectionMemberAccess") 18 | Method getTetheredIfaces = ConnectivityManager.class.getMethod("getTetheredIfaces"); 19 | return (String[]) getTetheredIfaces.invoke(manager); 20 | } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) { 21 | Log.e(TAG, "getTetheredFaces: ", e); 22 | } 23 | return null; 24 | } 25 | 26 | static boolean isTethering(Context context) { 27 | String[] tetheredFaces = getTetheredFaces(context); 28 | return tetheredFaces != null && tetheredFaces.length > 0; 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/res/values-v23/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |