|
|
本帖最后由 2010hook 于 2026-7-10 12:02 编辑
原作者:Sean Loaring,Slore
原地址:https://github.com/slorelee/binmay
Binmay 是用于文件或流中搜索替换二进制字符串的命令行工具,更通用。
近期,DeepSeek 编程能力增强了,我令其以资深编程专家角色多次优化源码,结果喜人。
binmay3 掩码增强:更灵活的掩码语法与搜索控制,中文使用手册有详细用法示例。
- 原始版:掩码仅支持显式十六进制字符串或自动生成的 `0xDF`(大小写不敏感),精确但灵活不足。
- 增强版:
- 增加通配符 ?? 和 .. :可在掩码串中使用 `??` 或 `..` 表示忽略对应字节,等同 0x00,共三种。例如 -S "??AA..BB00CC"。
- 索引列表语法:支持 `!`(忽略序数)和 `=`(仅匹配序数),以0开始,要双引号。例如:
-S "!0,4-6" → 忽略第 0 和 4-6 个字节,其余强制匹配。
-S "=0,4-6" → 仅匹配第 0 和 4-6 个字节,其余忽略。
列表接受空格、逗号、范围,极大方便了对特定位置的模糊匹配,解决了手工编写冗长十六进制掩码的痛点。
- 可删除搜索串:允许 `-r t:`(空替换),实现删除功能。
- 显式 `-S` 警告:当 `T:`/`U:` 自动生成大小写掩码时,若已通过 `-S` 显式设置了掩码,程序会警告并优先使用显式掩码,避免意外覆盖。
注意:
常见 ?? 和 .. 属于Byte级,会忽略256种可能组合,并非高大上。索引列表的价值更大。
十六进制 0~F (16x16种组合) 才是精确匹配bit,须用二进制推导!掩码底层是二进制,0 表示忽略,1 表示匹配。
------------------------- binmay2 完美版 ------------------------------
一、全局状态彻底整合,消除散落的全局变量
- 原始版:大量全局变量(verbose、UseBinaryP、pukebuf、plen、matches 等),函数间通过隐式全局通信,测试与复用困难。
- 优化版:全部状态归入 struct app_config,在 main() 中实例化,通过参数传递。配置文件备份路径、临时文件等字段一清二楚。
- 收益:逻辑内聚,可重入,为多线程或库化打下基础。
二、内存管理从“用完不管”升级为“有借有还”
- 原始版:自制 f_malloc 内含错误类型转换,且所有动态分配均未释放,完全依赖操作系统回收。出错时直接 abort/exit。
- 优化版:所有动态分配的资源(文件句柄、缓冲区、掩码结构)都在 main 或 cleanup 路径中释放。错误信息更具体(显示请求大小)。
- 收益:零内存泄漏,批量处理上万文件不会耗尽资源。
三、错误处理:从“自爆”变成“层层上报”
- 原始版:大量 abort()、exit(1),遇到任何问题立即终止程序,不留任何恢复余地。
- 优化版:函数返回值统一为 0 成功 / -1 失败,错误逐层向上传播。main() 根据返回值决定清理和退出码,即使出错也会尝试保留现场。
- 收益:在批处理脚本中可捕获退出码,不再因单个文件错误而中断整个流程。
四、原地更新(-u/-U)实现了原子写入,杜绝数据损坏
- 原始版:直接重命名原文件为 .org,然后在原路径上写新文件。若中途失败,原始文件已改名,数据可能永久丢失。
- 优化版:先输出到临时文件(原文件名.bintmp),所有处理成功后再执行重命名链。失败时保留原文件与临时文件,并在控制台给出明确恢复指令。
- 收益:符合“原子写入”原则,彻底防止因磁盘满、断电等意外导致文件损坏。
五、I/O 性能大幅提升,适应大文件与长模式
- 原始版:缓冲区 1KB,搜索/替换模式上限 1KB。处理大文件(如固件镜像)时频繁系统调用。
- 优化版:I/O 块大小提升至 128KB,模式长度上限同步增至 128KB。非0首字符匹配滤除大部分。
- 收益:处理上百 MB 的文件时,性能提升百倍;可应对超长二进制特征码搜索与替换。
六、Windows 平台兼容性专项加固
- 原始版:完全忽略 Windows 文本模式换行转换问题;错误引入 <sys/unistd.h>。
- 优化版:启动时通过 set_binary_mode() 将 stdin/stdout/stderr 设为二进制模式(_O_BINARY);使用条件编译处理平台差异。
- 收益:在 Windows 上彻底避免 0x0A → 0x0D 0x0A 的破坏性转换,保证二进制操作正确性。
七、命令行解析更严谨,用户操作更友好
- -b 强制前置:必须出现在所有字符串参数之前,防止后期参数解析歧义,否则直接报错。
- 互斥检测:-i/-o 与 -u/-U 不可混用,并给出明确错误提示。
- 文件名长度检查:使用 sizeof 和 FNAME_MAX 防止缓冲区溢出。
- 错误信息:输出包含程序名、选项,更符合 GNU 风格。
- 中文手册:全面详尽的中文使用手册,Markdown格式。
八、搜索替换引擎算法更精确、更高效
- 符号位修正:所有位运算操作统一转换为 unsigned char,避免 0x80 以上字节因符号扩展产生错误。
- 大小写兼容:hex 转换函数 hval 现在同时支持大小写字母 A-F/a-f。
- 搜索加速:masked_string_seek 增加“非0首字节快速跳过”判断,不匹配时直接跳过后面的逐字节比较。
九、代码结构清晰化,可维护性飞跃
- 清除所有未实现的函数声明(open_outfile 等)。
- 拆分 process_string 为 process_string_default,内部按格式前缀路由。
- 移除全局依赖,所有函数通过参数获取配置(如 binflag)。
- 删除残留的调试宏 DEBUG。
- 将 strcpy/strcat 全部替换为长度受限的 snprintf 或预先校验,杜绝栈溢出。
十、边界条件与空值防御
- 明确拒绝空搜索字符串,防止逻辑错误。
- 只给替换不给搜索时直接报错退出。
- load_file 和 buffered_read 增加 ferror 检测,区分 EOF 与读取错误。
- fread 返回值判断修正(fread 返回 size_t,不会是负数)。
总结:对错误处理、数据安全、性能、功能扩展性和跨平台兼容性等方面进行了全方位、专业级的重构,使其从“可用的”进化为“健壮的生产级”,同时保留了原始算法中缓冲滑动窗口和掩码按位合并的优秀思想。 |
-
-
binmay.7z
32.64 KB, 下载次数: 54, 下载积分: 无忧币 -2
开源,TinyCC 编译
|