反编译与计算机软件的知识产权保护
吴国平 北京市隆安律师事务所
本文与反编译的技术有关,但是并非技术帖,尽管如此,本文推荐的读者仍然包括软件项目经理以及软件企业的管理人员。全文5779字,阅读需要约10分钟。
对于律师或者软件公司的法务来讲,谈到软件的知识产权保护,一定会想到版权、专利和商业秘密保护;对于程序员来讲,谈到知识产权的保护,一定会联想到对源代码进行混淆、本地配置文件和基本数据库进行加密、网络传输数据加密、程序结构混排加密、硬件加密等方式。从实用性来讲,某种程度上,上述技术保护方式相较法律保护有更高的实用性,但是随着软件代码的封装交付,软件产品的特殊性决定了计算机程序发行时必须向用户交付经过包装加密和混淆的目标码,尽管如果不借助特殊的反编译工具,人们是无法直接进行阅读获取其内容的。但是尽管针对不同语言以及相应保密方式的不同,反编译后语言的识别率仍然存在种种问题,就如程序员所比拟的,编译的过程就像把生米做成熟饭,而反编译的就是把熟饭变成生米,其中的难度极为形象。但是毫无疑问的是,通过对他人软件的反编译,可以推导出他人的软件产品所使用的架构、原理、算法、处理过程、运行方法等要素,某些特定情况下可能推导出部分源代码(不同的产品代价不同)。
GNU C编译器自诞生至今已经三十余年,每个程序员都非常熟悉,目前已经由最初的只能处理C语言扩展可处理C++、Fortran、Pascal、Objective-C,但是针对C语言的特殊性,针对C语言产品的反汇编一直没有进展,尽管也出现过Dcc、Boomerang、C-Decomplier等专门工具,但是都存在无法识别复杂数据结构、子程序参数和变量名等种种问题,并且会存在大量的数据丢失,可读性很差,如下图示例:
从成本角度分析,如果以抄袭为目的的反编译所花的时间高于自己独立创作的时间,那么律师就没有必要再考虑这种情形下的法律保护问题了,因为再傻的程序员也不会选择这种方式抄袭别人的劳动成果。
律师处理案件中对反编译的认识局限于软件作品的抄袭方式以及如何通过反编译的方法向法官证明两个软件作品存在抄袭,实际上,反编译工具最初的开发目的并非基于单纯的商业目的,或者更进一步,并非出于抄袭的目的。最初的反编译工具的开发目的是为军方和涉密的*机关审查第三方提供的软件是否存在恶意代码或者未经授权的数据入口。所以最早反编译工具的开发总是和美国海军电子实验室、洛克希德导弹与空间实验室等相关,涉及潜艇射击控制软件系统、战斗机实时训练装置系统等。国内的解放军信息大学也曾经有类似的项目,相信也是出于类似的目的。
反编译技术开发的另外一个应用领域就是兼容性的需求。笔者曾处理一起关于数据兼容性的纠纷,客户通过努力争取到一个*机构的项目,但是该项目的开发过程中需要对接另外一个*平台的数据,该平台的技术维护方属于客户的竞争者,因此平台方拒不向客户提供接口文件并设置了种种障碍,因为利益关系复杂,客户的发包方协调数次未果,最终导致客户项目面临延期甚至开发失败的风险。对于客户来讲,项目的完成需要与平台信息的交换或者是对接,在此过程中就需要对于平台软件譬如数据库字段的一些定义进行探究,反编译方法恰好可以完成这一目的,这也是对软件进行反编译以获得兼容性的一个重要的现实需求。因为平台运营方的极力阻挠,反编译方法的合法性一度成为双方争议的焦点。
上述需求实际上跟另外一个计算机行业的数据获取相关的,那就是通常某些用户使用某一个特定的软件,使用过程中存储了事实上是由用户产生或者积累的一些数据,那么当这该用户在使用其它程序进行工作或者需要这种积累的数据迁移到另外一个软件作品之中的时候,就面临着一个数据如何进行获取对接的事情。的确,很多软件,特别是社交类软件的公司对于用户数据的所有权问题有着不同的认识,尽管数据是由用户操作并积累产生,但是所有的软件服务还有服务器等硬件都是企业提供的,因为现实中如果用户想要在不同的软件作品间进行数据迁移,就涉及数据所有权归属的问题。如果市场上已有某软件作品,开发者试图去开发一款新的软件作品,同时试图使用到用户原来积累的数据的时候,就必然存在这样的现实需求。
这与上述平台方阻挠获取数据或许极为类似,但是该种情况下,如果新开发者依然使用反编译的方式获取原有软件平台的数据,就脱离了因兼容性获取数据的边界,将面临更多的法律风险。
尽管有大量的开发工作,但是反编译工具的整体开发进度仍然是十分缓慢的,一方面可能是军方掌握的反编译工具处于完全保密状态的原因,另外一方面出于纯商业目的的反编译工具开发应用场景较少,限制了商业开发的投入。尽管一些公司可能会负责后期维护第三方公司的软件项目,但是又无法取得该项目的源代码(原因比较复杂),为了维护工作的顺利开展,反编译工具就有了商业使用的需求,因为维护工作的相对收入较少,一般也很难支持长期稳定的反编译投入。
这种情况一直持续到Sun公司推出JDK1.0后发生了变化,因为java包的实质内容是java源代码编译后的.class文件,由于java的面向对象特性和java的反射技术,可以很容易的通过对.class文件进行反射来得到java的源代码,也就是完成了反编译的整个过程!现在市场上java反编译工具有: Jadclipse、jad、JD-GUI、jdec、uuDeJava、Minjava等。从事软件知识产权保护的律师都应该感谢这家公司,正是因为该项产品的推出,使得不法之徒通过反编译获取他人的劳动成果变得相对容易,客观上也为律师介入该类案件提供了商业机会。
当然,上述说法并不意味着对他人软件作品进行反编译一定意味着违法行为,尽管几乎所有的软件在发行时附带的使用协议均标注禁止反编译,但是至少在商业秘密保护的领域,反编译是正当合法的。根据法释[2007]2号司法解释,通过对从公开渠道取得的产品进行拆卸、测绘、分析等而获得该产品的有关技术信息等反向工程等方式获得的商业秘密,不认定为反不正当竞争法第十条第(一)、(二)项规定的侵犯商业秘密行为。上述司法解释中“反向工程”在软件领域几乎等同于“反编译”,但是具体到软件行业,对程序员来讲“反向工程”的文字表述是如此的陌生,所以本文全部采用反编译的说法。
对于文字作品在内的多种作品形式,读者可以通过阅读它的内容了解该文字包含的思想,技术,方法或者信息,相比较而言,具体表现的计算机代码中的不受版权保护的因素却只能以反编译的方式予以获取,假如禁止反编译工具的使用,软件程序员就能够借助版权法对计算机程序中没有达到专利保护标准的功能性程序和架构取得事实上的垄断,因此这是为什么允许对计算机代码进行反编译的一个原理。
允许反编译的结论是有严格界定条件的,也不应被误解为反编译的技术使得软件商业秘密的保护落空。笔者曾承办软件商业秘密的刑事案件和民事案件,并且案例中还曾涉及军方武器控制系统的案件,深知在软件知识产权保护的可选项中,商业秘密选项是举证最难的一条途径。在某些条件下,软件的商业秘密保护基于版权保护和专利保护所无法比拟的优点而成为兜底的保护模式。但是,因为反编译技术的存在,使得软件商业秘密的保护存在挑战,也正是这个原因,使得对反编译技术的研判成为商业秘密案件中的重要因素,客观上也对承办律师的技术背景提出了更高的要求。当然,法官对软件行业的了解程度也可能成为案件成败的关键,在笔者承办的一起案例中,侵权人仅仅通过两个月就完成了权利人三年多数十次升级更新才完成的软件项目,单就这一点基本就完全可以判定侵权的事实,但是对于法官来讲,因为行业背景不同,很难理解软件开发完成与软件稳定运行的差异,客观上也造成了权利人维权的难度。
2020年1月16日中美第一阶段经贸协议中对商业秘密的保护做出了新的安排,包括举证责任倒置、紧急情况的行为保全、刑事案件中取消将实际损失作为刑事案件的启动条件,上述安排切实解决了实践中权利人商业秘密保护的困境,期待上述安排尽快与中国法律法规进行衔接,对于软件的商业秘密保护无疑是重大利好。
在软件商业秘密案件中,与反编译相关的一点就是雇佣离职员工的问题,司法实践中,一旦确定了被告雇佣原告方离职程序员的事实,反编译便不再成为法官考虑的重点。不容忽视的是,法官也认同商业秘密可以存在于已经公开的特征或者构建的组合之中,只要这种组合可以为权利人提供竞争上的优势,笔者承办的案例中,有鉴定机构出具报告认为包括算法在内的诸多因素都属于公知领域,有的算法甚至可以追溯到30年前,委托人认为案件注定失败甚至开始考虑撤诉,我在庭审中要求司法鉴定人对该种公知因素的组合是否公知并要求其提供证据,最终鉴定人不得不承认没有对基于众多公知因素的组合是否公知进行检索和判断。
在上述商业秘密案件中,容易被人忽略是程序员个人的经验因素。关于软件系统架构问题,因为涉及到程序员的工作经验。必须承认的是,程序员的工作经验是其多年努力而获取的谋生手段或者其个人的竞争优势,从公平角度来看,雇主对于程序员在离职后对于该架构的实施是否有超出雇主合法经营利益所必需的范围,从而确定保密协议的约定是否合理甚至是否有效的问题,因为雇主对程序员系统架构等职业经验所做出的限制有可能损害程序员谋生的合法利益,因而有理由对这种限制是否合理提出质疑。由程序员的自身利益出发,对其以前工作过程之中获得的技能和知识技巧的保护,基本上等同于对程序员谋生能力的保护。商业秘密保护立法的初衷是为了打击违反诚信并以不正当方式获取他人秘密,保护程序员个人积累的经验与上述立法初衷并不矛盾。对于上述雇主利益与程序员利益边界的确定一直是争议不断的,如何在商业秘密案件中进行判断,特别是离职程序员与反编译两个因素并存的案件中,法官也需要更为充足的理由证明其判断是客观和合理的,而不能单纯因为存在雇佣离职程序员的因素而直接做出认定。
以著作权为基础对软件进行保护的方式中,著作权法规定未经著作权人或者与著作权有关的权利人许可,故意避开或者破坏权利人为其作品采取的保护著作权或者与著作权有关的权利的技术措施的,属于违法行为,反编译过程采用的技术手段尽管在商业秘密范畴是正当的,但是在著作权法范畴**著作权人的加密或者混淆方式,采用反编译属于违法行为,只是因为举证的问题鲜有单纯以反编译为理由进行著作权诉讼的案例。
尽管反编译工具有可能成为不法之徒抄袭的捷径,但是同时也为保护软件作品提供了强有力的工具,因为权利人在案件举证期间无法获取抄袭作品的源代码,除了少数以相同BUG为理由进行起诉的案件外,几乎都需要提交以反编译工具进行对比的证据(极少数以相同界面为由进行立案的不予评论)。在案件的审理过程中,如果被告方拒不提交源代码,则只能根据双方的执行文件进行反编译,并按照反编译后程序对比的结果对案件做出认定。
在上述过程中,如果双方的作品属于“照搬照抄”的情形,则不必深究反编译后的程序与源代码之间的差异。但是特殊情形下有必要对上述方法进行质疑,如果我们深究技术方案以及背后的逻辑关系,不难发现有很多律师可以在案件中进行抗辩的空间。
首先,单就反编译的工具来讲, 还原的程序可能会存在大量语句丢失的情况,例如用eclipse查看class文件发现有214行,但是反编译后得到的源码却只有38行,JADX进行反编译过程中有时候反编译的代码不完整,会看到inconsistent code 标志的错误。相反的情况也会发生,因为内存、系统或者加密的原因,可能会出现例如下述红色部分的乱码,导致编译代码的行数远远高于实际行数:
一般 Apk 在发布出去之前,都是通过混淆加密的方式防止被反编译,这基本上国内软件厂商通用的做法。因此,通过反编译查看文件结构时,源文件中的类因为混淆而只能看到如下图的文件标:
因为反编译工具选取的差异,反编译的结果可能会出现语法错误,有时甚至是明显的语法错误,这样的语句在eclipse里根本就不能编译通过,有的只是return null。同时用eclipse反编译插件进行debug时,在debug里显示的进度行数与实际的行数完全不一致。有程序员发现,在需用JAD进行反编译时,如果同一文件夹下的子文件夹里如果隐藏着类名相同的class文件,jd-gui只会反编译其中的一个,如果不逐个查看,根本无法发现这样的BUG。
当然,本文不是技术贴,针对反编译工具的缺陷仍然要与具体案件中的法律判断结合到一起。无论是法官还是律师,处理一个软件著作权案件过程中,对于专业技术问题的判断,仍然大部分依赖于鉴定机构的意见,当鉴定机构的鉴定报告送达各方当事人时,尽管鉴定机构会将工作的方法例如选用的反编译工具(包括版本、编译环境)做简单的描述,甚至会将反编译过程中的部分截图编入鉴定报告,但是按照笔者查阅了经办案件的数十个鉴定报告,没有任何一个报告对上述反编译过程中可能出现的问题进行表述,当然也没有对为何选用某个反编译工具作出说明。
为了说明不同反编译工具之间的差异,笔者选用了某上线APP产品的部分文件,分别使用JADX、Jad、jd-gui三种不同的反编译工具对上述选取的文件进行反编译,期间使用的是同一部电脑,操作系统及硬件配置未有变化。笔者选取了部分反编译后的结果如下示例:
示例1、反编译工具JADX(version 1.1.0)
示例2、反编译工具jad(version 1.5.8)
示例3、 反编译工具 jd-gui(version 1.6.6)
通过上述示例的对比我们不难发现,同一个文件通过不同的反编译工具,在部分语句上得出的结果存在较大差异,如果以程序行数为单位进行对照,差异的比例约为30%。如果按照CRC方法对照三个反编译的文件,结论肯定是不相同。
当然,以上的结论仅仅是我们选取的一个很小的文件,样本数明显不足,如果需要对这个APP的文件包进行反编译,其结论可能给会略有差异。如果结合案件审理中鉴定机构的工作方法,可以初步认定反编译工具的选取可能会影响最终的认定结论,这种影响在被告自主开发但是存在部份抄袭的案件中会显得尤为重要。
软件知识产权案件,涉及的技术问题较多,在计算机科学与法学交叉的领域,有诸多被人误解的问题,例如仍有律师将软件的全部源代码作为商业秘密向法院提起诉讼。涉及反编译的案件对律师的要求也就更高,笔者曾经承办一个案件,因为对方当事人的律师对软件技术甚至软件行业缺乏基础的认识,导致案件处理过程处处被动,最终在本有机会取胜的情况下主动撤诉。
本文中讨论的反编译技术在软件商业秘密以及软件版权案件中的适用问题,供各位软件程序员、律师、软件企业法务参考,如有错误疏漏,还请指正,作者邮箱:[email protected]。