前几天我发了一篇文章:小米的存储扩容是拆承重墙吗,文中站在非技术角度解读,其核心论点是“小米公司不可能背着巨大的风险去做收效甚微的事”,有粉丝表示赞同:“当对技术不了解的时候,还可以从基本逻辑来理解”;然而有一些童鞋嗤之以鼻,表示没有技术分析,纯属 YY。

我观察了这些粉丝过往的留言,发现他们大部分都是懂技术的,其专业程度远超普通用户;我对此表示理解,他们就是因为我的技术关注我的,现在我在这说别的,当然属于是在扯淡。的确,我做技术已经十年了,在某些领域做得还不错,这自然会给人一种固有的刻板印象;五年前,我也因为技术而从大厂出来选择自主创业;不过,我对技术的理解并非你们想象中的那样。

技术,只是解决问题的一种方式。它是你日常工具箱里面的一种工具,就像水管松了用扳手拧,灯泡不亮用万用表测,衣服破了用缝纫机补一样。

阅读全文 »

若干年前,我还在做 Android 客户端性能优化的时候,读到了 OpenResty 作者章亦春老师的文章:动态追踪技术漫谈,当时被深深地震撼到了,原来通过使用各种高级的调试技术,解决问题竟然可以做到如此精准而优雅。

然而当我真正要解决 Android 系统上应用程序的性能问题时,才发现理想很丰满现实很骨感——手头趁手的工具几乎没有。文章中提到的内核态追踪技术 SystemTap / DTrace 在 Android 系统上压根不存在,用户态的追踪技术开销大到可怕:TraceView 开启后程序性能直接下降十倍不止,Systrace 当时功能半残废,使用起来还需要自己插桩;simpleperf 能使,但就是有点 simple……到最后,真正要解决问题的时候,还是靠经验、二分法和 inline hook;为了定位 Android 虚拟机的性能问题,我甚至还自己造了个 ART HOOK 的轮子

然而,时间来到 2022 年,世界已焕然一新:eBPF 这种革命性的技术改变了一切。

阅读全文 »

去年春节之前,妈妈打电话给我说,我们老家那边有疫情,听说高速路口都封锁了;今年你在外面过年,一定要好好搞点吃的,过个好年。

我听完之后一时间有点恍惚:长这么大,我还没有在外面过年过;每年春节,无论我身处何地,无论回家要转多少趟车,我都会回家陪爸妈过节。电话完之后我赶紧又给老家那边的疾控中心打电话确认了一遍,被告知疫情是隔壁县的,可以放心回家,心里一块石头落了地。终于,我在腊月廿七那一天踏上了回乡的旅途。

偷渡长江

那一天我早早地起了床,在经过大半天的转车之后,终于在下午五点左右下了高速出口;结果出人意料的事情发生了:路上的一座大桥被人为堵住,回家的路被彻底堵死了;我辗转千里,却在离家不到两公里的地方被拒之门外。

阅读全文 »

你如今的气质里,藏着你走过的路、读过的书、爱过的人,以及学习过的编程语言。

如果把编程类比作武侠或者修仙里面的打怪升级,那我在入行的头几年,一直在痴迷于各种各样的招式;那时候我学习和体验了各种各样的语言:C/C++/Java/Javascript/Kotlin/Python/Ruby/Scala/Clojure/Scheme/Erlang/Haskell,不过自从我学习了 Haskell 之后,这份列表就基本停止增长了;虽然后来也对 Elixer、Go 也有过简单的了解,但是也仅限于了解了。

一方面随着从业时间的增长,要解决的问题逐渐变成了系统问题或者业务问题;另一方面也是体会到,语言只是工具,招式再花里胡哨也是徒劳,修炼内功才是王道。

不过,在一次机缘巧合之下,我再一次接触到了 Rust。

阅读全文 »

对于搞机党或者开发人员来说,root 一定是一个不陌生的名词。在 [当我们谈论解锁 BootLoader 时,我们在谈论什么?] 一文中我们了解到,解锁 Bootloader 实际上能做到的是让手机可以运行第三方的操作系统,而通常来说,我们给手机解锁 Bootloader 就是为了获取 Root 权限。那么,何为 root?,解锁 Bootloader 和 root 到底有什么联系和区别?

In Unix-like computer OSes (such as Linux), root is the conventional name of the user who has all rights or permissions (to all files and programs) in all modes (single- or multi-user).

维基百科说,在类 Unix 系统中,root 是在所有模式(单用户或多用户)下对所有文件和程序拥有所有权利或许可的用户的名称。

现代操作系统(本文主要讨论 Android 系统,下同)一般都是多用户的,那个名为 root 的用户所拥有的权限就是 root 权限;而 root 权限中有三个「所有」,可以简单这么理解:root 意味着最高权限;不过,这么描述不够具象,接下来就带大家了解一下 root 的方方面面。

阅读全文 »

有过刷机经验或者曾经尝试过刷机的童鞋,一定听说过「解锁」这个词。这里的「解锁」全称应该是「解锁 BootLoader」或者简称为「解 BL 锁」。与通过人脸识别或者指纹、数字图案解锁手机屏幕的那种「屏幕解锁」不同,这里的「解锁」完全是另外一个概念。直观来说,解 BL 锁是刷机的前提条件。通常情况下,一旦某个设备无法解锁 BL,基本上就无法在这个设备进行刷机了。

那么,一定会有童鞋关心,解锁 BootLoader 到底意味着什么?为什么它会有限制?我们能绕过限制强制解锁吗?今天,我就尝试来回答一下这几个问题。

在搞清楚解锁 BootLoader 之前,我们必须先搞清楚什么是 BootLoader:

A bootloader is software that is responsible for booting a computer.

维基百科上的介绍言简意赅:Bootloader 是负责启动计算机的软件。计算机开机的时候,会执行一个相对较小的程序来初始化内存、外设等启动后续操作系统必备的资源,并最终启动用户所使用的操作系统(如 Windows, Android 等);这个程序就是 BootLoader。

我们知道,操作系统负责管理设备的硬件资源;而 BootLoader 是用来启动操作系统的,如果有人通过 BootLoader 来启动一个恶意的操作系统,那我们设备的安全性就无法得到保障了。因此,BootLoader 一个核心的功能就是,确保启动一个可信的操作系统。另外,当设备的操作系统出现问题时,BootLoader 还可以引导启动另外一个正常的可信系统来执行恢复;所以,BootLoader 另外一个功能重要功能就是恢复系统。

阅读全文 »

几个月前,我写了一篇Android 黑科技保活实现原理揭秘,当时我们提到,现在的进程保活基本上分为两类,一种是想尽办法提升进程的优先级,保证进程不会轻易被系统杀死;另一种是确保进程被杀死之后能通过各种方式复活。

Android 黑科技保活实现原理揭秘 中的进程永生术是第二种,它通过钻 Android 杀进程的空子实现了涅槃永生;不了解的同学可以参考一下 PoC。归根结底,所谓的黑科技就是利用系统漏洞。那么,既然我们可以利用漏洞逃过追杀,那何不更进一步,利用系统漏洞提权?

阅读全文 »

最近我在编写一个 Android 上的驱动程序,这个驱动程序的某些部分用到了 Unix domain socket,守护进程和客户端进程使用 C/S 模式进行通信。在调试程序的时候发现一个非常奇怪的问题:如果客户端开启若干个线程连上 socket,send/recv 若干消息之后立即退出进程,从日志上看,server 端有 10% 左右的概率无法正常回收资源。

一开始我以为是我自己程序写的有问题,毕竟这个驱动是使用纯 C 语言实现的,并且用到了 epoll 的 ET 模式,这种非阻塞的编程模型的确有许多微妙的地方,一不小心就容易出错。我排查了很久都没有发现问题所在,更有趣的是,虽然看起来我的程序无法回收资源,但是在压力测试下他也能正常工作,完全没有资源泄漏的迹象;实在没办法,我就祭出了大杀器 strace。不看不知道,一看就好笑:strace 显示,我的程序逻辑是正常的,它正确地调用了相关的资源释放函数!但是,logcat 中没有相关的日志,在客户端退出之后 server 端的日志就戛然而止了。看起来,好像不是我程序的问题,而是系统的 logcat 丢失了日志?

阅读全文 »

一直以来,App 进程保活都是各大厂商,特别是头部应用开发商永恒的追求。毕竟App 进程死了,就什么也干不了了;一旦 App 进程死亡,那就再也无法在用户的手机上开展任何业务,所有的商业模型在用户侧都没有立足之地了。

早期的 Android 系统不完善,导致 App 侧有很多空子可以钻,因此它们有着有着各种各样的姿势进行保活。譬如说在 Android 5.0 以前,App 内部通过 native 方式 fork 出来的进程是不受系统管控的,系统在杀 App 进程的时候,只会去杀 App 启动的 Java 进程;因此诞生了一大批“毒瘤”,他们通过 fork native 进程,在 App 的 Java 进程被杀死的时候通过 am命令拉起自己从而实现永生。那时候的 Android 可谓是魑魅横行,群魔乱舞;系统根本管不住应用,因此长期以来被人诟病耗电、卡顿。同时,系统的软弱导致了 Xposed 框架、阻止运行、绿色守护、黑域、冰箱等一系列管制系统后台进程的框架和 App 出现。

不过,随着 Android 系统的发展,这一切都在往好的方向演变。

阅读全文 »

去年发布的 Android P上引入了针对非公开API的限制,对开发者来说,这绝对是有史以来最重大的变化之一。前天 Google 发布了 Android Q 的 Beta 版,越来越多的 API 被加入了黑名单,而且 Google 要求下半年 APP 必须 target 28,这意味着现在的深灰名单也会生效;可以预见,在不久的将来,我们要跟大量的 API 说再见了。

去年我给出了一种绕过Android P对非SDK接口限制的简单方法,经验证,这办法在 Android Q 的 Beta 版上依然能正常使用。虽然这个方法需要进行内存搜索,理论上有可能失败,但实际上它曾在 VirtualXposed 和 太极 中得到了较为广泛的验证,从未收到过由于反射失败而导致问题的反馈。而且据我所知,有若干用户量不少的 APP 在线上使用了我提供的 FreeReflection 库,想来应该也是没有问题的吧。

不过今天,我打算给出另外一种绕过限制的办法。这个办法目前来说是最优方案,我个人使用了一个多月,不存在任何问题。

阅读全文 »