VMProtect除了代码虚拟化和变形处理,还带有一套序列号授权机制。项目接入以后,程序可以判断序列号是否有效,也能读取到期时间、硬件绑定、可用版本日期等信息。授权这一块比较容易遇到一种情况,序列号已经生成,看起来也没有输错,程序却始终判断为无效。问题可能出在产品参数、序列号限制条件,也可能是程序没有正确调用授权接口。配置时把“生成什么授权”和“程序怎么验证授权”分开检查,排错会清楚不少。
一、VMProtect怎么配置授权系统
VMProtect的授权体系围绕Licenses、序列号参数和SDK接口展开。工程里先建立对应产品的授权配置,再生成测试序列号,程序端负责接收并判断序列号状态。
1、在保护工程中建立授权配置
先把授权参数和当前产品工程对应起来,后面生成的序列号才能被这个产品识别。
①、打开【VMProtect】并载入当前【保护工程】。
②、进入【Project Options】中的授权相关设置。
③、检查【Licensing parameters】。
④、确认【File Name】指向当前使用的授权工程文件。
⑤、项目使用在线激活时填写对应的【Activation Server】。
⑥、保存当前【VMProtect Project】。
2、生成用于测试的序列号
①、进入【Licenses】页面。
②、点击【Add license】。
③、填写授权记录需要使用的名称等信息。
④、需要限时使用时启用【Expiration date】。
⑤、限制适用程序版本时设置【Max build date】。
⑥、需要绑定当前电脑时填写【Hardware ID】。
⑦、确认参数后生成【Serial Number】。
序列号能够同时携带多种限制信息,如果只是做初次接入测试,可以先减少限制条件。确认基础验证已经跑通以后,再逐项增加到期日期、硬件绑定等配置。
3、在程序中接入序列号验证
①、把对应平台的【VMProtect SDK】加入开发工程。
②、程序取得序列号后调用【VMProtectSetSerialNumber】。
③、保存该函数返回的授权状态。
④、需要再次读取状态时调用【VMProtectGetSerialNumberState】。
⑤、需要获取名称、到期日期等内容时调用【VMProtectGetSerialNumberData】。
⑥、重新编译原始程序。
⑦、使用【VMProtect】重新生成保护文件。
VMProtect把返回值为0视为当前序列号通过验证。如果返回了状态位,程序就要按照对应状态判断授权失败的原因。
4、给授权增加硬件绑定
①、在受保护程序中调用【VMProtectGetCurrentHWID】。
②、取得当前电脑对应的【Hardware ID】。
③、返回【Licenses】并新建授权记录。
④、启用硬件绑定相关设置。
⑤、把取得的【Hardware ID】填写到授权参数中。
⑥、重新生成【Serial Number】。
⑦、把新序列号交给程序重新验证。
二、VMProtect授权验证失败如何处理
授权验证失败时,不建议直接重新生成很多序列号。VMProtect会返回不同的序列号状态标志,把返回状态打印出来,再顺着状态去找配置,会省掉不少试错。
1、序列号直接显示无效
①、记录【VMProtectSetSerialNumber】的返回值。
②、调用【VMProtectGetSerialNumberState】再次读取状态。
③、检查是否出现【SERIAL_STATE_FLAG_INVALID】。
④、确认输入内容没有遗漏字符或多余换行。
⑤、返回【Licenses】重新复制完整【Serial Number】。
⑥、再次执行授权验证。
如果状态一直指向无效,还要确认序列号是不是由当前产品对应的授权参数生成。不同产品工程生成的序列号不能随意混用。
2、换电脑以后授权不能使用
①、读取当前电脑的【VMProtectGetCurrentHWID】结果。
②、查看授权状态是否包含【SERIAL_STATE_FLAG_BAD_HWID】。
③、返回原来的【License】记录检查硬件绑定信息。
④、核对序列号中的【Hardware ID】。
⑤、按当前授权规则生成新的【Serial Number】。
⑥、重新调用【VMProtectSetSerialNumber】。
硬件绑定序列号只能按照其中记录的硬件信息进行验证,直接把另一台电脑的授权复制过来,通常会得到硬件标识不一致的状态。
3、序列号以前能用,现在提示过期
①、读取【VMProtectGetSerialNumberState】。
②、检查【SERIAL_STATE_FLAG_DATE_EXPIRED】状态。
③、调用【VMProtectGetSerialNumberData】读取授权日期信息。
④、返回【Licenses】查看原授权的【Expiration date】。
⑤、需要继续使用时按新的授权期限生成序列号。
⑥、重新载入新【Serial Number】。
4、新版本程序突然不接受原授权
①、查看状态是否包含【SERIAL_STATE_FLAG_MAX_BUILD_EXPIRED】。
②、读取【VMProtectGetSerialNumberData】中的版本日期信息。
③、打开原来的【License】配置。
④、检查【Max build date】。
⑤、根据当前授权策略调整允许的版本日期。
⑥、生成新的【Serial Number】并重新测试。
5、序列号正确但受保护功能仍不能执行
①、确认程序已经调用【VMProtectSetSerialNumber】。
②、检查该函数是否在受保护功能执行前完成。
③、返回【Functions for Protection】。
④、找到启用了【Lock to Serial Number】的函数。
⑤、确认当前授权状态返回值为0。
⑥、重新生成【Protected File】并测试功能。
三、VMProtect授权系统配置后怎么检查
基础验证跑通以后,可以再把几种限制条件分别测试一遍。这样后面正式发放授权时,遇到问题更容易判断是序列号条件触发了,还是程序端验证逻辑发生了变化。
1、分别测试几种授权状态
①、生成一份正常的【Serial Number】并确认程序能够通过验证。
②、生成带【Expiration date】的测试授权。
③、生成绑定【Hardware ID】的测试授权。
④、分别运行程序并记录【Serial Number State】。
⑤、检查程序对各种状态的处理是否符合当前设计。
⑥、测试完成后恢复正式使用的授权配置。
2、保存已经验证过的授权工程
①、保存当前【VMProtect Project】。
②、保留产品对应的【Licensing parameters】。
③、记录程序当前使用的【VMProtect SDK】版本。
④、保存测试过的授权状态和程序版本。
⑤、后续修改授权逻辑前另存新的【工程文件】。
授权系统后面一旦加入更多限制,排错难度也会跟着增加。把基础版本留着,再逐项增加硬件绑定、有效期或版本限制,哪一项带来变化会更容易看出来。
总结
VMProtect授权配置里比较容易混淆的,是把“序列号生成成功”和“程序验证通过”当成同一件事。序列号本身还会受到硬件标识、有效期和版本日期等条件影响,只要其中一项不符合,程序就会得到对应的失败状态。碰到授权不认时,先把状态值读出来,再去查相应参数,比重新生成一堆序列号更省事。平时也可以留一套限制较少、已经测试通过的授权配置,后面增加新的授权规则时有个清楚的参照。
