Loading remote-droid-guard/build.gradle +0 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ dependencies { compile 'com.squareup.wire:wire-runtime:1.6.1' compile ':droidguasso:@jar' compile ':arthook:@aar' provided 'de.robv.android.xposed:api:82' compile project(':remote-droid-guard-lib') } Loading remote-droid-guard/src/main/AndroidManifest.xml +1 −11 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools"> <uses-sdk android:minSdkVersion="9" android:minSdkVersion="19" android:targetSdkVersion="24" tools:overrideLibrary="de.larma.arthook"/> Loading @@ -24,16 +24,6 @@ <action android:name="org.microg.gms.droidguard.REMOTE"/> </intent-filter> </service> <meta-data android:name="xposedmodule" android:value="true"/> <meta-data android:name="xposeddescription" android:value="Support module for DroidGuard Helper, required when XPosed is installed"/> <meta-data android:name="xposedminversion" android:value="54"/> </application> </manifest> remote-droid-guard/src/main/assets/xposed_initdeleted 100644 → 0 +0 −1 Original line number Diff line number Diff line org.microg.gms.droidguard.SysHook No newline at end of file remote-droid-guard/src/main/java/org/microg/gms/droidguard/SysHook.java +99 −75 Original line number Diff line number Diff line Loading @@ -16,41 +16,38 @@ package org.microg.gms.droidguard; import android.content.ContextWrapper; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.telephony.TelephonyManager; import android.util.Log; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.Iterator; import java.util.NavigableMap; import java.util.List; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import de.larma.arthook.$; import de.larma.arthook.ArtHook; import de.larma.arthook.BackupIdentifier; import de.larma.arthook.Hook; import de.larma.arthook.OriginalMethod; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; import static org.microg.gms.droidguard.Constants.GMS_PACKAGE_NAME; public class SysHook implements IXposedHookLoadPackage { public class SysHook { private static final String TAG = "SysHook"; private static boolean done = false; private static String odexArch = "arm"; // or "arm64" private static String checksum; static boolean done = false; static String odexArch = "arm"; // or "arm64" static String checksum; // From TelephonyManager private static String deviceId; private static String subscriberId; static String deviceId; static String subscriberId; public synchronized static void activate(String odexArch, String checksum, String deviceId, String subscriberId) { SysHook.odexArch = odexArch; Loading @@ -62,76 +59,102 @@ public class SysHook implements IXposedHookLoadPackage { ArtHook.hook(SysHook.class); } @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { if (!lpparam.packageName.equals("org.microg.gms.droidguard")) return; XposedHelpers.findAndHookMethod(TelephonyManager.class, "getSubscriberId", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { @Hook("android.telephony.TelephonyManager->getSubscriberId") public static String TelephonyManager_getSubscriberId(TelephonyManager tm) { Log.d(TAG, "Set subscriber id: " + SysHook.subscriberId); return subscriberId; } }); XposedHelpers.findAndHookMethod(TelephonyManager.class, "getDeviceId", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm) { Log.d(TAG, "Set device id: " + SysHook.deviceId); return deviceId; } }); XposedHelpers.findAndHookMethod(TelephonyManager.class, "getDeviceId", int.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm, int slot) { Log.d(TAG, "Set device id 2: " + SysHook.deviceId); return deviceId; } }); XposedHelpers.findAndHookMethod(ContextWrapper.class, "getPackageName", XC_MethodReplacement.returnConstant(GMS_PACKAGE_NAME)); XposedHelpers.findAndHookMethod(ContextWrapper.class, "getClassLoader", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(createModifiedClassLoader((ClassLoader) param.getResult())); @Hook("android.net.ConnectivityManager->getActiveNetworkInfo") public static NetworkInfo ConnectivityManager_getActiveNetworkInfo(ConnectivityManager cm) { return null; // null is a valid response } }); XposedHelpers.findAndHookMethod(TreeSet.class, "iterator", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { NavigableMap map = (NavigableMap) XposedHelpers.getObjectField(param.thisObject, "m"); if (map == null) map = (NavigableMap) XposedHelpers.getObjectField(param.thisObject, "backingMap"); if (map == null) return; if (detectMapsSet(map.navigableKeySet().iterator())) { param.setResult(createMapsReplacementSet().iterator()); @Hook("java.util.regex.Pattern->matcher") @BackupIdentifier("PatternMatcher") public static Matcher Pattern_matcher(Pattern pattern, CharSequence cs) { OriginalMethod method = OriginalMethod.by("PatternMatcher"); if (cs instanceof String) { String s = (String) cs; if (s.contains("Xposed") || s.contains("xposed") || s.contains("XPosed") || s.contains("XPOSED")) return method.invoke(pattern, ""); if (s.contains("org.microg.gms.droidguard")) return method.invoke(pattern, s.replace("org.microg.gms.droidguard", "com.google.android.gms")); } return method.invoke(pattern, cs); } }); SysHook.done = true; @Hook("android.content.ContextWrapper->getPackageName") public static String ContextWrapper_getPackageName(Object o) { Log.d(TAG, "Set package name: " + GMS_PACKAGE_NAME); return GMS_PACKAGE_NAME; } @Hook("android.telephony.TelephonyManager->getSubscriberId") public static String TelephonyManager_getSubscriberId(TelephonyManager tm) { return subscriberId; @Hook("android.os.SystemProperties->getInt") @BackupIdentifier("SystemPropertiesGetInt") public static int SystemProperties_getInt(String key, int def) { if (key.equals("ro.debuggable") || key.equals("service.adb.root")) return 0; if (key.equals("ro.secure")) return 1; return OriginalMethod.by("SystemPropertiesGetInt").invokeStatic(key, def); } @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm) { return deviceId; @Hook("java.util.Arrays->asList") @BackupIdentifier("ArraysAsList") public static List Arrays_asList(Object[] objs) { Log.d(TAG, "Arrays->asList: "+Arrays.toString(objs)); if (detectLibrariesList(objs)) return OriginalMethod.by("ArraysAsList").invoke(null, new Object[]{getModifiedSystemSharedLibraries()}); return OriginalMethod.by("ArraysAsList").invoke(null, new Object[]{objs}); } @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm, int slot) { return deviceId; static boolean detectLibrariesList(Object[] list) { boolean isList = false; boolean wasModified = false; for (int i = 0; i < list.length; i++) { if (!(list[i] instanceof String)) return false; if ("com.android.location.provider".equals(list[i]) || "android.test.runner".equals(list[i])) isList = true; if ("com.google.widevine.software.drm".equals(list[i])) wasModified = true; } return isList && !wasModified; } @Hook("android.content.ContextWrapper->getPackageName") public static String ContextWrapper_getPackageName(Object o) { return GMS_PACKAGE_NAME; @Hook("android.app.ApplicationPackageManager->getSystemSharedLibraryNames") @BackupIdentifier("PackageManagerGetSystemSharedLibraryNames") public static String[] PackageManager_getSystemSharedLibraryNames(Object o) { Log.d(TAG, "Modified SystemSharedLibraries"); return getModifiedSystemSharedLibraries(); } static String[] getModifiedSystemSharedLibraries() { return new String[]{"android.test.runner", "com.android.future.usb.accessory", "com.android.location.provider", "com.android.media.remotedisplay", "com.android.mediadrm.signer", "com.google.android.maps", "com.google.widevine.software.drm", "com.qualcomm.qcrilhook", "com.qualcomm.qti.rcsservice", "com.quicinc.cneapiclient", "javax.obex", "org.apache.http.legacy"}; } @Hook("android.content.ContextWrapper->getClassLoader") Loading @@ -140,7 +163,7 @@ public class SysHook implements IXposedHookLoadPackage { return createModifiedClassLoader((ClassLoader) OriginalMethod.by("ContextWrapperClassLoader").invoke(o)); } private static ClassLoader createModifiedClassLoader(ClassLoader original) { static ClassLoader createModifiedClassLoader(ClassLoader original) { return new URLClassLoader(new URL[0], original) { @Override public String toString() { Loading @@ -158,22 +181,23 @@ public class SysHook implements IXposedHookLoadPackage { return originalMethod.invoke(set); } private static boolean detectMapsSet(Iterator iterator) { static boolean detectMapsSet(Iterator iterator) { boolean hasDgCache = false; boolean hasFrameworkRes = false; while (iterator.hasNext()) { Object o = iterator.next(); if (!(o instanceof String)) { return false; } String s = (String) o; if (s.contains("org.microg.gms") && s.contains(".apk")) { Log.d(TAG, "Detected maps set"); return true; Log.d(TAG, "mapdetect: " + s); if (s.contains("app_dg_cache")) hasDgCache = true; if (s.contains("framework-res.apk")) hasFrameworkRes = true; } } return false; return hasDgCache && hasFrameworkRes; } private static Set<String> createMapsReplacementSet() { static Set<String> createMapsReplacementSet() { Set<String> replacement = new TreeSet<>(); replacement.add("/data/app/com.google.android.gms-1/base.apk"); replacement.add("/data/app/com.google.android.gms-1/oat/" + odexArch + "/base.odex"); Loading Loading
remote-droid-guard/build.gradle +0 −1 Original line number Diff line number Diff line Loading @@ -10,7 +10,6 @@ dependencies { compile 'com.squareup.wire:wire-runtime:1.6.1' compile ':droidguasso:@jar' compile ':arthook:@aar' provided 'de.robv.android.xposed:api:82' compile project(':remote-droid-guard-lib') } Loading
remote-droid-guard/src/main/AndroidManifest.xml +1 −11 Original line number Diff line number Diff line Loading @@ -4,7 +4,7 @@ xmlns:tools="http://schemas.android.com/tools"> <uses-sdk android:minSdkVersion="9" android:minSdkVersion="19" android:targetSdkVersion="24" tools:overrideLibrary="de.larma.arthook"/> Loading @@ -24,16 +24,6 @@ <action android:name="org.microg.gms.droidguard.REMOTE"/> </intent-filter> </service> <meta-data android:name="xposedmodule" android:value="true"/> <meta-data android:name="xposeddescription" android:value="Support module for DroidGuard Helper, required when XPosed is installed"/> <meta-data android:name="xposedminversion" android:value="54"/> </application> </manifest>
remote-droid-guard/src/main/assets/xposed_initdeleted 100644 → 0 +0 −1 Original line number Diff line number Diff line org.microg.gms.droidguard.SysHook No newline at end of file
remote-droid-guard/src/main/java/org/microg/gms/droidguard/SysHook.java +99 −75 Original line number Diff line number Diff line Loading @@ -16,41 +16,38 @@ package org.microg.gms.droidguard; import android.content.ContextWrapper; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.telephony.TelephonyManager; import android.util.Log; import java.net.URL; import java.net.URLClassLoader; import java.util.Arrays; import java.util.Iterator; import java.util.NavigableMap; import java.util.List; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.regex.Matcher; import java.util.regex.Pattern; import de.larma.arthook.$; import de.larma.arthook.ArtHook; import de.larma.arthook.BackupIdentifier; import de.larma.arthook.Hook; import de.larma.arthook.OriginalMethod; import de.robv.android.xposed.IXposedHookLoadPackage; import de.robv.android.xposed.XC_MethodHook; import de.robv.android.xposed.XC_MethodReplacement; import de.robv.android.xposed.XposedHelpers; import de.robv.android.xposed.callbacks.XC_LoadPackage; import static org.microg.gms.droidguard.Constants.GMS_PACKAGE_NAME; public class SysHook implements IXposedHookLoadPackage { public class SysHook { private static final String TAG = "SysHook"; private static boolean done = false; private static String odexArch = "arm"; // or "arm64" private static String checksum; static boolean done = false; static String odexArch = "arm"; // or "arm64" static String checksum; // From TelephonyManager private static String deviceId; private static String subscriberId; static String deviceId; static String subscriberId; public synchronized static void activate(String odexArch, String checksum, String deviceId, String subscriberId) { SysHook.odexArch = odexArch; Loading @@ -62,76 +59,102 @@ public class SysHook implements IXposedHookLoadPackage { ArtHook.hook(SysHook.class); } @Override public void handleLoadPackage(XC_LoadPackage.LoadPackageParam lpparam) throws Throwable { if (!lpparam.packageName.equals("org.microg.gms.droidguard")) return; XposedHelpers.findAndHookMethod(TelephonyManager.class, "getSubscriberId", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { @Hook("android.telephony.TelephonyManager->getSubscriberId") public static String TelephonyManager_getSubscriberId(TelephonyManager tm) { Log.d(TAG, "Set subscriber id: " + SysHook.subscriberId); return subscriberId; } }); XposedHelpers.findAndHookMethod(TelephonyManager.class, "getDeviceId", new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm) { Log.d(TAG, "Set device id: " + SysHook.deviceId); return deviceId; } }); XposedHelpers.findAndHookMethod(TelephonyManager.class, "getDeviceId", int.class, new XC_MethodReplacement() { @Override protected Object replaceHookedMethod(MethodHookParam methodHookParam) throws Throwable { @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm, int slot) { Log.d(TAG, "Set device id 2: " + SysHook.deviceId); return deviceId; } }); XposedHelpers.findAndHookMethod(ContextWrapper.class, "getPackageName", XC_MethodReplacement.returnConstant(GMS_PACKAGE_NAME)); XposedHelpers.findAndHookMethod(ContextWrapper.class, "getClassLoader", new XC_MethodHook() { @Override protected void afterHookedMethod(MethodHookParam param) throws Throwable { param.setResult(createModifiedClassLoader((ClassLoader) param.getResult())); @Hook("android.net.ConnectivityManager->getActiveNetworkInfo") public static NetworkInfo ConnectivityManager_getActiveNetworkInfo(ConnectivityManager cm) { return null; // null is a valid response } }); XposedHelpers.findAndHookMethod(TreeSet.class, "iterator", new XC_MethodHook() { @Override protected void beforeHookedMethod(MethodHookParam param) throws Throwable { NavigableMap map = (NavigableMap) XposedHelpers.getObjectField(param.thisObject, "m"); if (map == null) map = (NavigableMap) XposedHelpers.getObjectField(param.thisObject, "backingMap"); if (map == null) return; if (detectMapsSet(map.navigableKeySet().iterator())) { param.setResult(createMapsReplacementSet().iterator()); @Hook("java.util.regex.Pattern->matcher") @BackupIdentifier("PatternMatcher") public static Matcher Pattern_matcher(Pattern pattern, CharSequence cs) { OriginalMethod method = OriginalMethod.by("PatternMatcher"); if (cs instanceof String) { String s = (String) cs; if (s.contains("Xposed") || s.contains("xposed") || s.contains("XPosed") || s.contains("XPOSED")) return method.invoke(pattern, ""); if (s.contains("org.microg.gms.droidguard")) return method.invoke(pattern, s.replace("org.microg.gms.droidguard", "com.google.android.gms")); } return method.invoke(pattern, cs); } }); SysHook.done = true; @Hook("android.content.ContextWrapper->getPackageName") public static String ContextWrapper_getPackageName(Object o) { Log.d(TAG, "Set package name: " + GMS_PACKAGE_NAME); return GMS_PACKAGE_NAME; } @Hook("android.telephony.TelephonyManager->getSubscriberId") public static String TelephonyManager_getSubscriberId(TelephonyManager tm) { return subscriberId; @Hook("android.os.SystemProperties->getInt") @BackupIdentifier("SystemPropertiesGetInt") public static int SystemProperties_getInt(String key, int def) { if (key.equals("ro.debuggable") || key.equals("service.adb.root")) return 0; if (key.equals("ro.secure")) return 1; return OriginalMethod.by("SystemPropertiesGetInt").invokeStatic(key, def); } @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm) { return deviceId; @Hook("java.util.Arrays->asList") @BackupIdentifier("ArraysAsList") public static List Arrays_asList(Object[] objs) { Log.d(TAG, "Arrays->asList: "+Arrays.toString(objs)); if (detectLibrariesList(objs)) return OriginalMethod.by("ArraysAsList").invoke(null, new Object[]{getModifiedSystemSharedLibraries()}); return OriginalMethod.by("ArraysAsList").invoke(null, new Object[]{objs}); } @Hook("android.telephony.TelephonyManager->getDeviceId") public static String TelephonyManager_getDeviceId(TelephonyManager tm, int slot) { return deviceId; static boolean detectLibrariesList(Object[] list) { boolean isList = false; boolean wasModified = false; for (int i = 0; i < list.length; i++) { if (!(list[i] instanceof String)) return false; if ("com.android.location.provider".equals(list[i]) || "android.test.runner".equals(list[i])) isList = true; if ("com.google.widevine.software.drm".equals(list[i])) wasModified = true; } return isList && !wasModified; } @Hook("android.content.ContextWrapper->getPackageName") public static String ContextWrapper_getPackageName(Object o) { return GMS_PACKAGE_NAME; @Hook("android.app.ApplicationPackageManager->getSystemSharedLibraryNames") @BackupIdentifier("PackageManagerGetSystemSharedLibraryNames") public static String[] PackageManager_getSystemSharedLibraryNames(Object o) { Log.d(TAG, "Modified SystemSharedLibraries"); return getModifiedSystemSharedLibraries(); } static String[] getModifiedSystemSharedLibraries() { return new String[]{"android.test.runner", "com.android.future.usb.accessory", "com.android.location.provider", "com.android.media.remotedisplay", "com.android.mediadrm.signer", "com.google.android.maps", "com.google.widevine.software.drm", "com.qualcomm.qcrilhook", "com.qualcomm.qti.rcsservice", "com.quicinc.cneapiclient", "javax.obex", "org.apache.http.legacy"}; } @Hook("android.content.ContextWrapper->getClassLoader") Loading @@ -140,7 +163,7 @@ public class SysHook implements IXposedHookLoadPackage { return createModifiedClassLoader((ClassLoader) OriginalMethod.by("ContextWrapperClassLoader").invoke(o)); } private static ClassLoader createModifiedClassLoader(ClassLoader original) { static ClassLoader createModifiedClassLoader(ClassLoader original) { return new URLClassLoader(new URL[0], original) { @Override public String toString() { Loading @@ -158,22 +181,23 @@ public class SysHook implements IXposedHookLoadPackage { return originalMethod.invoke(set); } private static boolean detectMapsSet(Iterator iterator) { static boolean detectMapsSet(Iterator iterator) { boolean hasDgCache = false; boolean hasFrameworkRes = false; while (iterator.hasNext()) { Object o = iterator.next(); if (!(o instanceof String)) { return false; } String s = (String) o; if (s.contains("org.microg.gms") && s.contains(".apk")) { Log.d(TAG, "Detected maps set"); return true; Log.d(TAG, "mapdetect: " + s); if (s.contains("app_dg_cache")) hasDgCache = true; if (s.contains("framework-res.apk")) hasFrameworkRes = true; } } return false; return hasDgCache && hasFrameworkRes; } private static Set<String> createMapsReplacementSet() { static Set<String> createMapsReplacementSet() { Set<String> replacement = new TreeSet<>(); replacement.add("/data/app/com.google.android.gms-1/base.apk"); replacement.add("/data/app/com.google.android.gms-1/oat/" + odexArch + "/base.odex"); Loading