最近,一款名为 Cursor 的 AI 编程工具火遍了编程圈。自从 ChatGPT 发布以来,AI 正以肉眼可见的速度进化,从最初的翻译和总结,到现在的语音、视觉和思考能力,极大地方便了我们的工作和生活。许多人担心,未来 AI 会不会取代人类?

作为一个程序员,我的大部分工作都与代码打交道。在编程领域,AI 也展现了强大的能力。例如,Github Copilot 极大地提高了编程效率。Copilot 就像一个“副驾驶”,可以帮助你完成代码片段,但它无法自主完成整个项目,仍然需要你懂一些代码。

但是 Cursor 不一样。你只需描述自己的想法,它就能自动生成代码,重复这个过程就能完成整个项目。它有多强大呢?有一个 8 岁的小女孩借助 Cursor AI 在45分钟内写出了一个聊天机器人,着实令人震惊。

阅读全文 »

自 2018 年我发布 VirtualXposed 以来,这 6 年里我做了不少开源或者免费的产品,用过我 App 的用户,没有千万也有百万;然而,所有这些东西都是完全免费的,我没有任何直接的经济收益,「用爱发电」说的大概就是这了。

几天前我把小狐狸钱包的助记词搞丢了,当时我很着急,因为多年以前我就把这个钱包的地址放在我的很多捐赠页面,心想里面没准有一笔巨款呢;结果我去 etherscan 上去一查,没有任何交易记录,资产是零,总算有惊无险。

这听起来似乎很滑稽,但却是绝大多数“用爱发电”项目的现状,靠用户自发捐赠,可能连一顿饭钱都挣不回来,更别提养家糊口了。

不挣钱倒是没啥,毕竟我们都是手艺人,那两把刷子养活自己还是没啥问题的。更让人难受的是,我们还经常被各种网络喷子问候,那些无端的谩骂、诋毁甚至毁谤,会让人产生自我怀疑:“我到底是在图个啥?”。

阅读全文 »

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

阅读全文 »