Loading... # 破解 40 年前的软件复制保护加密狗 # 一、事件概述 ## 1. 背景 2026 年 2 月 1 日,软件开发者 Dmitry Brant 在其博客上分享了一次软件考古学探险经历:帮助一家会计事务所从使用了 40 年的遗留软件系统中迁移数据。这个过程中,他成功破解了一个古老的硬件复制保护加密狗(Dongle),使得这套基于 RPG 语言的会计软件得以在没有原始硬件的情况下运行。 ## 2. 核心发现 ### A. 遗留系统现状 这家会计事务所在 2026 年仍在使用 Windows 98 计算机运行 DOS 控制台程序。该软件使用 IBM RPG(Report Program Generator)语言编写,这是一种比 COBOL 还要古老的编程语言,最初用于 IBM 中型计算机(System/3、System/32、AS/400 等)。 ### B. 复制保护机制 软件运行依赖一个连接到计算机并行端口的硬件加密狗。加密狗由 Software Security Inc 公司生产,该公司位于美国康涅狄格州斯坦福德市,曾在 1990 年代初期的 SIGGRAPH 会议上展示过其产品,并持有相关软件保护专利。 # 二、技术分析 ## 1. 系统组成 ### A. 软件组件 - RPG II 编译器(RPGC.EXE):由 Software West Inc 公司开发 - 源代码编辑器(SEU.EXE):Source Entry Utility - 会计软件源代码:使用 RPG 语言编写的多个模块 - DOS 批处理文件:用于编排各模块的菜单系统 ### B. 硬件组件 - 并行端口加密狗:标签显示 RUNTIME 字样 - Windows 98 计算机:运行 DOS 控制台环境 ## 2. 保护机制工作原理 ```mermaid graph TD subgraph 程序启动流程 A[启动 RPG 程序] --> B[调用保护例程] B --> C[检测并行端口地址] C --> D[读取 BIOS 数据区] D --> E[向数据寄存器写入值] E --> F[读取状态寄存器响应] F --> G{累积响应值} G --> H[返回 BX 寄存器值] end subgraph 验证流程 H --> I{BX == 0x7606?} I -->|是| J[程序正常运行] I -->|否| K[显示错误退出] end ```  ### A. 保护例程特征 通过反汇编分析,保护例程具有以下特征: 1. **独立代码段**:保护代码位于单独的内存段(0x0800),仅 0x90 字节 2. **远调用返回**:使用 RETF 指令返回,表明是通过远调用(far CALL)调用 3. **并行端口通信**:使用 IN 和 OUT 指令与并行端口通信 4. **固定返回值**:BH 寄存器硬编码为 0x76,仅 BL 值由加密狗响应决定 ### B. 关键发现 保护例程没有任何输入参数,不从堆栈弹出数据,也不依赖传入的寄存器值。这意味着无论与加密狗进行多么复杂的通信,最终结果始终是一个常量值。 # 三、破解过程 ## 1. 分析工具 使用 Reko 反编译器对 16 位实模式可执行文件进行反汇编。Reko 能够理解这种古老的可执行格式,并尝试将汇编代码反编译为可读的 C 代码。 ## 2. 破解步骤 ```mermaid sequenceDiagram participant D as 反汇编器 participant A as 分析人员 participant P as 补丁程序 participant T as 测试环境 D->>A: 提取保护例程代码 A->>A: 分析 IN/OUT 指令 A->>A: 确定 BH = 0x76(固定值) A->>P: 初始补丁 BX = 0x1234 P->>T: 测试运行 T->>A: 立即失败(无延迟) A->>A: 确认补丁位置正确 A->>P: 暴力破解 BL(0-255) P->>T: 自动化测试 T->>A: BL = 0x06 成功 A->>P: 最终补丁 BX = 0x7606 ```  ### A. 初始尝试 首先用任意值(0x1234)替换保护例程的前四个字节: ``` BB 34 12 MOV BX, 1234h CB RETF ``` 程序仍然失败,但立即退出而非等待数秒,证明补丁位置正确。 ### B. 缩小范围 通过代码分析确定 BH 必须为 0x76,将搜索空间从 65536 种可能缩小到 256 种。 ### C. 暴力破解 编写脚本在 DosBox 中自动测试 0-255 的所有 BL 值,很快发现正确值为 6。 ### D. 最终补丁 ``` BB 06 76 MOV BX, 7606h CB RETF ``` 仅需修改 4 个字节即可完全绕过硬件保护。 # 四、技术意义 ## 1. 保护机制评估 ### A. 设计缺陷 - 返回值完全固定,不依赖任何动态输入 - 搜索空间极小(仅 256 种可能) - 所有可执行文件使用相同的保护代码 ### B. 历史背景 这种简单的保护机制在 1980-1990 年代较为常见。当时的软件厂商主要依赖硬件成本和物理分发限制来防止盗版,而非复杂的加密算法。 ## 2. 软件考古价值 ### A. 保存意义 - RPG II 编译器现已可在无原始硬件的情况下运行 - 为计算历史研究提供了可用的工具链 - Software West Inc 的 RPG II 编译器在互联网上几乎找不到其他副本 ### B. 技术传承 这个案例展示了: - 早期 PC 软件保护技术的演变 - IBM 大型机编程文化向个人电脑的迁移 - DOS 时代的软件分发和授权模式 # 五、经验总结 ## 1. 逆向工程方法论 ### A. 信息收集 - 观察程序行为(延迟、错误消息) - 搜索磁盘镜像中的线索文件 - 识别硬件标签上的公司信息 ### B. 静态分析 - 使用适当的反汇编工具(如 Reko) - 定位关键代码段(IN/OUT 指令) - 理解程序控制流 ### C. 动态验证 - 在模拟环境中测试补丁 - 使用自动化脚本进行暴力破解 - 验证补丁对所有相关程序的有效性 ## 2. 关键发现 编译器本身包含保护代码,并在编译时将相同的保护逻辑注入生成的可执行文件。因此,补丁后的编译器会生成同样已绕过保护的程序,大大简化了整个软件包的处理工作。 *** ## 参考资料 1. [Defeating a 40-year-old copy protection dongle](https://dmitrybrant.com/2026/02/01/defeating-a-40-year-old-copy-protection-dongle) 最后修改:2026 年 02 月 03 日 © 允许规范转载 赞 如果觉得我的文章对你有用,请随意赞赏