敝人对「保存音乐的介质」有一种迷一样的执著。如果你看过一个叫「科幻枸杞」的 YouTuber,那你大概就能懂,我跟他的爱好还挺像的(虽然这么说有点臭不要脸,人家那片子做得是真牛逼,而且我也没那闲钱折腾这种东西)。小学的时候特别喜欢用家里的磁带机做 Mix Tape,留下了很多美好回忆。而现在,人生理想是搞一台自己的磁带机 Walkman。
但这事儿它不咋好搞。Walkman 这东西,死贵,坑又多。~~我今年的生日愿望就是期待一个好心裙友送我一台,但我知道你会骂我臭不要脸~~。
为了填补那深邃的消费主义空洞。半年前,我凑合着买了个飞傲(Fiio)出的 Echo Mini,一个长得像 mini 磁带机的 MP3。
这个设备挺烂的
到手之后用了一阵子,产生了一种相当复杂的感受,挺好,但是活整挺烂。
最辣眼睛的是那个大果粒显示器,搁十五年前你可能会觉得它就是 Average Level 的显示屏幕。但在 2026 年的今天,盯着它那个屏幕,就只会觉得颇为微妙。其实哪怕屏幕是大果粒,只要你的视觉做得好(比如复古像素风),说不定还是个优势。但这设备的设计烂就烂在那破 UI,一开机「地铁老人看手机」的扭曲面庞就糊脸上了。
我一直跟裙友抱怨,这些设计师一看就是小年轻,因为他犯的设计执行错误实在太离谱了。**所有的图标,青一色,全没做像素对齐,所以看啥都是糊的。** In case you don't know, 蜀黍阿姨们还在玩设计的时候,屏幕分辨率都很低,为了让画面看上去锐利清晰通常都会尽可能避免锚点卡在半像素上导致次像素平滑。这设备的问题是,很多图标特别小,糊成一团基本就看不出来个形状,盯着瞅半天满脑子问号:这™是个啥?最荒谬的是,图标是糊的,文字渲染又是像素字体。
再比如,当你正在升级固件的时候,屏幕上会显示一个用中易黑、宋画出来的界面丑陋,而且提示文字竟然不在画面正中间!在日用的时候,如果你把语言切成法语,会发现带装饰符的字母和不带装饰符的字母大小还不一样,字母全都全都高高低低参差不齐。
还有更迷幻的,所有的位图 UI 素材看起来都像是先用有损格式导出,又转成了 BMP 最后嵌入固件的。所有贴图的明暗交界处都莫名其妙地多一圈白边,而且细节充满压缩后的噪点痕迹。总之,加上那说不上好的操作手感,用起来不免让人身心不适。
当然,它也有优点:长得挺可爱,很小,揣出去还能当个社交谈资。让我最喜欢的一点是,**它有两个耳机孔!** 一个平衡口,一个 3.5mm 接口,甚至能一起工作!这让我想起了上学时和好同学分享同一副耳机的青春碎月。现在有了这玩意儿,你可以和另外三个好朋友一起分享音乐了,四人同乐就非常的生草。
另外还有一些更离谱的玩法。
众所周知,索尼降噪大耳包基本上就是低音拉满玩命轰头,高频那边则是又糊又难听。但是我手边正好有个平头塞(YINCROW那款,最近刚买的),高音处理得还不错但是缺低音。那么问题来了,能不能让他们一个负责高音,一个负责低音嘞。
既然要强化低音,那不如就把 Clear Bass 直接拉到+10。平头塞就正常听,没加额外 EQ。
当我同时戴上两个耳机(就是把平头塞耳朵里,再把 XM3 罩在外面),然后轮流拔掉其中一个的插头,发现拔掉索尼,声音瞬间变薄,吉他指弹的泛音还在,但低频的箱体共振没了;拔掉平头,声音直接糊成一团,索尼那个闷糊感一下子就凸显出来了。两个一起的时候,竟然出现了真 正 的 音 乐 d(゚∀゚)b!
但这玩法不是没有代价的,输出相位肯定对不上,导致声音听起来特别「死」,像在水泥池子里游泳,空间感有很大的损失。
气氛上就是这样,硬件是好的,软件是烂的,烂的非常均匀彻底。不光软件 UI 设计是烂的,其实工程实践也是烂的,这点后面再说。
后来,我一气之下(其实也没太生气,就是动了个念想)开始尝试魔改固件?
固件魔改
初探
我几乎没有任何逆向工程的经验,上一次干这事儿还是在初中,早就忘光了。关于「逆向」这事情封顶的经验是研究被 Uglyify 的 JS 代码。所以,这活儿不是专业的人恐怕是真的干不来。
但是,咱有大语言模型是吧!
我试了下让 GLM 4.7 摸了一下固件大体的形状,他还真给分析出了点有料的东西。
最一开始,我和他讲「这有个固件,我的目标是把里面的位图给提出来,你告诉我咋整。」
他就告诉我,他需要 capstone, ghidra, r2pipe, rzpipe, angr。NixOS 装这些玩意的 Python binding 有一丢丢麻烦,但最后还是给配上了。
接下来他就开始自己扫二进制文件。没一会儿,芯片型号、SDK 型号全给扫出来了。他还找到了分区表,甚至自己尝试读取指令序列,发现了某种「固件加密」,做了修正程序(此处有巨大伏笔)。
后面,他爬到了文件内嵌的文件系统,顺藤摸瓜把 `.bmp` 文件全都给拽了出来了,我一看,图还真都是那么个形状。
但提取的时候也遇到了麻烦。那个 BMP 的颜色编码怎么都对不上。这地方就得我上场了,毕竟它不长眼睛,但我长眼睛。我负责看,它负责不停地试参数,最后我俩总算是把正确的解码参数给碰出来了。
字库提取
因为是像素图,所以有一个最简单的假设,字库的存储是二进制序列,0 是空白 1 是带字的部分。于是我掏出手机拍了一下屏幕上的汉字,然后开始数像素颗粒码到 TXT 文档里面当成搜索样本。不得不说,这还真得感谢它是大果粒像素字体!我能看清那一颗一颗的像素。
我把抠出来的几个字交给 GLM 4.7,告诉他「就这几个字,你想办法去扫扫看。」
结果意外的好,他通过各种垫 padding 还真把那像素字体存储的位置给抓出来了。
虽然找到了字形文件,但不知道数据结构是啥,也不知道索引表在哪。这就开始了漫长的盲人摸象。而且有一个很拧巴的点是,每隔几个字就会出现字符撕裂,就是左半边往上挪一点,右半边往下挪一点,隔一个字就来一下,完全不知道咋回事。
没啥招,只能看固件里面的文字渲染逻辑了。反正字在哪儿已经知道了,在地址上下摸一摸,总能摸出点东西。不到半小时,它就把渲染函数给摸出来了,然后一步步往上爬,最后找到了渲染公式。
但是这一直都没办法解释为什么会出现图像撕裂。为了解决这个问题,我们还一度怀疑是不是一些软硬件通信协议层面上的协定,甚至造了一个涉及 VOP DMA 的迷你渲染模拟器,问题都没抓出来。
一定是哪里出了问题,我当时一直陷入了一个死胡同里,认为是提取算法的问题。
撕裂的模式很明确左半边往上偏一点,右半边往下偏一点,隔一个字出现一次。于是我便尝试让 GLM 4.7 尝试找出偏移规律。这里面出现了一个很烦人的点,它经常打出一大堆 ASCII Art,明明打出来的字都已经扭曲了,但是他还是信誓旦旦地告诉我:对的,这是汉字,完整的汉字没问题。
但那个字明明已经裂开了。
LLM 是文本模型,它只能一行一行地横向读数据。 它看到的是一行行由点和井号构成的字符串,它能从统计规律上猜测「这看起来像汉字」,但它根本没有二维视觉,它看到的东西和人眼看到的完全不是同一件事。你要它判断一个字形对不对,它给你的不是视觉判断,是一个概率预测,而这个预测非常容易出错。
另外,他非常喜欢统计建模,认为「80% 对上了」比「50% 对上了」更好,哪怕它比对的可能完全不是一个东西。此时,你得非常耐心地告诉他,这东西只有完全对上了和完全对不上,没有只对得上一半的情况。
这件事反复发生了十多次。每次我说「你确定这是汉字吗?字都撕裂了,形状不对,字形不完整是好几个字拼在一起的」,它就道歉、重新分析,上下文爆掉压缩,犯过的错误被很糟糕的压缩提示词给搞丢,你明确告诉他「你要一列一列地读,不要一行一行地读」,他听了,然后过一会儿自动退回到行读模式。再告诉一遍,再退回去。你的指令对它来说是临时覆盖,不是真正改变了它的工作方式。
这个过程中我有几次情绪失控,直接开始飙骂。事后发现这是个非常具体的问题:你的情绪一旦注入对话,它会留在上下文里,甚至这些信息会在上下文压缩过程中保留下来(但是重要的方法论经验不会流下来),然后持续污染后续的推理质量。骂它之后,它开始把大量精力用来安抚你的情绪,而不是解决技术问题,并且前方百计地避免触发你的情绪感受,最后变得什么都不做,非常像人类的 FoF 反应。结果就是,推理越来越弱,你越来越烦,恶性循环。
这是个很实用的教训:和LLM协作时,你的情绪状态是工程变量,不是私事。
直到后面我开了一个新的上下文,请 LLM 做了一个渲染结果到 ROM 地址的映射可视化工具,我一块一块看,并且跟新的上下文做了确认,他问了我一句「你这固件文件哪里来的」?我把「修复脚本」给他看,他告诉我:那修复脚本 Fuck Up 了你的所有分析,他用错误的方式解读了固件把数据结构破坏掉了,所以才会出现字符撕裂的问题。
至此悬案解开了。
检字系统逆向
至此我们只找到了 CJK 区域的字,但是对于其他区域的字一无所知。我们看到了平面之间有大量纯 0 空白数据,有一段连续数据,中间又有大片空白,然后又是一大堆数据。LLM 说数据是分块存储的,并且狡猾地绕过了对那一大堆纯 0 数据来源的解释。
按照整个逻辑,如果数据是分片的,那么就需要有一个表,它就开始尝试产生一千零一种幻觉,试图把「查表」这个假说给硬凹出来。
另外,你也知道的,模型极不擅长数学,我给他几个样本字符,他「寻找规律」但一直告诉我没有规律,一定是查表得到的。于是我找了更多样本,甚至码着 CJK 码位搞出来了好几排字,让机器渲染出来,拍照,用 Gemini 的 Canvas 写了两个工具,造了一大堆的样本给他搜。
具体来讲,其中的一个工具是二进制序列复原工具,传入一张照片切片,自动切成16×15的格子,每格生成一个直方图,中间加一条拖动的分割线,标记左边是黑,右边是白,自动做二值化判断。之后我只需要拍照、传图、调分割线,字形就自动描出来了。
还有一个工具:给定一个位图,自动生成前后100个Unicode码位的字符表,点击某个字符就把对应的码位复制出来。这是因为当时根本找不到一个好用的Unicode码位查询网站,干脆自己造一个。
但是他一直在错误的上下文当中牵强附会,直到我把所有扫到的数据导出来扔给 Gemini 的 Canvas 做了一个线性回归拟合把公式甩回去之后……
嘿!它依然不听!因为这跟它看到的指令序列逻辑对不上。它说推出来的宽度是32,实际渲染的却是33。
这个问题卡了整整两天。
但好在我用 LLM 的习惯比较好,每次有研究成果都会直接输出一份 Markdown 笔记,并且有适度地维护整个文档库。于是我把整个文档库全都塞给了 NotebookLM,并且把整个问题上下文全都粘给 NotebookLM。NotebookLM一眼就看出来了:编译器把乘以33优化成了「左移5位再加原值」,即 `x << 5 + x`。 因为位移运算比乘法快,编译器会自动做这种替换,但 GLM 在分析反编译结果时没有识别出这个模式,所以一直把参数认成了 32。
这里又学到了两个重要的知识,复杂任务需要多个模型进行众议,一个模型很有可能会陷入知识盲区。事实上 Grok 最近也上架了一个集成多模型众议的模式,看着还挺好玩的。
上下文管理
到这个阶段,一个很明显的问题就被暴露出来了:**只要你的上下文窗口一大,塞的东西一多,它就会变弱智。** 当时我们俩生成的各种文档、日志、代码片段已经有好几千行了,它开始胡说八道,不停地抱怨,开始戳一步走一步,执行开始变得非常死板。
而且之前留下来的文档越累积越多,越来越长。如果一篇文档就能把上下文吃个大半,那整个研究便无从继续。所以是时候做 House Keeping 了。
结构化归档
第一步是把所有积累下来的文档一次性扔给 Claude,让它帮我整理成树状目录,每个知识点单独成文,文件之间互相索引,入口是一份导读。后续遇到具体问题时,只需要把目录加上相关的一两个小文件投喂给模型,而不是把整个研究历史都塞进去。上下文消耗量大幅压缩,模型能跑得更久、更准。
但这只解决了存量文档的问题。GLM 还有个坏习惯:让它记一份文档,它会偷偷创建三份。你的文档库很快就变成垃圾堆,所以借助额外的模型维持文档库是很重要的(但后面我发现 NotebookLM 做这事情效率更好一些)。
问题树
单纯归档还不够,因为它管的是「已知的知识」,而逆向工程推进的过程中,问题本身是动态生长的。
我维护了一份专门的问题树文档。这里面不是一个简单的待办清单,记录了整个问题空间的动态演化:一个大问题在研究推进中会衍生出若干子问题,子问题解决了一部分,又暴露出新的未知,新的未知再裂变成更具体的小问题。这棵树完整地记录了这个裂变过程。
这种结构带来的解决带来了两个好处。一方面,它对问题空间有一个高维度的抽象描述,你随时能看清楚「我们现在在哪、还有什么不知道、当前最重要的瓶颈是什么」,而不是淹没在一堆零散的技术细节里。第二,也是更关键的,它极大地帮助维护上下文的清洁。
具体来说:每次开启新的攻坚,我不是把所有研究文档都塞给模型,而是只把问题树的当前状态贴进去,从里面挑一个最重要的子问题,让模型围绕这一个问题生成任务指导书。模型拿到的是一个被高度抽象和压缩过的问题描述,而不是几天来积累的原始推导过程。这样它的上下文是干净的,推理质量就能维持在正常水平。
这一点在项目后期尤其关键。当研究推进到最深处、GLM 4.7 开始不停胡说的时候,我开了一个全新的对话窗口,把问题树的当前状态贴进去,挑出最重要的那个子问题,让 GLM 研究清单。原因很简单:它拿到的是一个干净的、经过抽象的问题,而不是被几天噪声污染过的上下文。
这套方法的核心逻辑是:大语言模型的有效工作窗口是有限的,你塞进去的信息越多,它能分配给真正思考的空间就越少。问题树做的事情,是把一个复杂项目的知识状态压缩成一个可以随时拎起来、随时投喂的抽象结构,它不记录你做了什么,它记录你还不知道什么,以及这些未知之间的关系。
NotebookLM
在整个逆向工程项目里,GLM 承担的是主要的执行工作,扫描二进制、反编译、写代码、追调用栈。但它有一个难以回避的缺陷:**它太容易顺着你的思路走。** 你给它一个方向,它会沿着这个方向一直推,推到撞墙为止,然后开始在墙边原地打转,却不会主动后退一步质疑这个方向本身是不是错的。
NotebookLM 在这个项目里扮演的是完全不同的角色。
任务书—任务报告的协作模式
套工作流的核心是把知识积累和任务执行拆成两个彼此独立的上下文。
NotebookLM负责知识侧:它的文档库里存放着所有的研究成果、问题树、技术文档。它不参与具体执行,它只读文档,然后输出任务书。
GLM负责执行侧:它拿到任务书,专注执行,完成后输出任务报告。它的上下文里只有当前任务的执行细节,不需要记住整个项目的历史。
具体流程是这样的:
项目卡住,或者一个阶段告一段落,我让NotebookLM读当前文档库里的所有研究成果,生成一份**任务书**。任务书的结构是固定的:问题陈述(我理解你现在卡在哪里)、分步课题(把大问题拆成三四个可管理的小目标)、任务清单(每个目标下列出具体步骤,明确说动作是什么、目的是什么)。
我把这份任务书原样交给 GLM 执行。不加任何个人解释,不加任何情绪,就是一份简简单单的结构化文档。
GLM执行完成后,输出一份任务报告:研究目标、关键发现、结论、遗留问题、下一步建议。同样是固定结构。
我把这份任务报告上传进NotebookLM的文档库。NotebookLM读取最新报告,结合已有的全部文档,生成下一份任务书。
循环往复。
表面上看,我只是在两个模型之间来回传文档,但它解决的是一个很麻烦的问题:上下文污染。
正常的人机对话模式里,你的情绪、你不专业的描述、你那些啰嗦的废话、你的错误假设,全都会随着对话积累进上下文,然后随着压缩过程被保留下来,持续干扰模型的推理质量。骂它一句,这句话会留着;给了一个错误的前提,这个前提会留着;绕了一大圈弯路,这段弯路会留着。上下文越长,这些垃圾积累得越多,模型的推理能力就会变得越弱。
任务书机制切断了这个污染路径。NotebookLM 只读结构化文档,这样就不存在你和 GLM 之间的聊天记录;GLM只执行任务书,不需要理解整个项目的来龙去脉。两者之间传递的全是格式化的、无情绪的、经过提炼的信息。
这相当于变相拓展了整个系统的有效上下文空间。不是把一个模型的上下文窗口变大,而是把知识和执行分离存放,让每一侧都只承载它真正需要的信息。
GLM 看到任务书之后会表现出一种很「兴奋」的态度,表示「哦,原来可以这样做!」然后 GLM 又能跑一段了。跑一会儿,又哭了。我再把新的问题陈述扔给 NotebookLM……
基本上,我就成了个「人肉管道」(SPL, System Prompt Line)。我看他俩聊得火热,但我一个人是懵的,很多细节我根本不懂。我只负责在他俩之间来回传话,全程发懵,只能在旁边鼓掌:「大佬们真棒!」
不过这事情后面有了更加自动化的解决方法,用了这个 Skill 之后,只要提示词给好,让它俩自己聊就行了,我也不用来回复制粘贴了。
让两个模型吵架
这套机制还有一个变体用法:当某个技术问题存在争议时,我会让两个模型互相批判对方的方案。
提示词是固定的:「请系统性的用逆向分析工具调查,并用建设性批判(constructive criticism)的方式回应以下观点。」
GLM 给出结论,交给 NotebookLM 批判;NotebookLM 给出修正,交回 GLM 批判。来回几轮之后,一个经过双向检验的分析框架自然浮现出来。两个模型单独面对人类输入时都倾向于顺从,但面对另一个模型的结论时批判性会明显提高。字符渲染管线最难啃的部分就是用这个方式调出来的。
我在这套机制里做的事情只有三件:决定什么时候切换(执行卡死了就切到NotebookLM)、判断任务报告的结论是否可信(模型没有眼睛,视觉判断必须由我来做)、以及维护问题树(决定下一个最重要的子问题是什么)。
其他所有事情,都在这个机器对机器的闭环里自动完成。
这是整个项目里最重要的一个方法论发现:虽然聪明的模型很重要,但是一个不会让它变笨的工作环境也很重要。
LLM 开始胡说时,说明你喂的信息可能不够了
这是整个项目里反复验证的一条规律,也是最反直觉的一条:当 LLM 开始四处碰壁、原地打转、输出越来越离谱的结论时,第一反应不应该是换个提示词,而是问它:你缺什么信息?
第一次:找TRM手册
字库逆向推进到一半,GLM开始出现典型的「信息饥渴」症状,静态分析反复声称「找到了函数入口」,但给出的地址在固件里根本不存在;推导链条越来越长,结论越来越玄;每隔几轮就说「我已经达到了静态分析的极限」。
我停下来直接问它:你现在需要什么才能继续?
它说:我需要这颗芯片的 Spec 和 TRM。Spec 是硬件规格书,TRM 是技术参考手册,里面有完整的指令集、寄存器定义、内存映射。没有这些,它只能靠猜,而它已经猜不下去了。
芯片型号是 Rockchip RKnano D。我去搜,找到了一份 Spec,但 Spec 只有硬件层面的参数,没有指令集。TRM 才是真正需要的东西,但搜遍常规渠道,什么都没有。
搜索过程中找到一个日本人的网站,上面列出了两条URL,分别指向硬件文档和指令集文档。点进去之后赫然弹出了一个 404。
TRM那条链接死了。
我盯着那个 404 的 URL 看了一会儿,然后把之前有效的 Spec URL 并排放在一起对比。一级域名相同,二级域名不同,一个是 Wiki 子域,一个是主站域名。网站搬过家,内容从 Wiki 迁到了主站,但日本人的那个网站上记录的还是旧地址。
我把 TRM 那条 URL 里的子域名改成主站格式,刷新。
文件下载成功了。
这是一个纯粹靠人的思维方式才能解决的问题。几乎不会有模型去盯着一个 404 的 URL 想「这两条链接的域名结构有什么关系」,它只会告诉你「文件不存在」然后建议你换个搜索词。发现 URL 结构规律、推断网站迁移、手动修改路径,这个推理链条需要的是人对网站运作方式的隐性经验,不是模型能做到的。
TRM 到手之后,我把它交给 NotebookLM。它拿到文档,立刻找到了之前那些「不存在的地址」对应的硬件机制,卡了很久的分析线索重新跑起来了。
顺手把这份 TRM 手动备份到了互联网档案馆,发现几年前已经有人备份过,只是没被搜索引擎收录。白忙了一场,但也只是浪费了一点时间。
第二次:把设备本身当文档
推进到硬件模拟阶段,GLM 在判断某些具体硬件规格时又开始乱说。这次我没有去找外部文档,而是想到了另一个信息来源:设备本身。
我把播放器的软硬件版本号、以及播放器官方页面上列出的产品 Spec 全部整理出来,一起交给 GLM。
这些信息看起来很普通,甚至有点像凑数,但它为一处基础的硬件版本判断提供了重要的数据锚点。顺着条件判断逻辑树一路往后推,发现了几处和之前推理对不上的地方,顺着这些矛盾点往回追,核心的硬件规格判断问题得到了突破。最后关于文本渲染的完整调用栈被彻底抓了出来,这也直接促成了 Flame Ocean 的字库检索和替换工具的完成。
刷!到!设!备!里!
研究推进到一定阶段之后,有一件事必须搞清楚:刷机有没有签名校验?
不管固件逆向做得多漂亮,如果设备在写入时会验证固件签名,一切努力都白费。
我先让 GLM 扫了一遍固件,问它有没有发现任何签名校验或安全防护机制。它言之凿凿地说:没有找到任何防护措施。
但这个结论站不住脚。「没找到」不等于「没有」这是个典型的条件概率问题,就像统计学里 p 值不显著不能说明没有效应一样。没有证据不是没有的证据。
于是我换了要求:不能凭空下结论,必须用反编译数据做实际佐证,找到代码,看到逻辑,才能说话。
接下来我让模型M认真去扫,还真找到了东西,固件里有一个 CRC 校验的函数。但这个函数非常奇怪:返回结果只有 8 bit。
与此同时,固件最尾端有一段数据,结构上看起来非常像某种校验哈希。之前我大概研究过一下, Rockchip 自己有一套叫 RKCRC 的算法,这段数据的位置和格式都很符合。但追了半天,也找不到任何验证逻辑去读取或比对这段数据。
结论和直觉完全对不上:从固件结构来看,它应该有校验;从代码逻辑来看,找不到任何地方在做校验。
静态分析给不出确定答案,于是我头铁直接把做了一点修改的刷机包塞到了机器里。它真的一点校验都没做就把我的固件包给吃下去了,中间没有任何拦截。
我去问了群里做硬件裙友。他们告诉我,这类低端MP3设备,校验一般做在刷机软件里,不做在硬件上。而且 Snowsky 这台设备的刷机方式本来就很奇特,你只需要把刷机包复制到根目录,设备开机自动检测到就会升级,不需要专用的刷机工具。so……
也有裙友告诉我,哪怕很多车机的固件升级也不会做任何完整性校验,如果你把下载了一半就断掉的固件喂给它,你的车就会被刷成超巨大黑砖,也算是长见识了。
工具的成型
研究材料都备齐了,接下来就是写一个小工具,用来做资源编辑和替换。整个工具是用 Svelte 搞的,我基本也没亲自动手写,直接让 LLM 帮忙做了简单的组件封装,界面突突突就给做出来了。说真的我也没太在乎美丑,就是个实用工具而已。出于好玩的心态,我给这工具起了个名字叫 Flame Ocean,as you can see, Snow Sky 的相反。
工具写完,扔到了 Reddit 上,几乎是同一天立刻就有人把 Boot Screen 动画换掉了,还发了个 PR 过来,可以自动把视频变成序列帧动画(虽然那 PR 的品质有点低,我花了一整天才把它的 UX 修到可以接受的水平,但还是感谢社区参与)。
后面陆续开始出现各种改 Mod 的案例,前几天都是简单开机画面魔改。上传官方 firmware 到 flame-ocean.not.ci,点一下「Replace Image」,下载新 bin 文件,刷机。几分钟后,你的二刺猿老婆就住到设备里了。
再过几天,更加彻底的魔改皮肤开始出现。我最喜欢的是这个破真磁带机主题、EVA 主题、 Fallout 主题。这个仿 macos 的主题也挺好玩的,而且作者提出了 pixel perfect 的重要性。
社区的环境也挺不错的。后面出现了一个网站专门收集魔改固件。如果有新手提问,没过多久就会有人在下面答疑,来自社区的魔改教程文档也开始出现了。
当 LLM 变成老虎机
关于大语言模型的心理健康风险,现有的讨论集中在两个方向:用 LLM 做心理咨询反而让心理变差,以及用 LLM 写代码产生冒牌者综合征。这两个问题都有人讲过,我不想重复。
我想借着这篇文章讲一个没什么人讨论过的问题:持续性奖赏刺激。
整个逆向工程项目期间,我把很多晚上耗到凌晨三点。同学在小组作业会议里听到我的声音,问:你还好吗?我说没事很好。但我手表告诉我已经长期处于应激状态,身体和心理都在承受持续的消耗,我自己完全没有察觉。
原因不是项目难,而是大语言模型制造了一种**极高密度的实时正反馈**。
每发出一个任务,五分钟内就有进展报告。每份报告都把当前的进展描述成突破性进展。解决一个子问题,立刻暴露出下一个子问题在等待。这个循环没有自然的停顿点,没有「今天做完了」的时刻,只有永远的「再推一步就出来了」。
对于ADHD患者来说,这个模式和赌场老虎机在神经机制上是同构的。老虎机的设计原理是**变比率强化**,不是每次都赢,但赢的时刻不可预测,这种不确定性制造的多巴胺刺激比固定奖励强得多。大语言模型的协作过程完全符合这个模式:大多数时候在推进但没有突破,偶尔突然跳出一个关键发现,然后立刻又陷入下一个未知。你永远不知道下一个任务书执行完是平淡收场还是重大突破,但你迫切地想知道。
再来一把。再推一步。说不定这次就出来了。
这件事对普通人也有影响,但对ADHD患者的杀伤力则是另外一个故事。
ADHD 的核心机制之一是执行功能出现问题,他们难以启动任务,但一旦进入高度感兴趣的状态,又极难主动脱离。这不是意志力问题,是神经层面的调节困难。大语言模型的高频反馈恰好精准地触发了这个机制的第二面:它不停地用小奖励把你钉在椅子上,让你的大脑持续处于「再做一点就完成了」的错觉里。
与此同时,我对这个项目的难度存在系统性低估。我不懂逆向工程,所以我评估不出来「找到 Unicode 到字形的完整映射公式」这件事究竟有多难。不懂的人倾向于低估难度,低估难度就会持续觉得「马上就好了」,而大语言模型每次给出的进展报告又在不断强化这个错觉。我在想象这件事成功的样子,我在追逐一个我以为触手可及但实际上还很远的终点。
这是一种很隐蔽的痛苦,一点一滴的把你的精力榨干。你不会觉得自己在受苦,你会觉得自己在全力冲刺。直到精疲力竭你才意识到某种痛苦,但是人却完全无法脱离这个高速反馈的实时环境。
冒牌者综合征的问题是:LLM 替你做了事,你怀疑自己的能力。这是一个关于自我认知的问题。
我描述的这个问题不同。它不质疑你的能力,它消耗你的身体。它利用的不是你的不自信,而是你对进步的渴望、对完成的执念、以及你大脑里那个停不下来的奖赏回路。它和赌博成瘾、手机上瘾的底层机制是一样的,只是包装成了「我在做一件很有意义的事」。
在我写这篇文章的当下,所有待解决的问题还没有清理干净。我也没有找到一个好的方法在保持高效协作的同时主动踩刹车。我能做到的只是把这件事说清楚,让下一个陷进去的人至少知道那种停不下来的感觉不只是热情,也是一个需要警惕的信号。
So What
通过这一顿狂暴折腾,逆向工程基本上是跑通了。我用 LLM 写了各种调试用的小工具,甚至还写了个很小的硬件模拟器模拟字符渲染,最终把字库渲染那一坨屎山给基本搞明白了。
但这个过程也让人有点担心。
你想想,我,一个只做过前端、只会解混淆 JS 的菜狗,靠着两个 LLM 吵架,就能把一个设备的底层固件给拆得七七八八。这意味着什么?这意味着未来「脚本小子」的门槛被无限拉低了。
而且,那个全自动的未来已经很近了。
最一开始我还是那个坐在中间手动传纸条的人:从NotebookLM取任务书,贴给GLM执行,把报告取回来,再送回NotebookLM。整个流程是自动化的,但调度靠人。但是 NotebookLM Skill 的出现把这一步也省了,我只需要坐椅子上盯着就行了。
另外,DeepSeek最新发表的稀疏注意力机制,在相当程度上缓解了本文反复提到的那个核心痛点:上下文一长模型就变弱。如果这个问题被真正解决,「人」的参与空间会进一步被压缩,原本需要人来判断「现在该切到哪个模型」的那个决策,也开始可以被自动化。
更值得警惕的是另一件事:很多能力很强的大模型是开源的。这意味着只要你有足够的算力,相当多大语言模型的行为可以完整运行在你自己的机器上,不经过任何第三方服务,不受任何平台审计。一套完整的逆向工程流水线从固件扫描、反编译、漏洞识别、利用路径推导,这当中的每一步理论上可以在任何人的地下室里全天候不间断地跑,针对任何一个目标。
目前这条路还有一道真实的门槛:小模型的推理能力依然不够。IQuesta Coder 这类自称 SoTA 的轻量模型,在面对稍微复杂一点的工程任务时,连 OpenCode 的基本文件编辑命令都拉不利索,更不用说独立完成完整的逆向分析链条。复杂项目依然需要大模型,大模型依然需要算力,算力依然需要钱。这道门槛现在还在。
但它在变低。
我做这个项目的出发点只是嫌一台 MP3 的 UI 太丑。沿着这条线走下来,在一个完全不是我专业领域的方向上,借助两个模型和一份手册,把一颗嵌入式芯片的字符渲染管线从头到尾摸了个七七八八。我不是安全研究员,我没有逆向工程背景,我只是有耐心,会提问,懂得什么时候该喂什么信息。
如果这件事换成一个真正懂安全的人来做,换成一套自动化的流水线来做,换成一个不需要睡觉、不会情绪崩溃、上下文永远干净的系统来做,它能做到什么程度呢。
或许不会有白痴希望把自己车机的开机画面改成二刺猿老婆,但是你正开在高速上突然车机上跳出来一个 Jump Scare,也挺吓人的。
那个全自动的未来不是科幻,它已经在路上了。
