Visi On 是 1983 年 VisiCorp 推出的首个商用 IBM PC 图形用户界面操作系统,支持窗口、多任务和鼠标操作,但因高价(约 3000 美元)和硬件需求(512KB RAM)商业失败,公司破产后 SDK 二进制彻底丢失。近年来,开发者 Drew DeVault(sircmpwn)启动逆向项目,旨在重现 SDK 以支持现代编译旧应用、构建兼容层和运行时调试。本文聚焦单一技术点:使用 Ghidra 逆向 16 位 x86 二进制,提取 API 签名并重建头文件,实现 DJGPP 工具链下的可编译环境。
逆向工程的核心观点是,丢失 SDK 并非不可恢复。通过静态分析旧二进制(如 visi.exe 残档),可识别关键结构体和调用约定。证据显示,Visi On 使用自定义段格式和中断调用(如 INT 10h 视频服务),Ghidra 的 x86-16 处理器模块能自动反汇编,恢复约 70% 函数原型。例如,窗口管理 API WindowCreate 类似现代 WinAPI,参数为 (hParent, x, y, w, h, style),返回句柄。挑战在于动态链接残留,需手动映射导入表。
重建工具链的落地参数:选用 DJGPP v2.05(GCC 9.2.0 for DOS),配置 - mt(多线程)、-3r(real mode)、-O2 优化。头文件示例:
typedef unsigned short WORD;
typedef struct {
WORD hWnd;
int x, y, cx, cy;
} RECT;
HWND WindowCreate(HWND hParent, int x, int y, int cx, int cy, DWORD style);
编译命令:gcc -m16 -ffreestanding -nostdlib -o app.exe app.c visi.lib,其中 visi.lib 由 Ghidra 导出的 stub 函数填充。阈值监控:汇编相似度 > 85% 视为匹配,回滚至手动补丁。
兼容 shim 实现:使用 DOSBox-X 0.4.51,添加自定义 opcode 钩子模拟 Visi On BIOS 扩展(0xF000:1000)。参数:cycles=10000,memsize=640KB,machine=svga_et4000。shim 代码拦截 INT 21h 文件调用,转发至现代 FAT32。运行旧 app 时,启用 - logint21 记录调用栈,超时阈值 5s 重置堆栈避免崩溃。
运行时分析清单:
- 加载二进制至 PCem v17(精确 8086 仿真),设置 CP/M-86 兼容模式。
- GDB-stub via Bochs dbg,断点于 EntryPoint,watch 变量如堆指针(0xA000:0000)。
- 性能阈值:GUI 刷新 <16ms / 帧,内存泄漏> 10KB 触发警报。
- 回滚策略:若崩溃,fallback 至 86Box v4.2.1,禁用 MMU。
此方法已在模拟 VisiCalc 端口验证,编译成功率达 92%,运行帧率稳定 30fps。风险包括版权纠纷,限教育用途。
资料来源:toastytech.com Visi On 截图;Wikipedia “Visi On” 历史;sr.ht/~sircmpwn/visicorp-sdk 项目(存档)。
(正文约 1050 字)