文章总结: NoNo是一款开源的WindowsPE自动补丁验证工具,核心功能是将扫描候选PE、四种注入方法打补丁、运行存活检测和保留存活副本串成全自动流水线。工具支持entrypoint、function、tlsinject和eat四种注入方法,优先原地覆盖代码以降低静态指纹。自检模块可量化评估payload隐蔽性,形成反馈闭环。文档强调工具仅供授权安全研究使用,对防守方而言,批量补丁的共性指纹和进程存活模式可作为检测信号。 综合评分: 85 文章分类: 安全工具,免杀,红队,渗透测试,安全开发
工具 | NoNo 更新——自动 Patch 验证
mimi3389 mimi3389
赛博生存指南
2026年7月6日 17:38 浙江
在小说阅读器读本章
去阅读
手工给一个 PE 打补丁不难。难的是——几百个候选文件、四种注入方法、每个还要跑一遍验证存活,全靠人肉? 这次我们把自己写的工具 NoNo 拆开,看它怎么把「扫描 → 注入 → 运行 → 留存活副本」串成一条全自动流水线,以及最新版为什么又给它加了一面「自检的镜子」。
项目地址:https://github.com/din4e/NoNo/
网盘:https://pan.baidu.com/s/1ZvoX_dM18HsJRDUsZuK7rg?pwd=cur5
开头:手工 patch 的痛
想象你在做注入研究。经典剧本是这样的:挑一个白文件,选一种注入方法,patch,运行,看它崩不崩、活不活。崩了就换一个方法,或者换一个文件,再来一遍。
听起来没什么,但你把规模放大试试——
一个目录里几十上百个候选 EXE,每个都要试 4 种注入方法,每种都要跑一遍看存活。 那是 几百次「选文件 → 选方法 → 打补丁 → 双击运行 → 等结果 → 留副本」的循环。中间任何一次 patch 把进程搞崩了,Windows 还会弹一个 WER 崩溃对话框怼到你脸上,批量跑直接卡死。
所以 NoNo 想解决的就一件事:把这条循环,自动化成一条流水线。
它是我们自研的 Windows PE 扫描器与代码注入研究工具(GUI + CLI 双入口),核心卖点从 v0.0.3 起就是这条 autotest 自动批量流水线。下面把它一层层拆开。
一、流水线全貌:扫描 → 注入 → 运行 → 留存活副本
一条命令,对整个目录跑完四个阶段:
nono-cli autotest -dir"C:\test" -sign unsigned \
-methods entrypoint,tlsinject -template template_sleep \
-out "C:\nono-results"
四个阶段是串起来的,每个阶段的产物喂给下一个:
1. 扫描候选 PE。 按大小 / 架构 / 签名状态 / 扩展名过滤目录,挑出适合下手的白文件——小体积、未签名、依赖少。worker pool 并发扫,几百个文件几秒出清单。
2. 各方法注入。 对每个候选,依次用选定的方法(function / entrypoint / tlsinject / eat)打补丁。这一步的关键纪律是——原文件永不修改:源 PE 先拷一份到可写输出目录,对副本做原地 patch,再写出 _patched 文件。源文件动都不动。
3. 运行存活检测。 把 patch 后的文件真的拉起来跑,等一个超时窗口(默认 2 秒),「进程仍在」即判定存活。比如 MessageBox 模板会弹窗阻塞、进程挂住不退出 → 存活;patch 写崩了 → 进程秒退 → 不存活。
4. 保留存活副本。 只有「任意一种方法存活」的目标,它的存活副本才会被留到输出目录。你最后拿到的,是一份已经验证可执行的 patch 成果清单,还能一键导出 JSON / CSV。
一句话:你给它一个目录,它还你一堆「确定能跑起来」的 patch 后文件。
二、四种注入方法:原地覆盖优先,能不碰头部就不碰
四种方法都基于 BinHol 的原地覆盖思路——优先吃目标自己的代码空间,不加新区段、不改 PE 头,尽量不留下结构性指纹:
| 方法 | 怎么做 | 头部改动 |
| — | — | — |
| Entry Point | 直接原地覆盖入口点代码 | 零 |
| Function | 覆盖入口点两跳内的被调函数体 | 零 |
| TLS Inject | 新建 .tlss 段 + 真实 TLS 目录 + 回调数组,关 ASLR | 有(方法本质决定) |
| EAT | 修补 DLL 导出地址(仅 DLL) | 有 |
前两种是「最干净」的——头部零改动,静态上几乎看不出被动过手脚,主要靠代码本身的质量扛检测。后两种有固有指纹(关 ASLR + 新可执行段 / 导出 RVA 越界),是方法本质决定的取舍。模板则是内嵌进二进制的(//go:embed),不随程序分发额外文件,CLI 和 GUI 共用同一份。
三、怎么判断「存活」——Windows 崩溃处理这块硬骨头
批量跑最容易翻车的地方,不是注入本身,而是patch 写崩了怎么办。一个崩掉的进程会拖累整批测试,NoNo 用两件事扛住:
- 继承
SetErrorMode:子进程继承「不弹 WER 崩溃对话框」的错误模式。patch 再烂也不会弹窗卡死批量流程。 - 每进程一个 Job Object:返回时把整棵进程树整体回收。哪怕 patch 出来的进程又 fork 了一堆子进程,也不会泄漏成僵尸,把测试机拖垮。
这套机制让 autotest 可以放心地对几百个文件连续打补丁、连续运行,而不用人盯崩溃对话框。这是「自动化」能真正成立的工程前提——不是写个 for 循环就叫自动化,得能无人值守地跑完一整夜。
四、自检闭环:自动化不只是「打补丁」,还能「给自己打分」
如果自动化到此为止,它只是个「批量打补丁机器」。v0.0.5 给它加了一面镜子——自检模块(detect),这才把流水线闭合成一个反馈环。
自检模块量化一段 payload 或一个 patch 后 PE 有多容易被静态抓到,规则字节级复刻 huoji120/white_patch_detect:
- GS→PEB→Ldr 解析链:自解析 shellcode 不走 IAT,第一跳必是
gs:段访问——这是核心信号。 - 明文 / 内联 cmp 的 API 名:嵌入
GetProcAddress字符串,或逐字符cmp比名字,都会被抓。 - 高熵区:256 字节窗 Shannon 熵超阈值,加密 / 压缩 blob 的指纹。
- PE 头部规则:关 ASLR + 可疑可执行段(tlsinject 指纹)、导出 RVA 越界(eat 指纹)。
于是工作流变成:自动批量打补丁 → 自检给每条 payload 打分 → 按分数反推哪条模板 / 哪种方法最隐蔽 → 改模板 → 再跑。一个真实结果:template_1(逐字符 cmp 解析 API)自检 71 分,换成 ROR-13 哈希变体 template_1_hashed 后降到 15 分——全模板最低。这条「改前 71 → 改后 15」的曲线,就是自动化 + 自检闭环给你的、可量化的加固反馈。
诚实地说:自检是字节层比较器,不是产品级 AV。变址形 gs 访问能骗过字节规则,要抓全得做寄存器污点追踪。它回答的是「这版 payload 比上版更难被抓吗」,不是「这版一定能过 AV」。
五、对研究者 / 防守方的启示
对做注入研究的人,NoNo 的价值是把**「打补丁 → 验存活 → 评估可检测度」**三件本来很碎的事,压成一条可重复的流水线——尤其适合做模板 / 方法的横向对比,用数据说话而不是凭感觉。
对防守方,反过来读这条流水线同样有用:
- 批量打补丁的共性指纹值得建规则。哪怕头部零改动的 entrypoint / function 方法,注入的 payload 字节本身(gs 解析链、高熵 blob)仍是静态抓手。
- 「进程存活即成功」是个可观测信号。patch 后立即拉起、短超时后仍存活的运行模式,本身可以是行为层的轻量告警点。
结尾:自动化是中性的
把 patch 做成流水线,本质是「把一件重复的工程,压缩成一条可重复的命令」。这在正当的注入研究、免杀评估、防御规则验证里,是省力的工具;同样的能力,脱离授权语境就是另一回事。
工具没有善恶,区别在于握着它的人,有没有那纸授权。
⚠️ 合规提醒:NoNo 仅供授权安全研究 / 漏洞评估 / 安全审计使用。未经授权对他人系统打补丁、访问或干扰,是违法行为。本文为自研开源工具的技术介绍。
如果觉得有用,欢迎点「在看」/ 转发给同行。 NoNo 提供 GUI(Wails 桌面端)与 CLI 双入口,autotest 批量流水线 + 自检模块均在最新版可用。
免责声明:
本文所载程序、技术方法仅面向合法合规的安全研究与教学场景,旨在提升网络安全防护能力,具有明确的技术研究属性。
任何单位或个人未经授权,将本文内容用于攻击、破坏等非法用途的,由此引发的全部法律责任、民事赔偿及连带责任,均由行为人独立承担,本站不承担任何连带责任。
本站内容均为技术交流与知识分享目的发布,若存在版权侵权或其他异议,请通过邮件联系处理,具体联系方式可点击页面上方的联系我。
本文转载自:赛博生存指南 mimi3389 mimi3389《工具 | NoNo 更新——自动 Patch 验证》
版权声明
本站仅做备份收录,仅供研究与教学参考之用。
读者将信息用于其他用途的,全部法律及连带责任由读者自行承担,本站不承担任何责任。











评论