山寨里的技术 – 小议“扒”
– 再回首:三十多年过去,弹指一挥间
不知何时,山寨这个名词火了起来,并形成一种山寨文化,流行起来了。
这里的山寨当然是指对知名或权威事物的仿冒,多有贬义,主要是对于产品的仿冒,常见但不只限于电子产品,并发展到所有3C产品领域。但随着仿冒水平的提高,产品质量也得到改善,使得山寨产品隐隐带有“物美价廉”的内涵。
生产山寨产品,也是需要有技术支持的,主要就是山寨原始设计 – 这个设计被一个单字动词描述的活灵活现:扒。
我近日开始回炉古典吉他,回想起四十年前按五线谱“扒”出来指法,其实这个“扒”就是其中的技术成分。我还偷懒,经常是等别人扒出指法来,我再从别人那里二次“扒”,一点技术含量都没有。后来有高手可以根据听到的曲子“扒”出谱子来,这就更是高手了,或者叫高技术,特别是有多乐器合成的曲子,那对我简直是不敢想象的。
但再怎么高手,这也不是原创。原创的才是最有价值的,才是推动人类文明进步的基本动力。就像我现在弹吉他还是磕磕绊绊的,听听正宗的古典吉他,陈志的高徒王雅梦小姐表演的《爱的罗曼史变奏》,我连再弹吉他的心情都没有了 – 我当年也是跟着陈志的吉他谱学的呀,这人和人的差距咋就那么大呢啊?
山寨产品有简单的,有复杂的。如果仿制的原产品没有做必要的技术保护,仿制是很容易的。下面我就聊一下我在八、九十年代经历的“扒”的相关技术经历。那时还没有山寨这个说法,华强北也只是卖东西的,“扒”是“高技术”,官称“逆向工程” – 当然,真正合法的逆向工程需要符合“净室原则”,而我这里说的“扒”则完全是以100%复制为目的的。
这里说的板,就是指PCB,印刷电路板。但在圈里都直接称为“板儿”,英文也就是 board 或 PCB(Printed Circuit Board)。那时的 PCB 的集成度还不高,双面板还有,常见的往往是四层、六层以下的,当然八层十层的也有。上面的器件也往往都是容易买到的,就算大陆买不到也可以去香港买。
题外话:当时有巴统禁运,一些高标的东西限制大陆进口。记得我做声音分析需要 AD 采样,人的听觉频率上限大约是 20 KHz,所以采样芯片需要 40 KHz (采样定理:两倍的目标信号频率)。可是巴统禁运,12 位的采样芯片允许进口的最高速就是 Analog Device 公司的 AD574,采样上限是 35 KHz,我只能多买几个,从中挑选 margin 较高的,可以接近 40 KHz。
当时扒的板往往不是最终产品,只是板级替代,比如程控交换机的用户板、PC 上的图像多媒体板、工控系统上的x线控板,当然也有汉卡、病毒卡等。对这样的板卡,不用考虑系统,直接把硬件“复制”就可以了。
这个硬件复制过程主要就是把 PCB 的接线逻辑图给“反”出来,然后就可以生产了。这个“反”图是个“技术活”,就是把所有线路板上的节点连接情况都要明确,建立起来一个大表格,以确保各点的连接逻辑正确。
有同事为此做了一个发明,据说还申请了专利(我没有验证):一个金属刷子,插在万用表的一端;另一端就用万用表的普通探针。选万用表的测联通档,把探针放在一点,然后用金属刷子一刷,碰到连接时万用表就会发出声音,这样大大地提高了效率(相比于用万用表自带的两个探针测试,每次只能测两点之间的连接,而不是一点到一面的测试)。
这种方法随着 PCB 的层数增加其难度变得越来越大,到了八层十层以上就很难分析出内部的连接情况了。有时只靠无损检测无法确定连接关系,还需要磨板。
测出了连接表,就可以照猫画虎地复制出 PCB 了。
板上往往还有 ROM 一类的存储,复制一下也就可以了,不是什么难点。但后来出了 PAL/GAL 等可编程逻辑阵列芯片。这东西就像一个多进多出的逻辑系统,必须要测出内部的逻辑关系真值表,然后根据这个真值表来复制出逻辑芯片。
最难的是芯片复制。有些复杂的 PAL 无法完全靠逻辑分析出来内部的 fuse 情况,就需要有损的照相来观看。这可不是普通的照相机可以完成的,是需要直径超过一米的巨大放大效果的镜头。把 PAL 磨开,然后照相。当时好像国内只有上海可以做。现在 PAL/GAL 都不见了,被 CPLD 等新型逻辑器件取代了。
声明一下,这些本人都没有做过,只是在一旁耳濡目染。不过下面有关扒软件的勾当我可是没少做。
那时很多软件为了防止盗版,都有各种防盗技术,比如登陆密码等。但在没有网络支持的时代,一个密码可以到处用。特别是可以在硬盘上安装软件后,靠登陆密码防止盗版也就是防君子不防小人了。
这时,就出现了密钥,俗称“加密狗”,或简称为狗。加密狗有两种形式,软磁盘密钥(软狗)和并口密钥(硬狗,后来有 USB 接口的了,叫 software dongle)。被保护的软件要想正常运行,作为密钥的软盘或并口插件必须存在才可以。
这是一个魔道争霸的过程。开始,软件只是在一开始启动时有一次检验狗是否存在。这时,就可以用跟踪软件找到机器码这个位置,直接跳过去就可以了。还记得 x86 代码 0xEB 条件转跳改成 0xE9,就是长跳,就可以“解密”了。
后来软件开发人员在某些关键部位也增加了检查狗的调用,代码跟踪就比较复杂了,因为一步一步地跟着机器码走太费时间。不过,也不是不可能。这种解密难度与软件价值往往是不成比例的,估计这与软件加密开发人员对解密方法的理解有关,也与软件的性能考虑有关,毕竟经常访问狗会降低运行效率,特别是软狗。另外,在软件中经常访问狗也会增加软件开发的维护难度。
那时我对软件版权的意识不强,甚至觉得这就是弱肉强食,你有本事你就加密,他有本事他就解密。对相关的法律意识很淡漠,也无人管。我的一个朋友就是我们那里的知识产权办公室主任,一个在他的办工桌上插两面小红旗的装X犯:一面是五星红旗,一面是镰刀斧头,交叉着插在桌面的笔架上。他们是几个局联合办公的,就他一个光杆司令,既没有权也没有人。在那里哪儿有什么版权的概念?也就是组织配合一下抓那些卖盗版光盘的。
那时在工作之余,我就喜欢研究 DOS (Diskette Operating System)系统,那是 PC 机上的基本操作系统,什么软件都需要在其上运行的。别人玩游戏,我只是看热闹,然后去改游戏,比如可以通过驻留的程序控制键盘 (interrupt 9/16),降低游戏的运行速度、增加人的响应时间同时减少机器的响应时间,增加 life 等,减少游戏的难度。只是这样改动之后,游戏本身也就不吸引人了。其实我对游戏的热情在读研究生时就花光了 – 那时玩的是 PC 上的《警察抓小偷》,和苹果II上的《十项全能》和《巷战》。
比如那时时髦的挖金子(digger)游戏,我可以控制计算机运行的快慢,从而让人有更多的响应时间。那个游戏的设计没有根据绝对时间做控制,只有相对时间控制,也就是依赖计算机的执行速度。在 286 出来以后,那个游戏就快得失控了,需要我的“加持”。
只有一次是有意义的,就是古典推箱子,日本人开发的,日语是Sokoban (倉庫番),150级,必须一级一级地升,不能跳过,每十级奖励一个美女图片,是一个动脑筋的智力游戏 – 这是那时我唯一喜欢玩的游戏。我们那里有一个高手,进步最快,打到一百来级的时候发现有一级设计错误无法通过,结果我的招数就可以用上了,跳过这级。
当年技术熟练时我可以根据 x86 的机器码大概看出执行流程,也可以用 debug 工具直接编程机器码并执行程序。这种能力到了三十几岁就不行了,当然也与事多心不静有关。大厂们要求员工 996 到 35 岁退休也是有原因的。我还不到 35 岁时,就发现脑力和体力的下降:复杂的逻辑分析能力和记忆力不如从前了;打篮球时以前觉得可够到的球这时够不到了,如果强行伸展,就会被拉伤。
当然,加密解密也是我的一大乐趣。慢慢地有了点小名气,经常会有外人来找我帮忙,当然也不是白帮的。
曾经做过一个价值数十万元(或上百万?)的 EDA 集成电路设计软件的硬狗解密(记得当时好像是 0.6 微米的工艺技术已经是天花板了,现在已经是 2~3 纳米了,大约 16 个摩尔周期之前!),花了一两个小时就完成了。那个机构要求原硬狗不能离开实验室,所以我的工作只能在他们的实验室进行。解密也只是为了方便:那个软件每次需要输出电路图时都要连上狗,而他们只有一只狗,几十个人用起来很不方便。给我的要求是把硬狗解密,但要给软件另外加密,以免流出。于是我在硬狗解密后给他们做了几个软狗,再把软件用软狗加密。其实就是他们实验室想省钱,只买了一个软件 license,但想要多人一起使用。这个软件是老外的,比较君子,只设了一个检查点,本来也就是防君子的。
那个实验室的头做事很地道,在解密过程中一直陪着我,或者说监视着我干活儿,避免软件被偷偷拷贝。等我解密成功后,他并不要那个解密软件,只是要求我在再次加密后把解密的软件删除,确保不会有解密的软件流出。
这次解密是我自认为最漂亮的一次:解了密,又再加了密,时间也短,还很实用,价值也高。特别是一屋子顶级研究机构的陌生计算机专业人员看着,我就像有金手指一样,给他们松绑。那种内心骄傲的感觉相当的爽 – 我毕竟不是计算机科班出身的,相当于民科一族,学校里计算机专业课一门也没有学过,连计算机语言学的都是 Fortran,纯数学编程语言。
还做过一个价值几万元的酒店门禁系统解密,零零散散持续了数周时间。这个加密既不是软狗也不是硬狗,而是一个时间狗。产品卖给酒店后,软件公司提供一个密码,可以用一个月,到期再续。悲催的是酒店把软件款付给了来安装软件的人员,而那个人卷款走人了,他说因为是软件开发公司欠他的工资。但软件开发公司不认,要求酒店再付款才可以给继续开通。酒店就不干了,不想付双份的费用,可这时这套门禁系统已经上线了,不能停,这也是软件公司敢于和酒店叫板的原因。我就在这时被酒店找来帮忙,倒是也没有费多大劲,就解了那个时间狗。
不料,过了几天,酒店又来找,说是在另一个应用点上还有一个时间狗。无奈,我再去给解开。可是几天后,又出现新的时间狗。这个时间狗设计很有意思,狗叫的时候并不是马上停止服务,而是不断预警:三天后就会停止服务。这是软件公司向酒店催收应付款的一个好方法,而我也必须在限定的时间内解决问题。就这样,来来回回好像有四五次,酒店就不再找我了,估计是都解干净了。因为软件安装在专用系统的硬盘上,我每次解密都要到酒店去,来来回回耗费了我不少时间,没完没了的,得不偿失。
这次解密也是我感觉最闹心的一次。中国人做的加密就是考虑得很严密。
我也碰到过解不开的加密技术。记得那是一款硬狗,而那只狗里不仅有防盗逻辑,还有软件需要的数据。从狗中读出来数据每次不一样,按时间随机的,用于填补应用软件里的需要的数据。这招比较高,我没有耐心去把狗里的数据都分析出来。其实,这时也就是成本问题,硬解这样的加密狗相当于用 brutal force 来解 RSA 算法,意义不大了。但我仔细考虑一下,发现这种加密的成本比较高,因为软件要把部分数据放到狗里边,这样开发的连带关系是比较麻烦的。
那时做解密也是有点手痒痒,看到加密的软件就有去解密的冲动,就像玩智力游戏一样,去理解加密人员的思路,反过来考虑该如何加密更安全。
经过大量的解密实践,我最后发现了一个通用解密方法,我管这种方法叫【内存锁定】。那时的 PC 都是 DOS 系统,实模式的,只有 640K 的内存,是一个flat memory,没有页面控制。我的【内存锁定】法是先将一个小的驻留程序(我起名叫 weasel)放到内存高端处,然后运行待解密软件(带狗的)。等软件运行通过了狗验证之后,也就是拔出狗后软件也是可以正常运行时,就激活我事先埋伏的小驻留程序,把整个内存给存到磁盘上,也就是 take a snapshot,然后按照 EXEC 的文件格式重新给这个 snapshot 加一个 EXEC 文件头,就可以把 CS/DS/ES 段址在运行时复位了。
用这种方法,根本不用跟踪软件,整个过程可以自动处理。而且,我没有发现市场上有人使用这样的技术。这简直就是一款通用的解密软件。
一次在一个软件展销会上,一个加密软件商不信我可以解开他的软件,我现场试验,在几分钟内就把用他的加密软件加密的 PC-tools 给解开了,唯一不同的是软件在磁盘中的大小变大了,从100 多 KB 变成 600 多 KB。但我后来又改进了,在文件上增加了一个自解压头,一般可以把这类程序文件压缩到约1/10 之内(因为多数内存都是空白的),像这种情况,也就是 60 多 KB。
也是那次展览会上,碰到一个同学。我们俩互相看着眼熟,都知道一定是同学,但都不记得是哪里的同学。于是,我说,咱俩谁都别问,就坐在这儿互相相面,谁能先叫出对方的名字,对方就负责午饭请客了。我中学换了好几个,这时已经高中毕业十多年了,真有点难。到了饭时,我俩大眼瞪小眼,还是认不出来,就是越看越觉得熟。最后我说算了,我自曝一下几个中学吧,看看交集。结果发现是上大学前高二时最后一年的同学,而且是前后桌的,他极为“愤慨”地说,我记不住你也就算了,可我是你的班长,怎么你也记不住?
嘿嘿,我的记忆力都放到有趣的技术上了。比如那时闲着没事儿,给计算机的硬盘加密,改了关键目录 FAT 表的链接,每次需要访问那个目录时都要用 debug 现改那个 FAT 表,一个 32 位的地址。不然只能看到自卷的目录,也就是这个目录的子目录就是本目录,无限循环,DIR 列目录就会刷屏。这种目录多了、时间长了就很难记住,那可真是闲的。
玩到这个时候,我也开始慢慢对解密的兴趣索然了。而且,后来 Windows 在市场上也开始起步了,在保护模式下我的许多招式也都不灵了,有没有硬件 ICE 支持,跟踪软件很累。特别是还需要养家糊口,得开始挣钱了,干事儿也不能全凭兴趣,于是就不太玩解密了。
只有做了解密,才知道如何加密更安全。
在总结了各种解密经验后,我自己做的加密系统有几个关键,是在其他加密软件中没有发现的。
其一是反跟踪。用过 debug 的开发人员都知道,stepping (也叫 single step,既单步中断,PC上是用 interrupt 3,代码 0xCC,来修改下一条指令来实现的)是跟踪软件最笨,但也是最难防的招数。用远端设置断点(break point)虽然快,但无法真正跟踪到执行逻辑,只能做大致的流程筛选。
为了反跟踪,我利用了 x86 的指令 pipeline cache 技术。这个 cache 不是后来 CPU 的 L1/L2 instruction/data 大 cache,而是 CPU 在 load 指令后进行解码的 pipleline cache。其特点是,如果用 stepping 跟踪,这些 pipeline 的每条指令都会被 invalidate,就是无效后重新 load,这样的执行路径与会与没有 stepping 跟踪的路径不同。用这种方法就会彻底把跟踪人的思路搞乱,不知道程序是如何执行的,一会儿就会跟到了死胡同。其实,就连我自己知道原理,跟踪起来也是很无力,因为这相当于步步陷阱,一不小心就误入歧途了。
其二是反驻留。防止高端内存的 interrupt 20/21/25/26 等 DOS 调用,避免系统被控制。这个是防止有像我上面提到的【内存锁定】之类的招数,虽然我没有见过别人有。
其三是控时。检查 interrupt 8 计数在我的程序执行之间的变化,以确定是否被跟踪。interrupt 8 是一个时钟中断,每秒会被激活 18.2 次。这个和近年国内高速上测超速是同一个道理:在两个检查点之间,如果用时太短了,那就一定是超速了。我这里的用法是反向的,就是如果执行我的代码超过了两个 ticks,说明有人在跟踪,就跳到无效路径上去误导解密者。
另外,系统软件开发人员都知道,goto 语句是最不好的,破坏了软件的层级结构。但是,goto 语句对防解密是最好的,可以把跟踪者的思路搞乱。
在解密中我就发现,反跟踪最有效的办法不是发现被跟踪后就宕机,而是进行误导,让解密者无法判断是否是在正路上,直到太晚了以后,也无法知道是在哪里迷路的。
在制造软狗时,用超大扇区(8 KB)格式化软盘(3.5” 和 5.25” 的软盘都一样)的第 4 道(track),这时可以在这个道的首尾相连缝隙处产生一个四个字节的随机数。我把这四个字节的随机数读出来,经变换后写到磁盘的引导扇区的引导记录后面的空白处。我的解码程序就去读软盘的第 4 道的随机数和写到引导扇区里变换后的结果,用来判断是不是合法的磁盘。这种方法很可靠,也很安全,软狗很难复制,因为那个四字节数是随机生成的,而且不可控制。
我后来自己做的小产品都用了这种加密来保护,防止拷贝。这种软狗的成本几乎是零,软件可以就装在那软盘里面,也很方便,还稳定可靠。
遗憾的是,那个 pipeline cache 的技术在 586 (奔腾)出现后不灵了。估计是 586 的体系结构在指令内存空间加上了只读限制,使得我在运行过程中修改指令的方法失效了,害得我只能在我的加密软件中取消了这种反跟踪。当时已经没有多大兴趣搞加密解密了,所以也就没有兴趣具体去研究关于 586 的解决方案。特别是软件都开始向 Windows 转移,就更没有 incentive 去做了。x86 的体系结构很复杂,比我后来涉及到的 RISC 芯片如 MIPS/ARM/PPC 等复杂多了。不过,估计花些时间也许是可以改进的。
经过一番折腾,这时我已经意识到不按规矩出牌的软件技术后患无穷了。比如那时有本时髦的技术资料,《DOS未公开的秘密》,里面记录了不少各种后门的应用。但是这些未公开的东西就是潜在的麻烦,将来可能会改变。Lessons learned。
吹个小牛:那时把 DOS 玩透了,看计算机就像进到自己家一样,看程序运行就会想到其底层的执行方式。一次,一位硬件哥们儿的 PCB 设计硬盘被病毒给黑了,大半年的工作没有软盘备份,而项目不允许拖延。他的头求我帮助恢复数据,我开始也心里没数,谁知道病毒干了什么坏事,也许把他的数据都给抹除了呢?但他运气不错,我在那硬盘的 FAT 备份分区表里找到了几个孤链,可以手动恢复,其中有一个链居然就是他的最新 PCB 数据文件,而且数据居然完整,把他们高兴坏了,他们的军工项目不至于拖期了,当晚就请我大搓一顿,除了白酒,还有那个头刚刚从美国带回来的袋装葡萄酒,一袋好像有七八斤,喝得我酩酊大醉。
也是在那个晚上,我第一次可以和别人在酒后胡咧咧,说起了我那悲催的童年(见《童年的记忆》)。
盗版一般只是在通用计算机上才可以。在专用的工业计算机上,复杂的软件往往无法直接盗用其机器码的程序的,除非是你可以100%复制了整个硬件软件系统,但这时你又无法升级、无法维护,连 bug 都被拷贝过来了。
这里说个笑话:当年菊花起步的时候盗版思科,就是把 bug 也一起盗走了,成为罪证。
真扒软件是一个逆向工程,虽然不是“净室技术”下的合法逆向工程,但也是一个不小的工程。
有些工具可以使用,记得当年有一个叫 SoftICE 的东西,可以把机器码反成 C 语言。当然,反出来的 C 代码是很难读的,和机器码也差不多,但逻辑基本正确,可以在此基础上打磨加工,形成真正的源代码。
其实,这个工作和 RSA 求逆算法差不多,只是算法复杂度的非对称性没有那么高,结果的要求也不是必须 100% 的一致。
系统软件的正向开发大体是这样的:
1)有经验的 architect 可以按软件逻辑分组,把一个大项目切割成几个小项目。其实,现实中因为公司政治的存在,这种切分往往体现的是公司的结构,结果软件的结构会跟着公司的结构走,而不是按着合理的设计走。所以往往如果公司的结构不合理,或和应用逻辑不匹配,结果就是出产的软件结构不合理,最后甚至成为垃圾。
2)每个子项目再细化,分到人头上。各子项目都要有至少一个大腕来进行总控把关。各种关键的应用逻辑都在这里体现。设计文档就是要在这一步生成,最后汇总到总体文档中。这里也是软件的核心价值所在,要“扒”出来的也是这里的应用逻辑。近十几年时髦 lean production,讲究 agile 软件开发,我一直对之嗤之以鼻,因为我总会想到当年的“抓革命,促生产”时搞出来的“边设计、边施工”的土八路招数。我的组里从来不搞 agile,公司要求也不干。我现在好像可以把 agile 和左左们联系起来。
3)按开发总管 VP 的要求安排,开发出来的各子项目按时开始集成,启动集成测试。
4)进入到 release 的 schedule,开始系统测试。当bug少到一定程度后,就可以release了。release后的软件就进入维护期了,branch 出来,另行维护。
软件逆向工程也是差不多就是把这个软件划分给“扒”出来。
1)先把机器码反成高级语言,比如 C 语言。这就是一堆杂乱无章的符号,所有的 label 标签都不过是字母数字。
2)根据团队组织结构,把这些垃圾般的代码划分到各个开发人员处。这些人读代码并理解其目的,按每个子函数 function 的意义和目的,为其命名。我有一个老友,多年的系统建构师,他有一句名言,我深以为是:software development is all about naming – 软件开发的核心就是命名。
3)对于不理解的 function,交由大家讨论,互相切磋。实在解决不了,留待以后,当了解的多了就可能有解了。这里有一句围棋格言:棋盘很大,不好走的地方先放一放,后面就会有变化的。
4)当绝大多数的 function 都有了合适的名字的时候,就可以开始系统集成了。编译出来的系统进行调试,验证,修改,回到了正向开发的 release 步骤中。
这时,软件也就真的“扒”完了。这些“扒”的开发人员也就学习到了软件的设计原理,为什么这样做,等等。这之后,也可以逆向地完成设计文档了。“扒”到了这一步,也是“扒”界的天花板了。但和玩真的还是不一样,是没有原发性、开创性的,只是高级拷贝。
鉴于众所周知的 sensitivity,我就不举例说明了。但真正合法的逆向工程是另一种形式的,称为净室设计技术:开发人员需要分成两组,A 组负责研究目标仿制系统,根据其运行方式写出设计规范,他们只能看其硬件系统运行状况;B 组人员不许接触目标仿制系统,只能根据 A 组人员撰写的设计文档,去实现设计 – 这个实现过程 A 组人员不允许参加。嗯,这种技术还有个名字,叫【中国墙】(Chinese wall technique),不是互联网的长城哈,虽然其名字也是来源于长城的,但早在三十年代就在华尔街的金融系统上使用了,用以分割券商和投行之间的信息,后来计算机系统开发逆向工程也借用了这个定义。
最著名的软件开发净室设计技术成果就是现在几乎所有基于 PC 结构的计算机都在使用的 Phoenix BIOS (Basic Input and Output System,PC 机上的必备底层启动软件,前面提到的多个 interrupt,除了DOS 的软中断 20/21/25/26 外,大多数都是由这个 BIOS 提供的处理功能),是 Phoenix 根据逆向研究 IBM 的PC BIOS,通过净室技术开发实现的。那时 IBM 开放了其 PC 结构,但总是打官司说别人侵权了他们的软件,主要就是那个 BIOS,于是 Phoenix BIOS 被大多数 PC 兼容机厂商选用,现在 IBM 的 BIOS 已经很罕见了,而 Phoenix 的 BIOS 到处都是。另外,IBM 采用了微软的 DOS,称为 MS-DOS,作为其 PC 的操作系统,又犯了一个大错,造就了另一个比自己还壮大的黑巨人。
记得上大学时流行励志讲座。当年好像是听李燕杰还是曲啸讲的,IBM 的 CEO 是多么牛逼,手指刚刚夹起一只古巴雪茄来,旁边马上会凑过来好几个打火机献媚。其实,那时的 IBM 已经犯下了这两个错误,后来导致这个蓝色巨人早早地就把自己独创的 PC 业务卖给了联想,彻底剥离出来了。当然,IBM 的 CEO 也没有那么大的范儿,只是我们那时还没有接触西方世界,被李燕杰们忽悠得一愣一愣的。当然,也许他们就是真的这样认为的也说不定。关于有关的笑话,可以看阎润涛在文学城上发表的《曲啸在美国遭遇滑铁卢纪实》 – 阎润涛已经在三年前故于新冠病毒,他的故事很精彩。
回过头来总结一下。从技术角度看,“扒”板就是累傻小子(或傻妞)的体力活儿;盗版解密就是抖小机灵的小偷勾当;加密防盗就是小区保安的辛苦活儿,不过信息技术复制几乎没有成本,所以这是一个机器人保安的活儿;逆向工程是江洋大盗的活儿,不仅有法律风险,还有经济风险和技术风险,但也很接近于真正的产品开发了。
我对盗版的认识也是逐步建立起来的。从开始的不在乎、无感,甚至某种程度的认同,到后来远离盗版,是一个缓慢的过程。
记得当初有一位“扒”防病毒卡的哥们儿有一句“名言”:“打击假冒伪劣”,其实假冒没有什么危害,伪劣才是真正侵害消费者的。所以他理直气壮地卖他的廉价盗版防病毒卡,说中国的国情就是这样,正版的卖高价,有钱人买,有服务;盗版的卖低价,穷人买。这样可以保证人人平等。这好像是印度仿药的理论基础。我怀疑如微软那些大公司很少在中国打知识产权官司可能也有这一层的考虑。
我当时也稀里糊涂地基本赞同他的观点。
当年还有一个说法,就是在国内的盗版软件成为了一种市场营销技巧。比如 MS-DOS,有哪一位花过钱买版权?但这是一个消费习惯的培养,接着 MS-Windows/Office 也是差不多,但到了一定程度,真正官方使用人员必须用正版的了,不然会有不可预知的麻烦,包括法律上的麻烦和技术上的麻烦。而没有盗版铺垫的软件则缺少大众支持,当该花钱选购软件产品时人们也会首先考虑自己熟知的软件,而不会选择那些生疏的软件。记得以前看过一种说法,就是用户的操作习惯和对软件的交互界面的熟悉程度是该软件的市场资源,是很有价值的东西。
这个观点在某种程度上有一定道理。西方国家也是对在高校里使用的各种软件用低价或免费的方式推广,除了支持教育以外,也有培养未来潜在客户的意图。那些高校毕业生到了工作市场中就会把他们的习惯和喜好也带入工作场景,成为那些有铺垫软件的支持者、爱好者,最后成为采购者。
但无节制的盗版对知识产权的危害其实是相当大的。最直接的危害就是让原创者缺少了开发产品的动力,特别是对中小软件企业。
比如,现在国内游戏公司有一个共识,那就是绝对不能做面向国内的单机游戏产品。因为无论你这款游戏口碑有多好,最后一定都会扑街在盗版上。在没有网络进行中央版权控制的情况下,硬件还好说点,盗版可以追踪;软件盗版的追踪成本奇高,惩罚手段寥寥,最后开发公司/人员只能选择放弃。
更有甚者,打民族牌。就在六年前,一款国产的单机游戏《ICEY》上架没有几天就被解密,并被发到网上(现在有了网络,盗版发行比正版要高效得多),最终迫于舆论压力,解密公司(对,不是个人行为)在网络上下架了盗版,并发表了一篇道歉信:“对不起,我们不该解破国产游戏” – 言外之意,解破外国的就可以了。
是的,国内各大游戏论坛一个约定俗成的规则就是,国产游戏不能破解,国外随便破解。这叫做“支持国货”。
对知识产权的保护,必须是国家法律的强行贯彻。靠道德约束和技术控制只能是治标不治本。我自觉道德修炼得不错了,但不仅以前有过这种盗版或协助盗版的行为,而且之后也不是那么干净。人是不可靠的,哪里也没有圣人。
我虽然近三十年没有进行过加密解密的相关活动,但最接近的一次是十年前,差一点就重操旧业了。那是在我开发系统时看到了一个合作商把他们的软件进行了 cipher 处理,就是把源代码的所有有意义的名字都替换成一些无意义的标识,并删去格式控制字符,混成一团,鼻子连眼睛的。这种软件可以正常编译使用,但无法读代码去理解其设计原理。
我心想我们合作干事儿,你们还这样保护,就产生了 decipher 的冲动。这段被 cipher 的代码是关于一个有限自动机上的一个带通滤波器,是这个公司的 bread and butter,但也碰巧是我研究生学习时的专业内容,属于信号处理范畴。这样也让我有点好奇去看看这个滤波器是怎么设计的,到底有什么值得保护的高招儿。
其实,这就是我在“软件逆向工程”里介绍的第(1)步完成后的状态,而我很想做第(2)步,虽然没有什么经济动机,可我还是技痒难耐,或者说是“恶习难改”啊。
这个 decipher 的工作其实要比我以前做的逆向工程容易多了,因为除了是我熟悉的应用领域,这段代码还有一组 API,就是没有 cipher 的外连函数调用。从这里出发,我很快就可以一层一层地挖了下去。但真正下手试一下,发现很快就没有了兴趣 – 这段代码量很大,全部 decipher 要花不少时间。特别是以前那种热情没有了,年纪大了?版权意识强了?incentive 不足?反正没有了动力,随后就把这个事儿抛在脑后了。
我终于没有再次犯戒,谢天谢地,洗洗睡吧。希望耶稣和佛祖都原谅我。最后,再憋出两句歪诗以抒发曾经的荒唐带来的窃悦,以及远离了荒唐后的一身轻松吧:
加锁解密爽,高山流水长;
逆向误工程,正道是沧桑。
说起来还要感谢盗版,我们这一代无不是从盗版碟开始窥探和了解外面的世界的。
把一篇专业性很强的文章写得丝丝入扣,外行也读得下去,还让人哑然失笑,点赞。