如何看待 7 月 15 日大量 QQ 账号被冻结？腾讯发生了什么？
先给结论：这应该是一次第三方依赖库升级引发的。 这个第三方依赖库是恰好是我本人在 github 上开源的，一个名为 `epic` 的项目（地址在这里：https://github.com/tiann/epic）；`epic` 是一个在虚拟机层面、以 Java Method 为粒度的 运行时 AOP Hook 框架。它可以拦截本进程内部几乎任意的 Java 方法调用，可用于实现 AOP 编程、运行时插桩、性能分析、安全审计等。 我开发这个库的初衷是做性能分析，更具体点，是为了监控 App 内部线程的调度情况。当时我正在支付宝做 Android 端 App 的性能优化，因为研发团队很大，内部又没有一个完全统一的基础设施，代码里面很多四处散落的线程（池）、广播，Service等；可能一个线程或者广播并不消耗什么性能，但是量变产生质变，支付宝启动之后峰值会有三百多个子线程在运行，同时有一百多个广播在主线程跑，即使每个只运行几毫秒加起来也有若干秒了。为了知道是哪里创建了这些资源，我非常需要一个运行时插桩工具来监控 App 的运行情况；于是我就花了点时间撸了一个库并且开源在 github 上。 说到这里也许有童鞋会问：这 `epic`听起来不是挺好吗，为啥会导致冻结？ 技术是一把双刃剑。由于 `epic` 可以拦截本进程内几乎任意的方法调用，一旦以合适的方式加以利用，就可以创建上帝视角，控制任意 App 的运行。这个功能与 Android 上大名鼎鼎的 Xposed 框架本质上是一样的。 比如说抢红包这功能，大部分都是借助 Xposed 框架通过模块实现的；这些功能看起来对普通人创造了便利，但是实际上滋生了很多阴暗的角落；就拿抢红包来说，有一些团体通过发红包来赌博，而如果有人通过 Xposed 框架干涉这个过程就相当于“出千”。若干年过去，大量灰黑产团体通过 Xposed 框架来干扰 App 的正常运行。因此 App 官方是非常讨厌 Xposed 框架存在的，它们通常会在用户手机上检测到 Xposed 框架存在之后，对用户进行账号冻结操作。 不过通常来说，使用 Xposed 框架的用户相对比较少，因此由于使用 Xposed 被封号的用户也是极少数。而这一次 QQ 更新之后，由于引入了错误的代码依赖，导致它在任何Android 手机上都认为检测到了 Xposed 框架，从而触发账户冻结。 QQ 在很早之前就引入了 `epic`，当时应该是为了做线上性能检测。那个时候的 `epic` 只是为了做性能监控，因此 API 与 Xposed 并不兼容，里面的类基本上与Xposed 没有太大关联；QQ 集成这个库之后，其实就是引入了一个非常普通的依赖；我们看一下上个版本 QQ 的代码： 可以看到，QQ 对 `epic`做了少许修改，部分类挪到了 `com.qq.android.dexposed`下面；因此这个实际上没有什么影响。然后我们看一下新版QQ的变化： 可以看到，这个类被挪到了 `de.robv.android.xposed` 这个包下面；而这个包，就是 Xposed 框架所在地方。一般来说，App 进程如果发现有这个包存在，那么就可以认为是手机上装有 Xposed 框架，从而进行一系列接下来的动作。而 QQ 的这个行为，直接就是把 Xposed 所有的类放在了自己名下；因此它如果检测 `Xposed` 相关类，会 100% 判定为手机上装有 Xposed 框架： 由于 `epic` 可以实现 Xposed 的功能，因此再后来我通过它实现了一些类 Xposed 框架，为了兼容原来的框架，我对 `epic`项目做出了一些调整：让它直接依赖了 Xposed 框架的相关类（具体commit见这里：https://github.com/tiann/epic/commit/dd5a10ddf2daa51a6724a943b73e87ae141fec82#diff-0d1d9100a9b6813b8cb5c470bf313d00）。在这一次调整之后，只要引入了 `epic`，就会默认引入 Xposed 相关的类。因此，QQ 在更新`epic`项目的版本之后，把 Xposed 相关的类也引入了 QQ。 经过对比分析两个版本 QQ 中 `epic` 的变化，可以进一步发现，是因为QQ更新了 `epic`的版本，导致引入了 `Xposed`相关的依赖，从而把所有 Xposed 相关的类集成到了QQ之中: 如上图，新版本的`epic`默认引入了两个额外依赖：`free_reflection` 和`Xposed`，进一步我们看到，新版本的QQ的确引入了我的另外一个库`free_reflection`：  至此，我们的技术分析就结束了。本次 QQ 被冻结的悲剧，实际上是一次工程失误，开发团队在对第三方依赖进行升级的时候，引入了错误的、不合适的依赖库，从而导致了悲剧的发生。  这也告诫我们，在升级第三方依赖的时候一定要慎之又慎，千万不要盲目追新；很多童鞋有升级强迫症，看到有更新就想试，实际上这是非常危险的。在现实世界中，项目的稳定性一定是第一位，在升级依赖之前，一定要做好充分的评估。这次 QQ 升级引发的事故，必须引以为鉴。