在写了IBM code page 852的可能起源之后,我想我应该重温一下捷克本土的替代解决方案,Kamenickýbrothers编码和他们的键盘驱动程序。它的存在有很好的文档记录,所谓的(有点命名错误)KEYBCS2编码甚至有自己的维基百科文章。编码本身存在于各种转换表中,将文本转换为Kamenický编码或从Kamenický编码转换文本的实用程序很容易找到。
但事实证明,找到真正的KEYBCS2实用程序非常困难。我在网上搜寻它。我找不到。完全我发现有相当多的文字在谈论它,但不是实际的用途。
在绝望中,我开始搜索我的NAS。我肯定在20世纪90年代初就有了这个实用程序,但在20世纪90年代中期我主要使用OS/2之后,DOS键盘驱动程序并没有那么有用,OS/2也有自己的功能良好的支持,使用CP852与内置的DOS支持兼容。
经过多次搜索,我找到了一个带有KEYBCS2的档案。90年7月27日在我的NAS上执行。可悲的是,我所有的尝试都以失败告终:
显然,我并没有试图调试程序,但我是被迫这么做的。
看看键盘。十六进制编辑器中的EXE没有显示明显的字符串;事实上,这一切看起来都很随机。但检查一个显示愚蠢错误消息的虚拟机的内存时,发现了一个看起来可疑的字符串:Program LOCK Version 1.10(C)1989 J.Belonoznik。好吧,一些愚蠢的反调试程序包装器,但为什么它认为我在调试它,而我没有?
在分析了“程序锁”之后,我发现它无意中阻止了“锁定”程序在任何一半的现代CPU上运行。它使用的上一代处理器是486,但在奔腾或更高版本上,它总是会失败,并显示“不允许调试”消息。
原因是(不出所料)调试器检测。锁代码检测对自身的修改,这可能会捕获任何INT3断点。通过使用自修改代码检测单步。它看起来大致(不完全)像这样:
异或ax,ax lea bx,模码mov字节ptr[bx],90h;NOP操作码jmp short$+2 mov字节ptr[bx],40h;INC AX opcodemod_代码:nop;修改指令cmp-ax,1;斧头是零还是一?
这段代码依赖于旧x86 CPU上是否存在软件可见的预取队列。在英特尔486之前(含),该代码将执行NOP指令。第二个MOV覆盖内存中的指令,但下一条指令已经在预取队列中,并将在刷新预取队列的跳转之后按原样执行。
在奔腾和更高版本的CPU上,处理器检测到当前在预取队列中的写入代码,刷新队列,并执行修改后的代码。经过努力,在奔腾(而非奔腾Pro)上检测可能会被愚弄,因为它使用的是线性地址,而不是物理地址,但它足够好,可以检测到这种自我修改代码的实例。
因此,“调试器检测”在奔腾和更高版本的处理器上肯定会失败。显然,该代码是1989年编写的,如果不是更早的话,其作者只是未能预测未来。
结果是,“反调试”代码充当了一个相当有效的定时炸弹,不能通过简单地将时钟向后拨来解决。
我考虑了制作受保护密钥BCS2的各种方法。EXE在CPU比486新的系统上运行。保护足够好,因此修补受保护的可执行文件非常困难。它会检查自身的完整性,并使用XOR链对可执行文件进行解密,这意味着需要在这里和那里修补一个字节。
我考虑编写某种TSR,通过截取打印错误消息的INT 21h调用,或者一个计时器挂钩,监视代码挂起的情况,从而围绕保护工作。这似乎不值得努力。
所以…我考虑了原始受保护程序是DOS的可能性。COM文件(相当高)。在这种情况下,可能在“程序锁”shell完成后,它会重建原始的。内存中的COM图像。所以我运行了KEYBCS2。EXE,保存内存内容,切掉似乎不属于的内容,并将剩下的内容重新保存为KEYBCS2。通用域名格式。成功了。
但首先我手动通过了调试器检查。讽刺的是,使用调试器。我所需要做的就是让程序执行一条JMP$指令来挂起自己,将其修补为JMP$+2(只需将第二个字节设置为零),然后继续。有两次这样的跳跃,每次都被击中几次;这就是为什么这条信息总共打印了五倍:
事实证明,KEYBCS2是一个相当花哨的键盘驱动程序,它占用了10KB的内存——这不是一个微不足道的数字。内存使用率相对较高的一个原因是,使用Ctrl+Shift+F1可以弹出一个漂亮的配置菜单:
KEYBCS2实用程序可以在几种可能的键盘布局之间动态切换。“标准”是未翻译的BIOS输入,“国家”是捷克或斯洛伐克键盘布局。但也有一个“组合”布局,实际上是两个布局同时按下Ctrl键切换到“其他”布局。甚至还有一个专门用于绘制“图形”的键盘布局:
我一直在想,有没有钥匙?我在KEYBDEF的在线帮助中找到了答案。EXE实用程序(与KEYBCS2.EXE位于同一档案中),允许用户为KEYBCS2驱动程序定义自己的键盘布局:
确实有一个KEYBCS1实用程序。它与KEYBCS2相同,但没有弹出的配置屏幕,因此可能更小。还有一个对应的KEYBSL1和KEYBSL2实用程序,默认情况下使用斯洛伐克键盘布局。
显然,将Kamenický编码称为“KEYBCS2”有点愚蠢,因为它同样是KEYBCS1、KEYBSL1和KEYBSL2编码。请注意,该实用程序实际上在其联机帮助中称自己为“KEYBxxy”。
还要注意的是,一些消息来源错误地宣称KEYBCS2是假定的KEYBCS实用程序的更新版本;事实并非如此,因为KEYBCS1和KEYBCS2是同一实用程序的不同变体。
Kamenický编码的设计方式远非随机。它最早是在1986年左右组装起来的,当时VGA还不存在,EGA是一种高端适配器。大多数电脑使用MGA、CGA或Hercules卡。
这些适配器的问题在于,除了Hercules Plus(仅于1986年发布)之外,它们在ROM中都有固定的字体。虽然用这些卡中的许多卡替换字符生成器EPROM通常是可能的,但它并不总是最终用户的选项,而且不是每个人都有所需的设备。
因此,选择了Kamenický编码,以便将国家字符放置在与标准IBM PC代码第437页中视觉相似的字形大致对应的位置。这有两个实际优势:第一,即使没有定制字体,捷克语或斯洛伐克语文本也清晰易读(尽管很难看)。其次,和CP852不同,Kamenický编码保留了所有CP437线描字符。
将这张曾经大受欢迎的诺顿指挥官的截图与Kamenický编码进行比较
使用PC Latin 2(CP852)编码的同一名诺顿指挥官的屏幕截图:
为了覆盖更多的语言,CP852牺牲了一些线描字符。虽然这是一个非常合理的折衷方案,但大多数用户只关心一种语言,而更喜欢不受干扰的线条图形。
编码设计也使排序和大小写更改变得更加困难,因为国家字符没有简单的算法排序。但这是一个在软件中可以解决的问题,而首先显示正确的字符不一定只是软件的问题。
同样的最小修改CP437的方法也是(独立地?)用于匈牙利CWI-1/CWI-2编码,在较小程度上用于波兰马佐维亚编码。
需要注意的一点是,KEYBCS2(实际上是整个KEYBxxy系列)没有试图对屏幕字体做任何事情;事实上,正如上面所解释的,它根本不一定需要全国性的屏幕字体。
同样,使用EGA或VGA硬件的用户显然希望使用正确的字体。由于KEYBCS2没有提供帮助,他们肯定使用了其他东西。
在一份旧文档中,我发现了一个EGASET实用程序,据报道它与KEYBCS2一起使用。我很快发现EGASET并不是一个非常独特的名字。然后我在一个最意想不到的地方,在一个名为CZHPFNT的档案中找到了正确的一个。拉链
CZHPFNT档案的起源是一个谜,但很清楚是在1989年4月。想象一下,当我发现一个名为KEYBCS3的实用程序时,我会有多么惊讶。COM包括:
这显然是我的KEYBCS2的旧版本(文件时间戳是1987年7月,程序本身表明是1987年5月)。我不知道为什么它被称为KEYBCS3,但它不仅仅是一个重命名的文件;该实用程序显然称自己为KEYBCS3。
我在任何地方都找不到提到KEYBCS3的地方。也不清楚“3”是什么意思;它可能意味着什么,但1990年更新的在线帮助只提到KEYBCS1和KEBYCS2,而KEYBCS3实用程序本身没有提供任何提示。
但这并不是CZHPFNT档案中唯一的惊喜。当我运行我一直在搜索的实际EGASET实用程序时,它显示了IBM Roece Inc.1986的版权,这与之前一篇帖子中提到的IBM Roece(欧洲中部和东部地区办事处)相同:
下面是一个菜单,EGASET实用程序会弹出,以响应Alt+右移键组合:
看来,EGASET真的是一个通用的EGA调整工具,它恰好允许加载字体。IBM ROECE最终使用它可能是因为这是他们发现的第一件事,而不是因为它是覆盖EGA字体的最明显的方法。
对于上面有IBM名称的东西,EGASET实用程序相当神秘。然而,如果它只是由IBM ROECE发布的话,它可能最终几乎完全落在铁幕后面,大约1991年以前的大部分计算历史几乎完全消失了。
提供的CSEGA14。FNT字体日期为1988年1月。CZHPFNT档案非常有力地表明,IBM ROECE确实为至少一些东欧国家提供了某种形式的国家语言支持,尽管这种支持到底是什么样子尚不清楚。除了参与EGASET实用程序之外,IBM ROECE是否与CZHPFNT归档文件有任何关系甚至尚不清楚。包含的字体仅包含原始字体数据和存档的自述文件。TXT也没有提供任何线索。
因为找到KEYBCS2实用程序非常困难,所以我和其他几个人一起在这里提供了它。原来的键盘BCS2不再工作。包括EXE和我的“解锁”键BCS2。通用域名格式。包括几个可选的键盘和/或显示驱动程序;那些捷克人。EXE是最新、最新奇的,它的传统内存占用最小,并且支持Kamenický、CP852、CP1250和ISO 8859-2编码的键盘/显示器。
尽管DOS 5.0及更高版本提供了功能完善的内置键盘和字体支持,但它仅限于CP852;第三方实用程序往往更强大、更灵活,同时需要更少的内存。