该进销存软件,为10年前发布的,发布者给用户的license,里面的过期时间是2022年1月1日过期,登录进入系统之后,就会弹窗,提示即将过期(在2022年1月1日前,客户就反馈过来,存在即将过期的问题),点击确认或取消按钮,程序就会退出。
首先,安装该软件,该软件对应的有数据库文件,是MS SQL Server数据库 ,安装的版本是SQL Server 2000,还需要安装SP4的补丁程序(后面发现该补丁程序不安装,根本连不上,坑)
根据客户提供的数据库备份文件,恢复数据库,在数据库中可以看到,有保存license信息
深入分析该软件,发现该软件是PowerBuilder9编写的,安装目录中有几个dll文件,还有PowerBuilder的虚拟机dll文件——pbvm90.dll文件。
网上搜索PowerBuilder的pbd文件的反编译工具,其中 Shudepb PB反编译专家 收费,不付费长段的代码只能看到前面几行的。PB DeCompiler.exe也不行,同样的有限制。最终找到个比较好用的无限制的——PBKiller.exe。
PowerBuilder的pbd文件,是PowerBuilder特有格式的文件,所以必须用反编译pbd文件的专用软件才能打开,打开后发现里面也有一些是PowerBuilder的pascal语言的文本格式的代码。若在pbd文件中有license解析校验的,那么PBKiller.exe不能更改保存pbd文件,只能查看,可以用二进制编辑软件,打开,找到对应的字符文件的二进制存储位置,修改即可。
最终发现,修改pbd文件的方法行不通,至少主界面登录完成,提示过期的弹窗,不是在这些pbd文件中。使用olldbg打断点(ShowWindow上),发现是调用的htsoft模块,安装目录下就有htsoft.dll这个文件。
并且,从pbd文件中的代码中看到,通过修改系统时间,绕过过期时间的检查,不太可行。因为代码会校验单据流水号的生成的最新时间,若系统登录的时间,比流水号生成的时间早,则直接报异常退出。虽然也可以更改数据库的流水号生成时间,但是改了系统时间,会造成录入的单据时间都是错的,这样也让这个系统,业务侧没法使用。
我自己本地分析,是通过更改了系统时间,到2009年1月1日之前,暂时可实现程序登录后不退出。
通过比较长的时间,一个个查看了这些pbd文件,还好这些文件可以看到是跟进销存系统的前端模块,进行划分的。里面找到了用户自行在软件界面,输入license进行校验,并保存到数据库的代码。
最终分析,用户输入license注册,进行license校验时,调用的是htinit.dll这个文件。
把htinit.dll这个文件,拖进IDA,发现这个dll只有一个GetLicenseDate函数,从函数名称可以看出,这个是校验读取license中,还剩余多长时间过期的。
从用户机器上拿到的license,在我自己的机器上安装之后,数据库中由于已经保存了注册好的license信息,所以我本地不再需要操作注册。但是,本地的过期时间,提示是2009年1月1日过期,而不是2022年1月1日过期,所以猜测,该license中,应该还有机器名或者硬件码相关的信息,是针对特定机器的注册码,虽然用户名是ts.cxgxds,但是还需要绑定机器。
上图为软件的用户注册页面
上图为注册界面,点击时间之后,连接服务器操作的代码。
上图为注册时,调用htinit.dll的GetLicenseDate函数,获取剩余过期天数的代码。
上图可以看到,htinit.dll只有 GetLicenseDate这一个导出函数。
用于htinit.dll只有 GetLicenseDate这一个函数,并且传入的参数,反编译后能推测出来,所以我自己用VC6.0写了一个,替换,直接返回一个较大的剩余过期天数,并且还实现了将传入的参数,保存到文本文件。后发现传入的参数是用户ID和可能经过处理的license,因为都是整数,记录下来的传入参数是变的,并且看不出来什么有用信息。
上图:拦截htinit.dll的GetLicenseDate方法,保存其传入参数
分析了GetLicenseDate的代码,发现这里面就包含了license的解密的算法相关的代码,但是具体的算法本人水平有限,并不能分析出来,网上也没找到相关资源。大致推测是des加密解密算法,不是非对称加密。
所以这一条路暂且放下了,因为这里仅仅是注册时license的校验。要最终达到破解的效果,让软件可用,去除那个主界面的过期提示,才能根本。
通过比较长时间的olldbg调试分析,发现过期的弹窗的提示,其代码在htsoft.dll文件中,并且在htsoft.dll文件中,看到了与htinit.dll的GetLicenseDate方法中,非常相似的license解密代码。到这里,离破解完成就不远了。
上图:找到了,对于license的过期判断,是否进行弹窗的关键逻辑判断位置,这个位置关键且唯一,那么改了这个地方,就能实现不再弹窗过期提示,也就达到了破解的效果。至于该软件的其余操作位置,是否也还有执行license校验的,目前经过全面的代码分析,应该是没有了,那么先改了这个
上图:即把jnz short loc 10004286 改为jz hort loc 10004286
75是jnz指令的机器码,74是jn指令的机器码,用二进制编辑软件HexFrame把这里修改,另存未一份新的htsoft.dll替换原来的,进入系统。发现已没有过期的弹窗提示,进行一些模块的操作,也是正常的,将软件一直开着,也没出现过期的弹窗提示了。
软件:IDA、olldbg、pbkiller、HexFrame
遗憾:由于水平有限,对加解密算法的逆向没多少经验,并没有逆向出license的加密解密算法,得到license的生成算法。
教训:在自己的软件开发过程中,license的校验,不要弄唯一点,这样容易修改。