diff --git a/DOC/tianweishu/Activity生命周期管理.md b/DOC/tianweishu/Activity生命周期管理.md index 263b016..15c9b09 100644 --- a/DOC/tianweishu/Activity生命周期管理.md +++ b/DOC/tianweishu/Activity生命周期管理.md @@ -1,11 +1,4 @@ -title: "Android 插件化原理解析——Activity生命周期管理" -date: 2016-03-21 19:43:32 -tags: -- android -- plugin framework -- droidplugin ---- - +# Activity生命周期管理 之前的 [Android插件化原理解析][1] 系列文章揭开了Hook机制的神秘面纱,现在我们手握倚天屠龙,那么如何通过这种技术完成插件化方案呢?具体来说,插件中的Activity,Service等组件如何在Android系统上运行起来? @@ -240,9 +233,9 @@ startActivity(new Intent(MainActivity.this, TargetActivity.class)); 由于`AMS`进程会对Activity做显式声明验证,因此在 启动Activity的控制权转移到`AMS`进程之前,我们需要想办法**临时**把TargetActivity替换成替身StubActivity;在这之间有很长的一段调用链,我们可以轻松Hook掉;选择什么地方Hook是一个很自由的事情,但是Hook的步骤越后越可靠——Hook得越早,后面的调用就越复杂,越容易出错。 -我们可以选择在进入`AMS`进程的入口进行Hook,具体来说也就是Hook `AMS`在本进程的代理对象ActivityManagerNative。如果你不知道如何Hook掉这个AMS的代理对象,请查阅我之前的文章 [Hook机制之AMS&PMS][5] +我们可以选择在进入`AMS`进程的入口进行Hook,具体来说也就是Hook `AMS`在本进程的代理对象ActivityManagerNative。如果你不知道如何Hook掉这个AMS的代理对象,请查阅我之前的文章 [Hook机制之AMS&PMS][5] -我们Hook掉ActivityManagerNative对于startActivity方法的调用,替换掉交给AMS的intent对象,将里面的TargetActivity的暂时替换成已经声明好的替身StubActivity;这种Hook方式 [前文][5] 讲述的很详细,不赘述;替换的关键代码如下: +我们Hook掉ActivityManagerNative对于startActivity方法的调用,替换掉交给AMS的intent对象,将里面的TargetActivity的暂时替换成已经声明好的替身StubActivity;这种Hook方式 [前文][5] 讲述的很详细,不赘述;替换的关键代码如下: ```java if ("startActivity".equals(method.getName())) { @@ -503,9 +496,9 @@ mInstrumentation.callActivityOnDestroy(r.activity); 喜欢就点个赞吧~持续更新,请关注github项目 [understand-plugin-framework][2]和我的 [博客](http://weishu.me)! -[1]: http://weishu.me/2016/01/28/understand-plugin-framework-overview/ +[1]: 概述.md [2]: https://github.com/tiann/understand-plugin-framework -[3]: http://weishu.me/2016/01/28/understand-plugin-framework-proxy-hook/ -[4]: http://weishu.me/2016/02/16/understand-plugin-framework-binder-hook/ -[5]: http://weishu.me/2016/03/07/understand-plugin-framework-ams-pms-hook/ +[3]: Hook机制之代理Hook.md +[4]: Hook机制之Binder-Hook.md +[5]: Hook机制之AMS&PMS.md [6]: http://blog.csdn.net/luoshengyang/article/details/6685853 diff --git a/DOC/tianweishu/BroadcastReceiver插件化.md b/DOC/tianweishu/BroadcastReceiver插件化.md index 0158edd..95dda07 100644 --- a/DOC/tianweishu/BroadcastReceiver插件化.md +++ b/DOC/tianweishu/BroadcastReceiver插件化.md @@ -1,11 +1,4 @@ -title: "Android插件化原理解析——广播的管理" -date: 2016-04-12 19:08:16 -tags: -- android -- plugin framework -- droidplugin -- broadcastreceiver ---- +# BroadcastReceiver插件化 在[Activity生命周期管理][1] 以及 [插件加载机制][2] 中我们详细讲述了插件化过程中对于Activity组件的处理方式,为了实现Activity的插件化我们付出了相当多的努力;那么Android系统的其他组件,比如BroadcastReceiver,Service还有ContentProvider,它们又该如何处理呢? @@ -184,7 +177,7 @@ public void run() { final IActivityManager mgr = ActivityManagerNative.getDefault(); final Intent intent = mCurIntent; mCurIntent = null; - + if (receiver == null || mForgotten) { if (mRegistered && ordered) { sendFinished(mgr); @@ -209,7 +202,7 @@ public void run() { + " in " + mReceiver, e); } } - + if (receiver.getPendingResult() != null) { finish(); } @@ -323,9 +316,9 @@ for (ActivityInfo activityInfo : ReceiverHelper.sCache.keySet()) { 接下来为文章会讲述四大组件中的另外两个——Service和ContentProvider的插件化方案;喜欢就点个赞吧~持续更新,请关注github项目 [understand-plugin-framework][2] 和我的 [博客](http://weishu.me) ! 如果你觉得能从文中学到皮毛,还请支持一下 :) -[1]: http://weishu.me/2016/03/21/understand-plugin-framework-activity-management/ -[2]: http://weishu.me/2016/04/05/understand-plugin-framework-classloader/ +[1]: Activity生命周期管理.md +[2]: ClassLoader管理.md [3]: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/5.0.1_r1/android/content/IIntentReceiver.java?av=f -[4]: http://weishu.me/2016/03/21/understand-plugin-framework-activity-management/ +[4]: Activity生命周期管理.md [5]: https://github.com/tiann/understand-plugin-framework -[6]: http://weishu.me/2016/01/28/understand-plugin-framework-overview/ \ No newline at end of file +[6]: 概述.md diff --git a/DOC/tianweishu/ClassLoader管理.md b/DOC/tianweishu/ClassLoader管理.md index ebad1b8..a7a4ee9 100644 --- a/DOC/tianweishu/ClassLoader管理.md +++ b/DOC/tianweishu/ClassLoader管理.md @@ -1,12 +1,4 @@ -title: 'Android 插件化原理解析——插件加载机制' -date: 2016-04-05 20:13:01 -tags: -- android -- plugin framework -- droidplugin -- binder -- classloader ---- +# 插件加载机制 上文 [Activity生命周期管理][3] 中我们地完成了『启动没有在AndroidManifest.xml中显式声明的Activity』的任务;通过Hook `AMS`和拦截ActivityThread中`H`类对于组件调度我们成功地绕过了AndroidMAnifest.xml的限制。 @@ -188,7 +180,7 @@ public final LoadedApk getPackageInfoNoCheck(ApplicationInfo ai, 我们首先看看ApplicationInfo代表什么,这个类的文档说的很清楚: > Information you can retrieve about a particular application. This corresponds to information collected from the AndroidManifest.xml's <application> tag. - + 也就是说,这个类就是AndroidManifest.xml里面的 这个标签下面的信息;这个AndroidManifest.xml无疑是一个标准的xml文件,因此我们完全可以自己使用parse来解析这个信息。 那么,系统是如何获取这个信息的呢?其实Framework就有一个这样的parser,也即PackageParser;理论上,我们也可以借用系统的parser来解析AndroidMAnifest.xml从而得到ApplicationInfo的信息。但遗憾的是,**这个类的兼容性很差**;Google几乎在每一个Android版本都对这个类动刀子,如果坚持使用系统的解析方式,必须写一系列兼容行代码!!DroidPlugin就选择了这种方式,相关类如下: @@ -208,7 +200,7 @@ OK回到正题,我们决定使用PackageParser类来提取ApplicationInfo信 ```java public static ApplicationInfo generateApplicationInfo(Package p, int flags, - PackageUserState state) + PackageUserState state) ``` 可以写出调用generateApplicationInfo的反射代码: @@ -691,15 +683,14 @@ DroidPlugin和Small的共同点是**两者都是非侵入式的插件框架**; OK,本文的内容就到这里了;关于『插件机制对于Activity的处理方式』也就此完结。要说明的是,在本文的『保守方案』其实只处理了代码的加载过程,它并不能加载有资源的apk!所以目前我这个实现基本没什么暖用;当然我这里只是就『代码加载』进行举例;至于资源,那牵扯到另外一个问题——**插件系统的资源管理机制**这个在后续文章的合适机会我会单独讲解。 -接下来的文章,会讲述Android四大组件的另外三个`Service`,`BroadCastReceiver`, `ContentProvider`的处理方式。喜欢就点个赞吧~持续更新,请关注github项目 [understand-plugin-framework][2]和我的 [博客](http://weishu.me)! 这文章我前前后后准备了快两个星期,如果你看到了这里,还请支持一下 :) +接下来的文章,会讲述Android四大组件的另外三个`Service`,`BroadCastReceiver`, `ContentProvider`的处理方式。喜欢就点个赞吧~持续更新,请关注github项目 [understand-plugin-framework][2]和我的 [博客](http://weishu.me)! 这文章我前前后后准备了快两个星期,如果你看到了这里,还请支持一下 :) -[1]: http://weishu.me/2016/01/28/understand-plugin-framework-overview/ +[1]: 概述.md [2]: https://github.com/tiann/understand-plugin-framework -[3]: http://weishu.me/2016/03/21/understand-plugin-framework-activity-management/ -[4]: http://weishu.me/2016/03/07/understand-plugin-framework-ams-pms-hook/ +[3]: Activity生命周期管理.md +[4]: Hook机制之AMS&PMS.md [5]: http://androidxref.com/6.0.1_r10/xref/libcore/dalvik/src/main/java/dalvik/system/PathClassLoader.java [6]: http://androidxref.com/6.0.1_r10/xref/libcore/dalvik/src/main/java/dalvik/system/BaseDexClassLoader.java -[7]: http://weishu.me/2016/02/16/understand-plugin-framework-binder-hook/ - +[7]: Hook机制之Binder-Hook.md diff --git a/DOC/tianweishu/ContentProvider插件化.md b/DOC/tianweishu/ContentProvider插件化.md index d7441c9..938599f 100644 --- a/DOC/tianweishu/ContentProvider插件化.md +++ b/DOC/tianweishu/ContentProvider插件化.md @@ -1,11 +1,4 @@ -title: "Android插件化原理解析——ContentProvider的插件化" -date: 2016-07-12 19:18:07 -tags: -- android -- plugin framework -- droidplugin -- ContentProvider ---- +# ContentProvider插件化 目前为止我们已经完成了Android四大组件中Activity,Service以及BroadcastReceiver的插件化,这几个组件各不相同,我们根据它们的特点定制了不同的插件化方案;那么对于ContentProvider,它又有什么特点?应该如何实现它的插件化? @@ -299,7 +292,7 @@ synchronized (cpr) { } ``` -你没看错,一个死循环就是糊在上面:AMS进程会通过一个死循环等到进程B完成ContentProvider的安装,等待完成之后会把ContentProvider的信息返回给进程A。那么,我们现在的疑惑是,**进程B在启动之后,在哪个时间点会完成ContentProvider的安装呢?** +你没看错,一个死循环就是糊在上面:AMS进程会通过一个死循环等到进程B完成ContentProvider的安装,等待完成之后会把ContentProvider的信息返回给进程A。那么,我们现在的疑惑是,**进程B在启动之后,在哪个时间点会完成ContentProvider的安装呢?** 我们接着看ActivityThread的main函数,顺便寻找我们上面那个问题的答案;这个分析实际上就是Android App的启动过程,更详细的过程可以参阅老罗的文章 [Android应用程序启动过程源代码分析][4],这里只给出简要调用流程: @@ -579,7 +572,7 @@ private Uri getRealUri(Uri raw) { 喜欢就点个赞吧,兜里有一块钱的童鞋可以点击下面的打赏然后扫一下二维码哦~持续更新,请关注github项目 [understand-plugin-framework][1] 和我的 [博客][3]! 另外很抱歉一个多月没有更新博客了,每天看到各位的来访记录深感惭愧,实在是业务繁忙,身不由已!不出意外接下来会以正常速度更新内容,谢谢支持 ^_^ [1]: https://github.com/tiann/understand-plugin-framework -[2]: http://weishu.me/2016/01/28/understand-plugin-framework-overview/ +[2]: 概述.md [3]: http://weishu.me [4]: http://blog.csdn.net/luoshengyang/article/details/6689748 -[5]: http://blog.csdn.net/luoshengyang/article/details/6967204 \ No newline at end of file +[5]: http://blog.csdn.net/luoshengyang/article/details/6967204 diff --git a/DOC/tianweishu/Hook机制之AMS & PMS.md b/DOC/tianweishu/Hook机制之AMS&PMS.md similarity index 98% rename from DOC/tianweishu/Hook机制之AMS & PMS.md rename to DOC/tianweishu/Hook机制之AMS&PMS.md index 25f552a..14ee72b 100644 --- a/DOC/tianweishu/Hook机制之AMS & PMS.md +++ b/DOC/tianweishu/Hook机制之AMS&PMS.md @@ -1,10 +1,4 @@ -title: 'Android 插件化原理解析——Hook机制之AMS&PMS' -date: 2016-03-07 16:35:46 -tags: -- android -- plugin framework -- droidplugin ---- +# Hook机制之AMS&PMS 在前面的文章中我们介绍了DroidPlugin的Hook机制,也就是**代理方式**和**Binder Hook**;插件框架通过AOP实现了插件使用和开发的透明性。在讲述DroidPlugin如何实现四大组件的插件化之前,有必要说明一下它对ActivityManagerServiche以及PackageManagerService的Hook方式(以下简称AMS,PMS)。 @@ -174,7 +168,7 @@ D/HookHelper﹕ method:startActivity called with args:[android.app.ActivityThrea D/HookHelper﹕ hey, baby; you are hook!! D/HookHelper﹕ method:activityPaused called with args:[android.os.BinderProxy@9bc71b2] ``` -可以看到,简单的几行代码,`AMS`已经被我们完全劫持了!! 至于劫持了能干什么,自己发挥想象吧~ +可以看到,简单的几行代码,`AMS`已经被我们完全劫持了!! 至于劫持了能干什么,自己发挥想象吧~ DroidPlugin关于`AMS`的Hook,可以查看`IActivityManagerHook`这个类,它处理了我上述所说的兼容性问题,其他原理相同。另外,也许有童鞋有疑问了,你用`startActivity`为例怎么能确保Hook掉这个静态变量之后就能保证所有使用`AMS`的入口都被Hook了呢? @@ -279,10 +273,10 @@ OK,我们又成功劫持了`PackageManager`!!DroidPlugin 处理PMS的代 喜欢就点个赞吧~持续更新,请关注github项目 [understand-plugin-framework][2]和我的 [博客](http://weishu.me)! -[1]: http://weishu.me/2016/02/16/understand-plugin-framework-binder-hook/ +[1]: Hook机制之Binder-Hook.md [2]: https://github.com/tiann/understand-plugin-framework [3]: http://blog.csdn.net/luoshengyang/article/details/6689748 [4]: http://weishu.me/2016/01/12/binder-index-for-newer/ [5]: http://grepcode.com/file_/repository.grepcode.com/java/ext/com.google.android/android/4.0.1_r1/android/app/ActivityManagerNative.java/?v=diff&id2=2.3.3_r1 -[6]: http://weishu.me/2016/01/28/understand-plugin-framework-proxy-hook/ -[7]: https://segmentfault.com/a/1190000004077469 \ No newline at end of file +[6]: Hook机制之代理Hook.md +[7]: https://segmentfault.com/a/1190000004077469 diff --git a/DOC/tianweishu/Hook机制之Binder Hook.md b/DOC/tianweishu/Hook机制之Binder-Hook.md similarity index 98% rename from DOC/tianweishu/Hook机制之Binder Hook.md rename to DOC/tianweishu/Hook机制之Binder-Hook.md index 462d172..b011c5a 100644 --- a/DOC/tianweishu/Hook机制之Binder Hook.md +++ b/DOC/tianweishu/Hook机制之Binder-Hook.md @@ -1,11 +1,4 @@ -title: "Android插件化原理解析——Hook机制之Binder Hook" -date: 2016-02-16 19:22:45 -tags: -- android -- plugin framework -- droidplugin -- binder ---- +# Hook机制之Binder-Hook Android系统通过Binder机制给应用程序提供了一系列的系统服务,诸如`ActivityManagerService`,`ClipboardManager`, `AudioManager`等;这些广泛存在系统服务给应用程序提供了诸如任务管理,音频,视频等异常强大的功能。 @@ -84,7 +77,7 @@ IXXInterface in = IXXInterface.Stub.asInterface(b); // 转换为Service接口 ```java public static android.content.IClipboard asInterface(android.os.IBinder obj) { if ((obj == null)) { - return null; + return null; } android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR); // Hook点 if (((iin != null) && (iin instanceof android.content.IClipboard))) { @@ -292,7 +285,7 @@ cache.put(CLIPBOARD_SERVICE, hookedBinder); 喜欢就点个赞吧~持续更新,请关注github项目 [understand-plugin-framework][3] 和我的 [博客][5]! [1]: http://weishu.me/2016/01/12/binder-index-for-newer/ -[2]: http://weishu.me/2016/01/28/understand-plugin-framework-overview/ +[2]: 概述.md [3]: https://github.com/tiann/understand-plugin-framework -[4]: http://weishu.me/2016/01/28/understand-plugin-framework-proxy-hook/ +[4]: Hook机制之代理Hook.md [5]: http://weishu.me/ diff --git a/DOC/tianweishu/Hook机制之代理Hook.md b/DOC/tianweishu/Hook机制之代理Hook.md index 2995a31..6a75a8b 100644 --- a/DOC/tianweishu/Hook机制之代理Hook.md +++ b/DOC/tianweishu/Hook机制之代理Hook.md @@ -1,10 +1,4 @@ -title: "Android插件化原理解析——Hook机制之动态代理" -date: 2016-01-28 20:27:13 -tags: -- android -- plugin framework -- droidplugin ---- +# Hook机制之动态代理 使用代理机制进行API Hook进而达到方法增强是框架的常用手段,比如J2EE框架Spring通过动态代理优雅地实现了AOP编程,极大地提升了Web开发效率;同样,插件框架也广泛使用了代理机制来增强系统API从而达到插件化的目的。本文将带你了解基于动态代理的Hook机制。 @@ -156,10 +150,10 @@ public class EvilInstrumentation extends Instrumentation { try { Method execStartActivity = Instrumentation.class.getDeclaredMethod( "execStartActivity", - Context.class, IBinder.class, IBinder.class, Activity.class, + Context.class, IBinder.class, IBinder.class, Activity.class, Intent.class, int.class, Bundle.class); execStartActivity.setAccessible(true); - return (ActivityResult) execStartActivity.invoke(mBase, who, + return (ActivityResult) execStartActivity.invoke(mBase, who, contextThread, token, target, intent, requestCode, options); } catch (Exception e) { // 某该死的rom修改了 需要手动适配 @@ -206,4 +200,4 @@ public static void attachContext() throws Exception{ 喜欢就点个赞吧~持续更新,请关注github项目 [understand-plugin-framework][1]和我的 [博客](http://weishu.me)! -[1]: https://github.com/tiann/understand-plugin-framework \ No newline at end of file +[1]: https://github.com/tiann/understand-plugin-framework diff --git a/DOC/tianweishu/Service插件化.md b/DOC/tianweishu/Service插件化.md index 0f126c1..9bcdce4 100644 --- a/DOC/tianweishu/Service插件化.md +++ b/DOC/tianweishu/Service插件化.md @@ -1,11 +1,4 @@ -title: "Android 插件化原理解析——Service的插件化" -date: 2016-05-11 21:02:50 -tags: -- android -- plugin framework -- droidplugin -- service ---- +# Service插件化 在 [Activity生命周期管理][1] 以及 [广播的管理][2] 中我们详细探讨了Android系统中的Activity、BroadcastReceiver组件的工作原理以及它们的插件化方案,相信读者已经对Android Framework和插件化技术有了一定的了解;本文将探讨Android四大组件之一——Service组件的插件化方式。 @@ -135,7 +128,7 @@ int bindServiceLocked(IApplicationThread caller, IBinder token, Intent service, ```java private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, boolean execInFg, boolean whileRestarting) throws TransactionTooLargeException { - + // 略。。 final boolean isolated = (r.serviceInfo.flags&ServiceInfo.FLAG_ISOLATED_PROCESS) != 0; @@ -186,7 +179,7 @@ private final String bringUpServiceLocked(ServiceRecord r, int intentFlags, bool ```java private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { - + // 略。。 boolean created = false; @@ -275,7 +268,7 @@ OK,现在ActivityThread里面的`handleCreateService`方法成功创建出了S ```java private final void realStartServiceLocked(ServiceRecord r, ProcessRecord app, boolean execInFg) throws RemoteException { - + // 略。。 boolean created = false; @@ -529,7 +522,7 @@ if ("startService".equals(method.getName())) { newIntent.setComponent(componentName); // 把我们原始要启动的TargetService先存起来 newIntent.putExtra(AMSHookHelper.EXTRA_TARGET_INTENT, integerIntentPair.second); - + // 替换掉Intent, 达到欺骗AMS的目的 args[integerIntentPair.first] = newIntent; Log.v(TAG, "hook method startService success"); @@ -739,16 +732,15 @@ public void onStart(Intent proxyIntent, int startId) { Service,Activity等不过就是一些普通的Java类,它们之所称为四大组件,是因为他们有生命周期;这也是简单地采用Java的动态加载技术无法实现插件化的原因——动态加载进来的Service等类如果没有它的生命周期,无异于一个没有灵魂的傀儡。对于Activity组件,由于他的生命周期受用户交互影响,只有系统本身才能对这种交互有全局掌控力,因此它的插件化方式是Hook AMS,但是生命周期依然交由系统管理;而Service以及BroadcastReceiver的生命周期没有额外的因素影响,因此我们选择了手动控制其生命周期的方式。不论是借尸还魂还是女娲造人,对这些组件的插件化终归结底是要赋予组件“生命”。 插件化系列的文章有整整一个月没有更新了,非常抱歉!这段时间发生了很多事情,我实在抽不出时间照顾博客;而写这种文章又需要足够的时间准备,要跟踪源码分析过程,要找联系DroidPlugin作者确认设计思路,还要亲自写demo验证。 -喜欢就点个赞吧,兜里有一块钱的童鞋可以点击下面的打赏然后扫一下二维码哦~持续更新,请关注github项目 [understand-plugin-framework][3] 和我的 [博客][9]! +喜欢就点个赞吧,兜里有一块钱的童鞋可以点击下面的打赏然后扫一下二维码哦~持续更新,请关注github项目 [understand-plugin-framework][3] 和我的 [博客][9]! -[1]: http://weishu.me/2016/03/21/understand-plugin-framework-activity-management/ -[2]: http://weishu.me/2016/04/12/understand-plugin-framework-receiver/ +[1]: Activity生命周期管理.md +[2]: BroadcastReceiver插件化.md [3]: https://github.com/tiann/understand-plugin-framework -[4]: http://weishu.me/2016/01/28/understand-plugin-framework-overview/ +[4]: 概述.md [5]: http://developer.android.com/intl/zh-cn/guide/components/services.html -[6]: http://weishu.me/2016/03/07/understand-plugin-framework-ams-pms-hook/ -[7]: http://weishu.me/2016/04/05/understand-plugin-framework-classloader/ +[6]: Hook机制之AMS&PMS.md +[7]: ClassLoader管理.md [8]: https://github.com/singwhatiwanna/dynamic-load-apk [9]: http://weishu.me - diff --git a/DOC/tianweishu/概述.md b/DOC/tianweishu/概述.md index 85803f9..78d98a4 100644 --- a/DOC/tianweishu/概述.md +++ b/DOC/tianweishu/概述.md @@ -1,4 +1,4 @@ -# Android插件化原理解析——概要 +# 概要 2015年是Android插件化技术突飞猛进的一年,随着业务的发展各大厂商都碰到了Android Native平台的瓶颈: @@ -44,8 +44,8 @@ H5和Hybird可以解决这些问题,但是始终比不上native的用户体验 另外,对于每一章内容都会有详细的demo,具体见[understand-plugin-framework](https://github.com/tiann/understand-plugin-framework);喜欢就点个关注吧~定期更新,敬请期待! [1]: Hook机制之代理Hook.md -[2]: 'Hook机制之Binder Hook.md' -[3]: 'Hook机制之AMS & PMS.md' +[2]: Hook机制之Binder-Hook.md +[3]: Hook机制之AMS&PMS.md [4]: Activity生命周期管理.md [5]: ClassLoader管理.md [6]: BroadcastReceiver插件化.md