一个能拖动、能最小化最大化关闭、右上角带系统菜单、正中央还画着文字的“完整”Windows程序,可以小到383字节——比一张表情包还小几十倍。这是GitHub仓库HelloAssembly给出的答案,源头是Dave's Garage频道两期复古编程视频。但README里藏着一句不太起眼的提醒:这么抠出来的程序,很可能被杀毒软件当成病毒直接隔离。

体积和“像不像病毒”,在这个项目里成了同一个问题的两面。

三个版本,三种抠法

仓库放了三份实现,用不同链接器和技巧逼近“最小完整Windows程序”这条线:

实现目录链接工具最终体积核心手段
LasseMASM321104字节常规链接
LasseCrinkler818字节压缩链接
TinyOriginalCrinkler540字节直接函数指针+压缩
TheronYasm383字节手写PE头

Theron目录手写PE头,把常规链接器留下的对齐字节、库名填充统统砍掉,还把消息结构塞进BSS段省声明,两次提交就从396字节降到383。Lasse目录走shellcode套路:不老实查导入表,而是遍历进程环境块PEB,动态解析需要的API地址,配上“egghunter”式内存搜索,把Windows GUI程序写成了黑客工具的样子。TinyOriginal目录靠Crinkler这款专为几KB级可执行文件设计的压缩链接器,同样的代码,MASM32链出1104字节,Crinkler链出只要818字节,少了近三成。

从1488字节到383字节,两年磨一个数字

这不是一次性成果。2021年的首期视频里,常规链接版本是1488字节,当时用Crinkler做的799字节版本甚至跑不起来。直到2023年初续集视频,项目才被重新激活,社区贡献者陆续加入,一点点把数字往下磨:TinyOriginal方案在2月到3月三次提交里,从596字节一路降到572、542,最终定格在540字节——这正是README体积表里被截断、没显示出来的那一行。

体积瘦身两年史 2021.3 1488字节 常规链接 2021.4 799字节 跑不起来 2023.1 续集视频 社区重启 2023.3 383/540字节 两版定稿

越小,越像病毒

问题出在这里:压缩到这个量级用的手法,和恶意软件加壳器的手法,在结构层面几乎是同一套。

同一套手法,两张脸 demoscene优化 恶意软件加壳 体积小于1KB 体积小于1KB 不查标准导入表 隐藏导入表 自定义PE头 伪造PE头 代码压缩自解压 自解压载荷 特征几乎相同

不查标准导入表、自己写PE头、代码压缩自解压——这些特征本是demoscene圈子几十年的传家宝,恰好也是Defender这类启发式引擎判断“疑似加壳恶意软件”的强信号。README点名F-Secure SAFE和Microsoft Defender都会误报,让用户自己决定要不要临时关掉杀毒软件。这不是孤例:同源的TinyRetroPad项目也报告过,890字节的激进压缩版本会让Defender“相当不满”,退一步用轻量压缩才能换回一个能跑的版本。

  • 风险.体积优化和恶意代码在PE结构层面高度同构,启发式检测越激进,良性极限项目被错杀的概率越高。

误报好修,但修不干净

比误报本身更麻烦的是修复流程。有开发者在微软官方社区反映过,一个已被判定为误报、解除隔离的可执行文件,过一阵子换个检测规则版本又被重新标记——申诉不是一次性生效,而要跟着Defender的规则库反复打地鼠。微软自己的文档也承认,高普及度文件和企业签名提交的申诉,处理优先级天然更高,独立开发者的几百字节小程序排在队尾。开源代码本身干净,不代表你从任何渠道下载到的可执行文件干净,README那句“我们保证仓库代码没问题,但不保证其他来源的构建产物”说的就是这层意思——很多人下意识把“开源”和“可信”划等号,中间其实还差一道编译和分发。

把程序做小是手艺,把小程序做得不像病毒,才是真本事。

我更在意的是这场冲突背后没有胜负,只有成本转移。demoscene式的极限优化本来是致敬底层机制的游戏,PE格式、消息循环、导入表,每一个都被榨到骨头缝里。但当安全厂商越来越依赖“体积异常小+导入表精简+自定义头部”这类结构特征做判断,良性实验和真实恶意软件就共享了同一张嫌疑名单。Defender不是不该报警——面对真加壳器,这套启发式确实有效——问题是修正机制没跟上:申诉不透明、结果不持久、小项目没有议价能力。关掉杀毒软件测试可以救急,但不是长久出路,真正该解决的是让“体积小”和“意图恶意”这两件事,能被更精细地分开判断。