diff --git a/project/Libraries/DroidPlugin/build.gradle b/project/Libraries/DroidPlugin/build.gradle index 7252a4ee..3f983670 100644 --- a/project/Libraries/DroidPlugin/build.gradle +++ b/project/Libraries/DroidPlugin/build.gradle @@ -3,6 +3,23 @@ apply plugin: 'com.android.library' dependencies { compileOnly fileTree(dir: 'lib', include: '*.jar') implementation fileTree(dir: 'libs', include: '*.jar') + + implementation "com.android.support:support-v4:23.1.1" + implementation "com.android.support:gridlayout-v7:23.1.1" + implementation "com.android.support:cardview-v7:23.1.1" + implementation 'com.android.support:appcompat-v7:23.1.1' + implementation 'com.android.support:design:23.1.1' + + + //10.0解决黑名单问题 + //https://zhuanlan.zhihu.com/p/59455212 + //https://github.com/tiann/FreeReflection + api 'me.weishu:free_reflection:3.0.1' + + //https://github.com/Guolei1130/android_p_no_sdkapi_support + + //http://weishu.me/2018/06/07/free-reflection-above-android-p/ + } android { @@ -13,18 +30,24 @@ android { abortOnError false } - defaultConfig{ + defaultConfig { + +// packagingOptions { +// doNotStrip "/armeabi/.so" doNotStrip "/armeabi-v7a/.so" doNotStrip "/x86/.so" +// } // 建议改为自己的 packageName + .droidplugin_stub ,防止跟其它本插件使用者冲突 def authorityName = "com.morgoo.droidplugin_stub" - minSdkVersion 9 + minSdkVersion 21 versionCode 1 versionName '1.0' buildConfigField "String", "AUTHORITY_NAME", "\"${authorityName}\"" manifestPlaceholders = [ - authorityName:"${authorityName}", + authorityName: "${authorityName}", ] } + + } diff --git a/project/Libraries/DroidPlugin/project.properties b/project/Libraries/DroidPlugin/project.properties index 6e18427a..4ab12569 100644 --- a/project/Libraries/DroidPlugin/project.properties +++ b/project/Libraries/DroidPlugin/project.properties @@ -11,4 +11,4 @@ #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt # Project target. -target=android-21 +target=android-19 diff --git a/project/Libraries/DroidPlugin/src/main/AndroidManifest.xml b/project/Libraries/DroidPlugin/src/main/AndroidManifest.xml index b20527b3..5cb9858c 100644 --- a/project/Libraries/DroidPlugin/src/main/AndroidManifest.xml +++ b/project/Libraries/DroidPlugin/src/main/AndroidManifest.xml @@ -25,6 +25,7 @@ --> @@ -47,7 +48,9 @@ - + @@ -83,7 +86,9 @@ - + @@ -99,7 +104,9 @@ - + @@ -158,27 +165,73 @@ - - + + - - + + - + + + + + - + + + + + + + + + + + + + + + + android:authorities="${applicationId}.plugin.servicemanager" /> - - + android:theme="@android:style/Theme.Light.NoTitleBar"> + + @@ -206,6 +259,7 @@ -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin; @@ -27,7 +27,9 @@ import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; +import android.os.Build; import android.os.Environment; + import com.morgoo.helper.Log; import com.morgoo.helper.compat.SystemPropertiesCompat; @@ -78,7 +80,12 @@ public void uncaughtException(Thread thread, Throwable ex) { Date date = new Date(); String dateStr = SIMPLE_DATE_FORMAT1.format(date); - File file = new File(Environment.getExternalStorageDirectory(), String.format("PluginLog/CrashLog/CrashLog_%s_%s.log", dateStr, android.os.Process.myPid())); + File file = null; + if (Build.VERSION.SDK_INT >= 30) { + file = new File(mContext.getExternalCacheDir(), String.format("PluginLog/CrashLog/CrashLog_%s_%s.log", dateStr, android.os.Process.myPid())); + } else { + file = new File(Environment.getExternalStorageDirectory(), String.format("PluginLog/CrashLog/CrashLog_%s_%s.log", dateStr, android.os.Process.myPid())); + } if (!file.getParentFile().exists()) { file.getParentFile().mkdirs(); } diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/PluginApplication.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/PluginApplication.java index f1e39193..1189dd27 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/PluginApplication.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/PluginApplication.java @@ -25,6 +25,8 @@ import android.app.Application; import android.content.Context; +import me.weishu.reflection.Reflection; + /** * Created by Andy Zhang(zhangyong232@gmail.com) 2014/12/5. */ @@ -41,6 +43,7 @@ public void onCreate() { @Override protected void attachBaseContext(Context base) { + Reflection.unseal(base); PluginHelper.getInstance().applicationAttachBaseContext(base); super.attachBaseContext(base); } diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/am/BaseActivityManagerService.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/am/BaseActivityManagerService.java index 5616c3eb..92659bc5 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/am/BaseActivityManagerService.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/am/BaseActivityManagerService.java @@ -98,6 +98,7 @@ private class MyRemoteCallbackList extends RemoteCallbackList -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.core; @@ -48,29 +48,30 @@ public PluginClassLoader(String apkfile, String optimizedDirectory, String libra @Override protected Class loadClass(String className, boolean resolve) throws ClassNotFoundException { - - if (Build.MANUFACTURER != null && sPreLoader.contains(Build.MANUFACTURER.toUpperCase())) { - try { - /** - * FUCK QIKU! - * 这里适配奇酷手机青春版。 - * 因为奇酷手机自己加载了自己修改过的的Support V4库,在插件中也用了这个库的时候,ClassLoader会优先加载奇酷手机自带的Support V4库。 - * 原因在于,奇酷手机没有预加载插件中打的Support V4库。详情可以研究super.loadClass(className, resolve)标准实现 - * 但是这可能会导致类不兼容,出现java.lang.IncompatibleClassChangeError。因为插件编译时使用的插件的Support V4,而奇酷手机则使 - * 用的是它修改过的Support V4。 - * - * SO,在Class Loader加载某个Class的时候,我们优先从自己的ClassLoader中加载Class,如果找不到,再从Parent Class Loader中去加载。 - * 这样修改后,Class的加载顺序就跟系统的不一样了。 - * - */ - Class clazz = findClass(className); - if (clazz != null) { - return clazz; - } - } catch (ClassNotFoundException e) { - Log.e("PluginClassLoader", "UCK QIKU:error", e); + //不判断设备类型,优先加载自己的dex类 +// if (Build.MANUFACTURER != null && sPreLoader.contains(Build.MANUFACTURER.toUpperCase())) { + try { + /** + * FUCK QIKU! + * 这里适配奇酷手机青春版。 + * 因为奇酷手机自己加载了自己修改过的的Support V4库,在插件中也用了这个库的时候,ClassLoader会优先加载奇酷手机自带的Support V4库。 + * 原因在于,奇酷手机没有预加载插件中打的Support V4库。详情可以研究super.loadClass(className, resolve)标准实现 + * 但是这可能会导致类不兼容,出现java.lang.IncompatibleClassChangeError。因为插件编译时使用的插件的Support V4,而奇酷手机则使 + * 用的是它修改过的Support V4。 + * + * SO,在Class Loader加载某个Class的时候,我们优先从自己的ClassLoader中加载Class,如果找不到,再从Parent Class Loader中去加载。 + * 这样修改后,Class的加载顺序就跟系统的不一样了。 + * + */ + Class clazz = findClass(className); + if (clazz != null) { + return clazz; } + } catch (ClassNotFoundException e) { + //不打印 +// Log.i("PluginClassLoader", "UCK QIKU:error", e); } +// } return super.loadClass(className, resolve); } } diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/core/PluginProcessManager.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/core/PluginProcessManager.java index 6056a498..6083672a 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/core/PluginProcessManager.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/core/PluginProcessManager.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.core; @@ -37,6 +37,7 @@ import android.content.pm.PackageManager; import android.content.pm.ProviderInfo; import android.content.pm.ServiceInfo; +import android.os.Build; import android.os.Build.VERSION; import android.os.Build.VERSION_CODES; import android.os.Handler; @@ -169,14 +170,41 @@ public static ClassLoader getPluginClassLoader(String pkg) throws IllegalAccessE } + public static void removeSettingsProvider() { + if (Build.VERSION.SDK_INT >= 28) { + try { + Object object = ActivityThreadCompat.currentActivityThread(); + Object mProviderMapObj = FieldUtils.readField(object, "mProviderMap"); + MethodUtils.invokeMethod(mProviderMapObj, "clear"); + Object mProviderRefCountMap = FieldUtils.readField(object, "mProviderRefCountMap"); + MethodUtils.invokeMethod(mProviderRefCountMap, "clear"); + + Object sProviderHolder = FieldUtils.readStaticField(Class.forName("android.provider.Settings$Global"), "sProviderHolder"); + FieldUtils.writeField(sProviderHolder, "mContentProvider", null); + sProviderHolder = FieldUtils.readStaticField(Class.forName("android.provider.Settings$System"), "sProviderHolder"); + FieldUtils.writeField(sProviderHolder, "mContentProvider", null); + sProviderHolder = FieldUtils.readStaticField(Class.forName("android.provider.Settings$Secure"), "sProviderHolder"); + FieldUtils.writeField(sProviderHolder, "mContentProvider", null); + + } catch (Exception e) { + Log.e("Android28Helper", "removeSettingsProvider", e); + } + } + + } + public static void preLoadApk(Context hostContext, ComponentInfo pluginInfo) throws IOException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, PackageManager.NameNotFoundException, ClassNotFoundException { if (pluginInfo == null && hostContext == null) { return; } + if (pluginInfo != null && getPluginContext(pluginInfo.packageName) != null) { return; } + //https://github.com/DroidPluginTeam/DroidPlugin/issues/446 + removeSettingsProvider(); + /*添加插件的LoadedApk对象到ActivityThread.mPackages*/ boolean found = false; @@ -194,7 +222,7 @@ public static void preLoadApk(Context hostContext, ComponentInfo pluginInfo) thr } sPluginLoadedApkCache.put(pluginInfo.packageName, loadedApk); - /*添加ClassLoader LoadedApk.mClassLoader*/ + /*添加ClassLoader LoadedApk.mClassLoader*/ String optimizedDirectory = PluginDirHelper.getPluginDalvikCacheDir(hostContext, pluginInfo.packageName); String libraryPath = PluginDirHelper.getPluginNativeLibraryDir(hostContext, pluginInfo.packageName); @@ -209,7 +237,7 @@ public static void preLoadApk(Context hostContext, ComponentInfo pluginInfo) thr classloader = new PluginClassLoader(apk, optimizedDirectory, libraryPath, hostContext.getClassLoader().getParent()); } catch (Exception e) { } - if(classloader==null){ + if (classloader == null) { PluginDirHelper.cleanOptimizedDirectory(optimizedDirectory); classloader = new PluginClassLoader(apk, optimizedDirectory, libraryPath, hostContext.getClassLoader().getParent()); } @@ -365,11 +393,14 @@ private static Context getBaseContext(Context c) { sSkipService.add("tv_input"); sSkipService.add("jobscheduler"); sSkipService.add("sensorhub"); - + //NSDManager init初始化anr的问题 sSkipService.add("servicediscovery"); // sSkipService.add("usagestats"); + //P Q + sSkipService.add("color_display"); +// sSkipService.add("network_watchlist"); } @@ -413,8 +444,19 @@ private static void fakeSystemServiceInner(Context hostContext, Context targetCo Context originContext = getBaseContext(hostContext); Object mServiceCache = FieldUtils.readField(originContext, "mServiceCache"); + + Log.i(TAG, "mServiceCache class is %s", mServiceCache.getClass()); + if (mServiceCache instanceof List) { + Log.i(TAG, "mServiceCache instanceof List"); ((List) mServiceCache).clear(); + } else if (mServiceCache instanceof Object[]) { + //P Q + Log.i(TAG, "mServiceCache instanceof Object[]"); + int length = ((Object[]) mServiceCache).length; + mServiceCache = new Object[length]; + //先写个空集合 + FieldUtils.writeField(originContext, "mServiceCache", mServiceCache); } for (Object key : sSYSTEM_SERVICE_MAP.keySet()) { @@ -424,17 +466,18 @@ private static void fakeSystemServiceInner(Context hostContext, Context targetCo Object serviceFetcher = sSYSTEM_SERVICE_MAP.get(key); try { + //Log.i(TAG, "serviceFetcher class is " + (serviceFetcher != null ? serviceFetcher.getClass().getName() : "null") + " and value is " + serviceFetcher); Method getService = serviceFetcher.getClass().getMethod("getService", baseContext.getClass()); getService.invoke(serviceFetcher, originContext); } catch (InvocationTargetException e) { Throwable cause = e.getCause(); if (cause != null) { - Log.w(TAG, "Fake system service faile", e); + Log.w(TAG, "Fake system service 1 faile ", e); } else { - Log.w(TAG, "Fake system service faile", e); + Log.w(TAG, "Fake system service 2 faile ", e); } } catch (Exception e) { - Log.w(TAG, "Fake system service faile", e); + Log.w(TAG, "Fake system service 3 faile ", e); } } mServiceCache = FieldUtils.readField(originContext, "mServiceCache"); diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/HookFactory.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/HookFactory.java index 138a3ceb..09a59064 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/HookFactory.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/HookFactory.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook; @@ -50,10 +50,12 @@ import com.morgoo.droidplugin.hook.binder.IWifiManagerBinderHook; import com.morgoo.droidplugin.hook.binder.IWindowManagerBinderHook; import com.morgoo.droidplugin.hook.proxy.IActivityManagerHook; +import com.morgoo.droidplugin.hook.proxy.IActivityTaskManagerHook; import com.morgoo.droidplugin.hook.proxy.IPackageManagerHook; import com.morgoo.droidplugin.hook.proxy.InstrumentationHook; import com.morgoo.droidplugin.hook.proxy.LibCoreHook; import com.morgoo.droidplugin.hook.proxy.PluginCallbackHook; +import com.morgoo.droidplugin.hook.proxy.WebViewFactoryProviderHook; import com.morgoo.droidplugin.hook.xhook.SQLiteDatabaseHook; import com.morgoo.helper.Log; import com.morgoo.helper.utils.ProcessUtils; @@ -124,6 +126,7 @@ public void installHook(Hook hook, ClassLoader cl) { public final void installHook(Context context, ClassLoader classLoader) throws Throwable { if (ProcessUtils.isMainProcess(context)) { + installHook(new IActivityTaskManagerHook(context), classLoader); installHook(new IActivityManagerHook(context), classLoader); installHook(new IPackageManagerHook(context), classLoader); } else { @@ -132,16 +135,20 @@ public final void installHook(Context context, ClassLoader classLoader) throws T installHook(new ISearchManagerBinderHook(context), classLoader); //for INotificationManager installHook(new INotificationManagerBinderHook(context), classLoader); - installHook(new IMountServiceBinderHook(context), classLoader); + if (VERSION.SDK_INT < VERSION_CODES.P) { + //先让这个不要抛出异常先 + installHook(new IMountServiceBinderHook(context), classLoader); + } installHook(new IAudioServiceBinderHook(context), classLoader); installHook(new IContentServiceBinderHook(context), classLoader); installHook(new IWindowManagerBinderHook(context), classLoader); if (VERSION.SDK_INT > VERSION_CODES.LOLLIPOP_MR1) { installHook(new IGraphicsStatsBinderHook(context), classLoader); } -// if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { -// installHook(new WebViewFactoryProviderHook(context), classLoader); -// } + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + //这个 基本废弃 + //installHook(new WebViewFactoryProviderHook(context), classLoader); + } if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { installHook(new IMediaRouterServiceBinderHook(context), classLoader); } @@ -186,6 +193,7 @@ public final void installHook(Context context, ClassLoader classLoader) throws T if (VERSION.SDK_INT >= VERSION_CODES.M) { installHook(new IAppOpsServiceBinderHook(context), classLoader); } + installHook(new IActivityTaskManagerHook(context), classLoader); installHook(new IActivityManagerHook(context), classLoader); installHook(new IPackageManagerHook(context), classLoader); installHook(new PluginCallbackHook(context), classLoader); diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/IAppOpsServiceBinderHook.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/IAppOpsServiceBinderHook.java index 68be19d3..09d13ded 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/IAppOpsServiceBinderHook.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/IAppOpsServiceBinderHook.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.binder; import android.content.Context; @@ -26,12 +26,13 @@ import com.morgoo.droidplugin.hook.BaseHookHandle; import com.morgoo.droidplugin.hook.handle.IAppOpsServiceHookHandle; +import com.morgoo.droidplugin.reflect.MethodUtils; import com.morgoo.helper.compat.IAppOpsServiceCompat; /** * Created by Andy Zhang(zhangyong232@gmail.com) on on 16/5/11. */ -public class IAppOpsServiceBinderHook extends BinderHook{ +public class IAppOpsServiceBinderHook extends BinderHook { private static final String SERVICE_NAME = Context.APP_OPS_SERVICE; @@ -45,6 +46,13 @@ Object getOldObj() throws Exception { return IAppOpsServiceCompat.asInterface(iBinder); } + @Override + protected void onInstall(ClassLoader classLoader) throws Throwable { + super.onInstall(classLoader); + //Class aClass = Class.forName("com.android.server.wm.ActivityTaskManagerService"); + //MethodUtils.invokeStaticMethod(aClass, "checkCallingPermission", String.class); + } + @Override public String getServiceName() { return SERVICE_NAME; diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/MyServiceManager.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/MyServiceManager.java index b9056b82..67fd2460 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/MyServiceManager.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/MyServiceManager.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.binder; @@ -44,10 +44,14 @@ public static void addOriginService(String serviceName, IBinder service) { mOriginServiceCache.put(serviceName, service); } - static void addProxiedServiceCache(String serviceName, IBinder proxyService) { + static void addProxiedServiceCache(String serviceName, IBinder proxyService) { mProxiedServiceCache.put(serviceName, proxyService); } + static IBinder getProxiedServiceCache(String serviceName) { + return mProxiedServiceCache.get(serviceName); + } + static Object getProxiedObj(String servicename) { return mProxiedObjCache.get(servicename); } diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/ServiceManagerCacheBinderHook.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/ServiceManagerCacheBinderHook.java index 8f0151ee..50129d51 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/ServiceManagerCacheBinderHook.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/binder/ServiceManagerCacheBinderHook.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.binder; @@ -31,6 +31,7 @@ import com.morgoo.droidplugin.hook.HookedMethodHandler; import com.morgoo.droidplugin.reflect.FieldUtils; import com.morgoo.droidplugin.reflect.Utils; +import com.morgoo.helper.Log; import com.morgoo.helper.MyProxy; import com.morgoo.helper.compat.ServiceManagerCompat; @@ -48,6 +49,8 @@ public class ServiceManagerCacheBinderHook extends Hook implements InvocationHandler { + private final static String TAG = ServiceManagerCacheBinderHook.class.getSimpleName(); + private String mServiceName; public ServiceManagerCacheBinderHook(Context hostContext, String servicename) { @@ -60,6 +63,7 @@ public ServiceManagerCacheBinderHook(Context hostContext, String servicename) { @Override protected void onInstall(ClassLoader classLoader) throws Throwable { Object sCacheObj = FieldUtils.readStaticField(ServiceManagerCompat.Class(), "sCache"); + //Log.i(TAG, "sCacheObj class is " + sCacheObj.getClass()); if (sCacheObj instanceof Map) { Map sCache = (Map) sCacheObj; Object Obj = sCache.get(mServiceName); @@ -68,6 +72,7 @@ protected void onInstall(ClassLoader classLoader) throws Throwable { //但是这样有缺陷。 throw new RuntimeException("Can not install binder hook for " + mServiceName); } else { + Log.i(TAG, "mServiceName is " + mServiceName); sCache.remove(mServiceName); IBinder mServiceIBinder = ServiceManagerCompat.getService(mServiceName); if (mServiceIBinder == null) { @@ -76,6 +81,7 @@ protected void onInstall(ClassLoader classLoader) throws Throwable { } } if (mServiceIBinder != null) { + //Log.i(TAG, "mServiceIBinder is " + mServiceIBinder.getClass()); MyServiceManager.addOriginService(mServiceName, mServiceIBinder); Class clazz = mServiceIBinder.getClass(); List> interfaces = Utils.getAllInterfaces(clazz); @@ -97,7 +103,9 @@ public Object invoke(Object proxy, Method method, Object[] args) throws Throwabl return method.invoke(originService, args); } HookedMethodHandler hookedMethodHandler = mHookHandles.getHookedMethodHandler(method); + Log.i(TAG, "hookedMethodHandler is " + hookedMethodHandler); if (hookedMethodHandler != null) { + Log.i(TAG, "hookedMethodHandler doHookInner method is " + method.getName()); return hookedMethodHandler.doHookInner(originService, method, args); } else { return method.invoke(originService, args); diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IActivityManagerHookHandle.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IActivityManagerHookHandle.java index 7c724571..ca692f45 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IActivityManagerHookHandle.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IActivityManagerHookHandle.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.handle; @@ -48,6 +48,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.RemoteException; +import android.os.UserHandle; import android.text.TextUtils; import com.morgoo.droidplugin.PluginManagerService; @@ -71,6 +72,7 @@ import java.lang.reflect.Method; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Random; @@ -87,6 +89,8 @@ public IActivityManagerHookHandle(Context hostContext) { @Override protected void init() { + //android Q + sHookedMethodHandlers.put("activityTopResumedStateLost", new activityTopResumedStateLost(mHostContext)); sHookedMethodHandlers.put("startActivity", new startActivity(mHostContext)); sHookedMethodHandlers.put("startActivityAsUser", new startActivityAsUser(mHostContext)); sHookedMethodHandlers.put("startActivityAsCaller", new startActivityAsCaller(mHostContext)); @@ -151,6 +155,21 @@ protected void init() { } + //android Q + private static class activityTopResumedStateLost extends ReplaceCallingPackageHookedMethodHandler { + public activityTopResumedStateLost(Context hostContext) { + super(hostContext); + } + + @Override + protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { + Log.i(TAG, "activityTopResumedStateLost.beforeInvoke.method:" + (method != null ? method.getName() : "null")); + Log.i(TAG, "activityTopResumedStateLost.beforeInvoke.args." + Arrays.toString(args)); + return super.beforeInvoke(receiver, method, args); + } + } + + private static class startActivity extends ReplaceCallingPackageHookedMethodHandler { public startActivity(Context hostContext) { @@ -202,6 +221,20 @@ protected boolean doReplaceIntentForStartActivityAPIHigh(Object[] args) throws R args[intentOfArgIndex] = newIntent; args[1] = mHostContext.getPackageName(); + + if (args[args.length - 1] != null) { + Class aClass = args[args.length - 1].getClass(); + Log.i(TAG, "last agrs class is " + aClass); + if (args[args.length - 1] instanceof Integer) { + try { + UserHandle owner = (UserHandle) FieldUtils.readStaticField(UserHandle.class, "OWNER"); + args[args.length - 1] = MethodUtils.invokeMethod(owner, "getCallingUserId"); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } else { Log.w(TAG, "startActivity,replace selectProxyActivity fail"); } @@ -519,6 +552,8 @@ public registerReceiver(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { + + Log.i(TAG, "registerReceiver--->beforeInvoke"); //API 2.3 /* public Intent registerReceiver(IApplicationThread caller, IIntentReceiver receiver, IntentFilter filter, @@ -533,11 +568,16 @@ protected boolean beforeInvoke(Object receiver, Method method, Object[] args) th /* public Intent registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String requiredPermission, int userId) throws RemoteException;*/ + //Q + /* public Intent registerReceiver(IApplicationThread caller, String callerPackage, + IIntentReceiver receiver, IntentFilter filter, String permission, int userId, + int flags)*/ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) { if (args != null && args.length > 0) { for (int index = 0; index < args.length; index++) { if (args[index] instanceof String) { String callerPackage = (String) args[index]; + Log.i(TAG, "registerReceiver--->beforeInvoke.callerPackage:" + callerPackage); if (isPackagePlugin(callerPackage)) { args[index] = mHostContext.getPackageName(); } @@ -762,9 +802,9 @@ public getServices(Context hostContext) { @Override protected void afterInvoke(Object receiver, Method method, Object[] args, Object invokeResult) throws Throwable { //api 2.3,15,16,17,18 - /*public List getServices(int maxNum, int flags) throws RemoteException;*/ + /*public List getServices(int maxNum, int flags) throws RemoteException;*/ //API 19,21 - /*public List getServices(int maxNum, int flags) throws RemoteException;*/ + /*public List getServices(int maxNum, int flags) throws RemoteException;*/ if (invokeResult != null && invokeResult instanceof List) { List objectList = (List) invokeResult; for (Object obj : objectList) { @@ -1165,7 +1205,7 @@ public peekService(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { //API 2.3, 15, 16, 17, 18, 19, 21 - /* public IBinder peekService(Intent service, String resolvedType) throws RemoteException;*/ + /* public IBinder peekService(Intent service, String resolvedType) throws RemoteException;*/ replaceFirstServiceIntentOfArgs(args); return super.beforeInvoke(receiver, method, args); } @@ -1204,7 +1244,7 @@ public backupAgentCreated(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { //API 2.3,15,16,17,18,19, 21 - /* public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;*/ + /* public void backupAgentCreated(String packageName, IBinder agent) throws RemoteException;*/ final int index = 0; if (args != null && args.length > index) { if (args[index] != null && args[index] instanceof String) { @@ -1227,7 +1267,7 @@ public unbindBackupAgent(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { //API 2.3,15,16,17,18,19, 21 - /* public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;*/ + /* public void unbindBackupAgent(ApplicationInfo appInfo) throws RemoteException;*/ final int index = 0; if (args != null && args.length > index) { if (args[index] != null && args[index] instanceof ApplicationInfo) { @@ -1250,7 +1290,7 @@ public killApplicationProcess(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { //API 2.3,15,16,17,18,19, 21 - /* public void killApplicationProcess(String processName, int uid) throws RemoteException;*/ + /* public void killApplicationProcess(String processName, int uid) throws RemoteException;*/ final int index = 0; if (args != null && args.length > index) { @@ -1303,7 +1343,7 @@ public getActivityClassForToken(Context hostContext) { } //API 2.3,15,16,17,18,19, 21 - /* public ComponentName getActivityClassForToken(IBinder token) throws RemoteException;*/ + /* public ComponentName getActivityClassForToken(IBinder token) throws RemoteException;*/ //FIXME I don't know what function of this,just hook it. //通过token拿Activity?搞不懂,不改。 } @@ -1612,7 +1652,7 @@ public killBackgroundProcesses(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { //API 2.3,15,16 - /*public void killBackgroundProcesses(final String packageName) throws RemoteException;*/ + /*public void killBackgroundProcesses(final String packageName) throws RemoteException;*/ //API 17,18,19,21 /* public void killBackgroundProcesses(final String packageName, int userId) @@ -1665,6 +1705,7 @@ public getRunningAppProcesses(Context hostContext) { @Override protected void afterInvoke(Object receiver, Method method, Object[] args, Object invokeResult) throws Throwable { + Log.i(TAG, "getRunningAppProcesses>>>>afterInvoke"); //2.3,15,16,17,18,19,21 /* public List getRunningAppProcesses() throws RemoteException;*/ @@ -1945,7 +1986,7 @@ public getPackageScreenCompatMode(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { - /* public int getPackageScreenCompatMode(String packageName) throws RemoteException;*/ + /* public int getPackageScreenCompatMode(String packageName) throws RemoteException;*/ //我也不知道这个函数是干嘛的,不过既然写了,我们就改一下。 //因为如果万一插件调用了这个函数,则会传插件自己的包名,而此插件并未被安装。就这样调用原来函数传给系统,是会出问题的。所以改成宿主程序的包名。 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { @@ -2001,7 +2042,7 @@ public getPackageAskScreenCompat(Context hostContext) { @Override protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { //API 15, 16, 17, 18, 19, 21 - /* public boolean getPackageAskScreenCompat(String packageName) throws RemoteException;*/ + /* public boolean getPackageAskScreenCompat(String packageName) throws RemoteException;*/ //我也不知道这个函数是干嘛的,不过既然写了,我们就改一下。 //因为如果万一插件调用了这个函数,则会传插件自己的包名,而此插件并未被安装。就这样调用原来函数传给系统,是会出问题的。所以改成宿主程序的包名。 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) { diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IAppOpsServiceHookHandle.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IAppOpsServiceHookHandle.java index 8f0baec6..47236096 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IAppOpsServiceHookHandle.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/IAppOpsServiceHookHandle.java @@ -1,32 +1,38 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.handle; +import android.app.AppOpsManager; import android.content.Context; +import android.util.Log; import com.morgoo.droidplugin.hook.BaseHookHandle; import com.morgoo.droidplugin.hook.HookedMethodHandler; +//import com.morgoo.helper.Log; import com.morgoo.helper.compat.IAppOpsServiceCompat; +import java.lang.reflect.Method; +import java.util.Arrays; + /** * Created by Andy Zhang(zhangyong232@gmail.com) on on 16/5/11. */ @@ -59,25 +65,25 @@ protected void init() { // void setUserRestrictions(in Bundle restrictions, int userHandle); // void removeUser(int userHandle); // } - sHookedMethodHandlers.put("checkOperation",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("noteOperation",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("startOperation",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("finishOperation",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("startWatchingMode",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("stopWatchingMode",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("getToken",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("permissionToOpCode",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("noteProxyOperation",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("checkPackage",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("getPackagesForOps",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("getOpsForPackage",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("setUidMode",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("setMode",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("resetAllModes",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("checkAudioOperation",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("setAudioRestriction",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("setUserRestrictions",new MyBaseHandler(mHostContext)); - sHookedMethodHandlers.put("removeUser",new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("checkOperation", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("noteOperation", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("startOperation", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("finishOperation", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("startWatchingMode", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("stopWatchingMode", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("getToken", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("permissionToOpCode", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("noteProxyOperation", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("checkPackage", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("getPackagesForOps", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("getOpsForPackage", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("setUidMode", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("setMode", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("resetAllModes", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("checkAudioOperation", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("setAudioRestriction", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("setUserRestrictions", new MyBaseHandler(mHostContext)); + sHookedMethodHandlers.put("removeUser", new MyBaseHandler(mHostContext)); addAllMethodFromHookedClass(); } @@ -95,5 +101,41 @@ private static class MyBaseHandler extends ReplaceCallingPackageHookedMethodHand public MyBaseHandler(Context context) { super(context); } + + @Override + protected boolean beforeInvoke(Object receiver, Method method, Object[] args) throws Throwable { + // final int mode = getAppOpsService().noteOperation(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, + // callingUid, callingPackage); + /** + * ActivityStarter.java + * + * //shouldAbortBackgroundActivityStart 方法里面的 + * + * // don't abort if the callingUid has SYSTEM_ALERT_WINDOW permission + * if (mService.hasSystemAlertWindowPermission(callingUid, callingPid, callingPackage)) { + * Slog.w(TAG, "Background activity start for " + callingPackage + * + " allowed because SYSTEM_ALERT_WINDOW permission is granted."); + * return false; + * } + * + * //ActivityTaskManagerService.java + * boolean hasSystemAlertWindowPermission(int callingUid, int callingPid, String callingPackage) { + * final int mode = getAppOpsService().noteOperation(AppOpsManager.OP_SYSTEM_ALERT_WINDOW, + * callingUid, callingPackage); + * if (mode == AppOpsManager.MODE_DEFAULT) { + * return checkPermission(Manifest.permission.SYSTEM_ALERT_WINDOW, callingPid, callingUid) + * == PERMISSION_GRANTED; + * } + * return mode == AppOpsManager.MODE_ALLOWED; + * } + */ + Log.i("MyBaseHandler", "method:" + method.getName()); + if ("noteOperation".equals(method.getName())) { + Log.i("MyBaseHandler", "args:" + Arrays.toString(args)); + //认为有悬浮权限 + setFakedResult(AppOpsManager.MODE_ALLOWED); + } + return super.beforeInvoke(receiver, method, args); + } } } diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginCallback.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginCallback.java index 17f5243a..0f66891d 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginCallback.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginCallback.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.handle; @@ -32,6 +32,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Message; +import android.util.ArrayMap; import com.morgoo.droidplugin.core.Env; import com.morgoo.droidplugin.core.PluginProcessManager; @@ -40,6 +41,11 @@ import com.morgoo.droidplugin.reflect.FieldUtils; import com.morgoo.droidplugin.stub.ShortcutProxyActivity; import com.morgoo.helper.Log; +import com.morgoo.helper.compat.ActivityThreadCompat; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.util.List; public class PluginCallback implements Handler.Callback { @@ -226,6 +232,9 @@ public boolean isEnable() { public boolean handleMessage(Message msg) { long b = System.currentTimeMillis(); try { + + Log.i(TAG, "PluginCallback.handleMessage msg.what:%d", msg.what); + if (!mEnable) { return false; } @@ -241,9 +250,10 @@ public boolean handleMessage(Message msg) { } } - if (msg.what == LAUNCH_ACTIVITY) { + if (msg.what == LAUNCH_ACTIVITY || msg.what == 159/* >28 */) { return handleLaunchActivity(msg); - } /*else if (msg.what == INSTALL_PROVIDER) { + } + /*else if (msg.what == INSTALL_PROVIDER) { return handleInstallProvider(msg); } else if (msg.what == CREATE_BACKUP_AGENT) { //TODO 处理CREATE_BACKUP_AGENT @@ -349,10 +359,108 @@ public boolean handleMessage(Message msg) { // return false; // } + + private boolean handleActivity(Message msg) { + // 这里简单起见,直接取出TargetActivity; + try { + Object mClientTransaction = msg.obj; + //https://blog.csdn.net/wby371427/article/details/103447375 + //https://www.cnblogs.com/Jax/p/9521305.html + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + //获取mClientTransaction中的List mActivityCallbacks + Field mactivityCallbacks = mClientTransaction.getClass().getDeclaredField("mActivityCallbacks"); + mactivityCallbacks.setAccessible(true); + List mActivityCallbacks = (List) mactivityCallbacks.get(mClientTransaction); + if (mActivityCallbacks.size() == 0) { + return false; + } + Class mLaunchActivityItemClass = Class.forName("android.app.servertransaction.LaunchActivityItem"); + Object mLaunchActivityItem = mActivityCallbacks.get(0); + //拿到LaunchActivityItem中的Intent + Field mIntentField = mLaunchActivityItemClass.getDeclaredField("mIntent"); + mIntentField.setAccessible(true); + Intent stubIntent = (Intent) mIntentField.get(mLaunchActivityItem); + + Intent targetIntent = stubIntent.getParcelableExtra(Env.EXTRA_TARGET_INTENT); + if (targetIntent != null) { + mIntentField.setAccessible(true); + mIntentField.set(mLaunchActivityItem, targetIntent); + } + } + } catch (Exception e) { + e.printStackTrace(); + } + if (mCallback != null) { + return mCallback.handleMessage(msg); + } else { + return false; + } + } + private boolean handleLaunchActivity(Message msg) { try { + //这逻辑在真机不行,注释算了 +// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P + 1) { +// //android.app.servertransaction.TopResumedActivityChangeItem +// //不处理 +// if (mCallback != null) { +// return mCallback.handleMessage(msg); +// } else { +// return false; +// } +// } Object obj = msg.obj; - Intent stubIntent = (Intent) FieldUtils.readField(obj, "intent"); + Intent stubIntent = null; + Object mLaunchActivityItemP = null; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) { + Object mClientTransaction = msg.obj; + Log.i(TAG, "mClientTransaction>>>" + mClientTransaction.getClass()); + //获取mClientTransaction中的List mActivityCallbacks + Field mactivityCallbacks = mClientTransaction.getClass().getDeclaredField("mActivityCallbacks"); + mactivityCallbacks.setAccessible(true); + List mActivityCallbacks = (List) mactivityCallbacks.get(mClientTransaction); + Log.i(TAG, "mactivityCallbacks>>>" + mActivityCallbacks); + if (mActivityCallbacks == null || mActivityCallbacks.size() == 0) { + if (mCallback != null) { + return mCallback.handleMessage(msg); + } else { + return false; + } + } + Class mLaunchActivityItemClass = Class.forName("android.app.servertransaction.LaunchActivityItem"); + mLaunchActivityItemP = mActivityCallbacks.get(0); + Log.i(TAG, "mLaunchActivityItemP>>>" + mLaunchActivityItemP.getClass()); + if ("android.app.servertransaction.TopResumedActivityChangeItem".equals(mLaunchActivityItemP.getClass().getName())) { + //https://cs.android.com/android/platform/superproject/+/master:frameworks/base/core/java/android/app/servertransaction/TopResumedActivityChangeItem.java;bpv=0;bpt=1 + //android Q 改为:android.app.servertransaction.TopResumedActivityChangeItem + //Class mTopResumedActivityChangeItem = Class.forName("android.app.servertransaction.TopResumedActivityChangeItem"); + throw new RuntimeException("Android Q 的 TopResumedActivityChangeItem 没有 mIntent"); + } else if ("android.app.servertransaction.NewIntentItem".equals(mLaunchActivityItemP.getClass().getName())) { + // private List mIntents; + Field mIntentLists = mLaunchActivityItemP.getClass().getDeclaredField("mIntents"); + mIntentLists.setAccessible(true); + List intentLists = (List) mIntentLists.get(mLaunchActivityItemP); + stubIntent = (Intent) intentLists.get(0); + } else { + //拿到LaunchActivityItem中的Intent + Field mIntentField = mLaunchActivityItemClass.getDeclaredField("mIntent"); + mIntentField.setAccessible(true); + stubIntent = (Intent) mIntentField.get(mLaunchActivityItemP); + } + + if (stubIntent != null) { + Log.i(TAG, "stubIntent>>>" + stubIntent.getClass() + "," + stubIntent.toString()); + } +// Intent targetIntent = stubIntent.getParcelableExtra(Env.EXTRA_TARGET_INTENT); +// if (targetIntent != null) { +// mIntentField.setAccessible(true); +// mIntentField.set(mLaunchActivityItemP, targetIntent); +// } + } + if (stubIntent == null) { + stubIntent = (Intent) FieldUtils.readField(obj, "intent"); + Log.i(TAG, "stubIntent null>>>" + stubIntent.getClass() + "," + stubIntent.toString()); + } //ActivityInfo activityInfo = (ActivityInfo) FieldUtils.readField(obj, "activityInfo", true); stubIntent.setExtrasClassLoader(mHostContext.getClassLoader()); Intent targetIntent = stubIntent.getParcelableExtra(Env.EXTRA_TARGET_INTENT); @@ -360,12 +468,15 @@ private boolean handleLaunchActivity(Message msg) { // 也会带上一个EXTRA_TARGET_INTENT的数据,就会导致这里误以为是启动插件Activity,所以这里要先做一个判断。 // 之前ShortcutProxyActivity错误复用了key,但是为了兼容,所以这里就先这么判断吧。 if (targetIntent != null && !isShortcutProxyActivity(stubIntent)) { + + Log.i(TAG, "targetIntent >>>" + targetIntent.getClass() + "," + targetIntent.toString()); + IPackageManagerHook.fixContextPackageManager(mHostContext); ComponentName targetComponentName = targetIntent.resolveActivity(mHostContext.getPackageManager()); ActivityInfo targetActivityInfo = PluginManager.getInstance().getActivityInfo(targetComponentName, 0); if (targetActivityInfo != null) { - if (targetComponentName != null && targetComponentName.getClassName().startsWith("")) { + if (targetComponentName != null && targetComponentName.getClassName().startsWith(".")) { targetIntent.setClassName(targetComponentName.getPackageName(), targetComponentName.getPackageName() + targetComponentName.getClassName()); } @@ -406,6 +517,13 @@ private boolean handleLaunchActivity(Message msg) { } } + Object activityClientRecordObj = null; + Field mActivities = ActivityThreadCompat.currentActivityThread().getClass().getDeclaredField("mActivities"); + mActivities.setAccessible(true); + ArrayMap mActivitiesArrayMap = (ArrayMap) mActivities.get(ActivityThreadCompat.currentActivityThread()); + for (Object o : mActivitiesArrayMap.keySet()) { + activityClientRecordObj = mActivitiesArrayMap.get(o); + } if (!success) { Intent newTargetIntent = new Intent(); newTargetIntent.setComponent(targetIntent.getComponent()); @@ -413,12 +531,78 @@ private boolean handleLaunchActivity(Message msg) { if (stubActivityInfo != null) { newTargetIntent.putExtra(Env.EXTRA_STUB_INFO, stubActivityInfo); } - FieldUtils.writeDeclaredField(msg.obj, "intent", newTargetIntent); + //FieldUtils.writeDeclaredField(msg.obj, "intent", newTargetIntent); + if (mLaunchActivityItemP != null) { + if ("android.app.servertransaction.NewIntentItem".equals(mLaunchActivityItemP.getClass().getName())) { +// if (activityClientRecordObj != null) { +// Field intent = activityClientRecordObj.getClass().getDeclaredField("intent"); +// intent.setAccessible(true); +// intent.set(activityClientRecordObj, newTargetIntent); +// } + //构建替换intent + Field mReferrerField = stubIntent.getClass().getDeclaredField("mReferrer"); + mReferrerField.setAccessible(true); + String mReferrer = (String) mReferrerField.get(stubIntent); + Constructor constructor = stubIntent.getClass().getConstructor(Intent.class, String.class); + constructor.setAccessible(true); + Object newIntent = constructor.newInstance(targetIntent, mReferrer); + //重新赋值回去 + Field mIntentListFields = mLaunchActivityItemP.getClass().getDeclaredField("mIntents"); + mIntentListFields.setAccessible(true); + List intentLists = (List) mIntentListFields.get(mLaunchActivityItemP); + intentLists.clear(); + intentLists.add(newIntent); + mIntentListFields.set(mLaunchActivityItemP, intentLists); + } else { + FieldUtils.writeDeclaredField(mLaunchActivityItemP, "mIntent", newTargetIntent); + } + } else { + FieldUtils.writeDeclaredField(msg.obj, "intent", newTargetIntent); + } } else { - FieldUtils.writeDeclaredField(msg.obj, "intent", targetIntent); + //FieldUtils.writeDeclaredField(msg.obj, "intent", targetIntent); + if (mLaunchActivityItemP != null) { + if ("android.app.servertransaction.NewIntentItem".equals(mLaunchActivityItemP.getClass().getName())) { +// if (activityClientRecordObj != null) { +// Field intent = activityClientRecordObj.getClass().getDeclaredField("intent"); +// intent.setAccessible(true); +// intent.set(activityClientRecordObj, targetIntent); +// } + //构建替换intent + Field mReferrerField = stubIntent.getClass().getDeclaredField("mReferrer"); + mReferrerField.setAccessible(true); + String mReferrer = (String) mReferrerField.get(stubIntent); + Constructor constructor = stubIntent.getClass().getConstructor(Intent.class, String.class); + constructor.setAccessible(true); + Object newIntent = constructor.newInstance(targetIntent, mReferrer); + //重新赋值回去 + Field mIntentListFields = mLaunchActivityItemP.getClass().getDeclaredField("mIntents"); + mIntentListFields.setAccessible(true); + List intentLists = (List) mIntentListFields.get(mLaunchActivityItemP); + intentLists.clear(); + intentLists.add(newIntent); + mIntentListFields.set(mLaunchActivityItemP, intentLists); + } else { + FieldUtils.writeDeclaredField(mLaunchActivityItemP, "mIntent", targetIntent); + } + } else { + FieldUtils.writeDeclaredField(msg.obj, "intent", targetIntent); + } + } + //FieldUtils.writeDeclaredField(msg.obj, "activityInfo", targetActivityInfo); + if (mLaunchActivityItemP != null) { + if ("android.app.servertransaction.NewIntentItem".equals(mLaunchActivityItemP.getClass().getName())) { + if (activityClientRecordObj != null) { + Field activityInfoFiled = activityClientRecordObj.getClass().getDeclaredField("activityInfo"); + activityInfoFiled.setAccessible(true); + activityInfoFiled.set(activityClientRecordObj, targetActivityInfo); + } + } else { + FieldUtils.writeDeclaredField(mLaunchActivityItemP, "mInfo", targetActivityInfo); + } + } else { + FieldUtils.writeDeclaredField(msg.obj, "activityInfo", targetActivityInfo); } - FieldUtils.writeDeclaredField(msg.obj, "activityInfo", targetActivityInfo); - Log.i(TAG, "handleLaunchActivity OK"); } else { Log.e(TAG, "handleLaunchActivity oldInfo==null"); @@ -446,7 +630,7 @@ private boolean isShortcutProxyActivity(Intent targetIntent) { ResolveInfo info = pm.resolveActivity(targetIntent, 0); if (info != null) { String name = info.activityInfo.name; - if (name != null && name.startsWith("")) { + if (name != null && name.startsWith(".")) { name = info.activityInfo.packageName + info.activityInfo.name; } return ShortcutProxyActivity.class.getName().equals(name); diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginInstrumentation.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginInstrumentation.java index 2d82b602..688a7cbd 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginInstrumentation.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/PluginInstrumentation.java @@ -1,29 +1,30 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.handle; import android.annotation.TargetApi; import android.app.Activity; +import android.app.AppComponentFactory; import android.app.Application; import android.app.Instrumentation; import android.content.ContentResolver; @@ -36,7 +37,9 @@ import android.graphics.drawable.Drawable; import android.os.Build; import android.os.Bundle; +import android.os.IBinder; import android.os.RemoteException; +import android.os.UserHandle; import android.text.TextUtils; import com.morgoo.droidplugin.am.RunningActivities; @@ -47,9 +50,12 @@ import com.morgoo.droidplugin.hook.proxy.IPackageManagerHook; import com.morgoo.droidplugin.pm.PluginManager; import com.morgoo.droidplugin.reflect.FieldUtils; +import com.morgoo.droidplugin.reflect.MethodUtils; import com.morgoo.helper.Log; +import com.morgoo.helper.compat.ActivityThreadCompat; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; /** * Created by Andy Zhang(zhangyong232@gmail.com) on 2014/12/5. @@ -318,5 +324,56 @@ public void callActivityOnNewIntent(Activity activity, Intent intent) { } } + @TargetApi(Build.VERSION_CODES.P) + public AppComponentFactory getFactory(String pkg) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { +// if (pkg == null) { +// android.util.Log.e(TAG, "No pkg specified, disabling AppComponentFactory"); +// return AppComponentFactory.DEFAULT; +// } +// if (mThread == null) { +// android.util.Log.e(TAG, "Uninitialized ActivityThread, likely app-created Instrumentation," +// + " disabling AppComponentFactory", new Throwable()); +// return AppComponentFactory.DEFAULT; +// } +// LoadedApk apk = mThread.peekPackageInfo(pkg, true); +// // This is in the case of starting up "android". +// if (apk == null) apk = mThread.getSystemContext().mPackageInfo; +// return apk.getAppFactory(); + + Log.i(TAG, "我来了吗?getFactory"); + Object mThread = FieldUtils.readField(mTarget, "mThread", true); + if (mThread == null) { + try { + FieldUtils.writeField(mTarget, "mThread", ActivityThreadCompat.currentActivityThread()); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + return (AppComponentFactory) MethodUtils.invokeMethod(mTarget, "getFactory", pkg); + } + /** + * public ActivityResult execStartActivity( + * Context who, IBinder contextThread, IBinder token, Activity target, + * Intent intent, int requestCode, Bundle options) { + * 10.0 系统没办法指定 UserHandle user 所有这里拦截也没反应 + * @param who + * @param contextThread + * @param token + * @param resultWho + * @param intent + * @param requestCode + * @param options + * @param user + * @return + * @throws NoSuchMethodException + * @throws IllegalAccessException + * @throws InvocationTargetException + */ +// public ActivityResult execStartActivity( +// Context who, IBinder contextThread, IBinder token, String resultWho, +// Intent intent, int requestCode, Bundle options, UserHandle user) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException { +// Log.i(TAG, "我来了吗?execStartActivity"); +// return (ActivityResult) MethodUtils.invokeMethod(mTarget, "execStartActivity", who, contextThread, token, resultWho, intent, requestCode, options, user); +// } } diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/WebViewFactoryProviderHookHandle.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/WebViewFactoryProviderHookHandle.java index d744978d..4c8a691f 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/WebViewFactoryProviderHookHandle.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/handle/WebViewFactoryProviderHookHandle.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.handle; import android.content.Context; @@ -55,6 +55,8 @@ protected void init() { private static Class sContentMain; + private static Class sContextUtils; + private static void fixWebViewAsset(Context context) { try { if (sContentMain == null) { @@ -62,6 +64,12 @@ private static void fixWebViewAsset(Context context) { if (provider != null) { ClassLoader cl = provider.getClass().getClassLoader(); + try { + sContextUtils = Class.forName("org.chromium.base.ContextUtils", true, cl); + } catch (ClassNotFoundException e) { + Log.e(TAG, "fixWebViewAsset sContextUtils", e); + } + try { sContentMain = Class.forName("org.chromium.content.app.ContentMain", true, cl); } catch (ClassNotFoundException e) { @@ -75,13 +83,17 @@ private static void fixWebViewAsset(Context context) { } if (sContentMain == null) { - throw new ClassNotFoundException(String.format("Can not found class %s or %s in classloader %s", "org.chromium.content.app.ContentMain", "com.android.org.chromium.content.app.ContentMain", cl)); + //throw new ClassNotFoundException(String.format("Can not found class %s or %s in classloader %s", "org.chromium.content.app.ContentMain", "com.android.org.chromium.content.app.ContentMain", cl)); } } } if (sContentMain != null) { MethodUtils.invokeStaticMethod(sContentMain, "initApplicationContext", context.getApplicationContext()); } + + if (sContextUtils != null) { + MethodUtils.invokeStaticMethod(sContextUtils, "initApplicationContext", context.getApplicationContext()); + } } catch (Exception e) { Log.e(TAG, "fixWebViewAsset error", e); } diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/proxy/IActivityManagerHook.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/proxy/IActivityManagerHook.java index 803213ec..ed0dd0e6 100644 --- a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/proxy/IActivityManagerHook.java +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/proxy/IActivityManagerHook.java @@ -1,24 +1,24 @@ /* -** DroidPlugin Project -** -** Copyright(c) 2015 Andy Zhang -** -** This file is part of DroidPlugin. -** -** DroidPlugin is free software: you can redistribute it and/or -** modify it under the terms of the GNU Lesser General Public -** License as published by the Free Software Foundation, either -** version 3 of the License, or (at your option) any later version. -** -** DroidPlugin is distributed in the hope that it will be useful, -** but WITHOUT ANY WARRANTY; without even the implied warranty of -** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -** Lesser General Public License for more details. -** -** You should have received a copy of the GNU Lesser General Public -** License along with DroidPlugin. If not, see -** -**/ + ** DroidPlugin Project + ** + ** Copyright(c) 2015 Andy Zhang + ** + ** This file is part of DroidPlugin. + ** + ** DroidPlugin is free software: you can redistribute it and/or + ** modify it under the terms of the GNU Lesser General Public + ** License as published by the Free Software Foundation, either + ** version 3 of the License, or (at your option) any later version. + ** + ** DroidPlugin is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + ** Lesser General Public License for more details. + ** + ** You should have received a copy of the GNU Lesser General Public + ** License along with DroidPlugin. If not, see + ** + **/ package com.morgoo.droidplugin.hook.proxy; diff --git a/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/proxy/IActivityTaskManagerHook.java b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/proxy/IActivityTaskManagerHook.java new file mode 100644 index 00000000..7d230ae7 --- /dev/null +++ b/project/Libraries/DroidPlugin/src/main/java/com/morgoo/droidplugin/hook/proxy/IActivityTaskManagerHook.java @@ -0,0 +1,84 @@ +package com.morgoo.droidplugin.hook.proxy; + +import android.app.ActivityManager; +import android.content.Context; +import android.os.Build; + +import com.morgoo.droidplugin.hook.BaseHookHandle; +import com.morgoo.droidplugin.hook.handle.IActivityManagerHookHandle; +import com.morgoo.droidplugin.reflect.FieldUtils; +import com.morgoo.droidplugin.reflect.Utils; +import com.morgoo.helper.Log; +import com.morgoo.helper.MyProxy; +import com.morgoo.helper.compat.SingletonCompat; + +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.List; + +/** + * Copyright (C), 2018-2020 + * Author: ziqimo + * Date: 2020/8/1 2:54 PM + * Description: + * History: + *