注册码异常分析
异常软件注册码的原理:
获取电脑的MAC地址,然后以MAC地址和使用期限(10年期)按一定规则进行合并,然后一起生成一个hash值注册码;
验证的时候主是通过获取本机的MAC并与10年的日期一一合并生成一个hash,然后与原始注册码进行匹配,只要有一个匹配成功,则表明还在有效期内。
问题现象
电脑桌面的软件注册码在有效期内失效了,导致软件不能使用。
并且后续发现,只要在有网的状态下,就能正常登陆并使用软件,也就是说软件的MAC地址在有网络的情况下才能正常获取到;且在只要联网后,后续即使联网也能正常。
之后又发现,一些电脑偶尔正常,偶尔不正常。
排查过程
看了下获取网卡的源码,如下所示。即获取物理网卡中的第1张网卡,然后再获取MAC。
// 优先选择物理网卡(排除虚拟、环回等) var physicalNic = allNetInterfaces .FirstOrDefault(nic => nic.NetworkInterfaceType != NetworkInterfaceType.Loopback && nic.OperationalStatus == OperationalStatus.Up && nic.GetIPProperties().GatewayAddresses.Count > 0 && !nic.Description.Contains("Virtual") && !nic.Description.Contains("Pseudo") && nic.GetPhysicalAddress()?.ToString().Length == 12); // MAC 通常为 12 字符
为什么要联网才能获取MAC?
从源码中可以明显看出,代码为了保证能获取到使用的MAC,让
NetworkInterface.OperationalStatus==OperationalStatus.Up
OperationalStatus 枚举如下:
| 名称 | 值 | 说明 |
|---|---|---|
| Dormant | 5 |
网络接口不处于传输数据包的状态;它正等待外部事件。 |
| Down | 2 |
网络接口无法传输数据包。 |
| LowerLayerDown | 7 |
网络接口无法传输数据包,因为它运行在一个或多个其他接口之上,而这些“低层”接口中至少有一个已关闭。 |
| NotPresent | 6 |
由于缺少组件(通常为硬件组件),网络接口无法传输数据包。 |
| Testing | 3 |
网络接口正在运行测试。 |
| Unknown | 4 |
网络接口的状态未知。 |
| Up | 1 |
网络接口已运行,可以传输数据包。 |
将上述代码注释后,又发现,若关机前将网络禁用,再次开机又会发现不能正常获取到MAC,导致软件不能正常使用。这时需要联网一次后,后续再断网也没有问题了。
于是回头再次看了下代码,发现代码中还验证了一下GatewayAddresses,这也就导致了若开机时没网,肯定就没有IP地址,这时肯定也就没有相应的GatewayAddresses了;
因此将GatewayAddresses也注释,再交付测试在一些电脑上是完全没有问题的。
但在另外MS的平板电脑上出现了比较诡异的事情,它时好时坏。验证了一下,surface电脑上,每次获取到第1张物理网卡竟然是不一样的。于是就不能正常使用了。
原因分析
原始设计是以联网来获取第1张网卡的MAC,但当前却需要在无网的状态下也要能正常使用,于是导致在无网状态下就不能使用了,也就是说这属于需求变更或需求没有理清导致的。
后续在修改的一过程中发现,获取默认的第1张网卡,在某些品牌的电脑上运行时,返回的结果却是不一样的,这就导致了在这些品牌电脑上出现注册码时好时坏的情况。
解决方案
1. MAC的校验,可以将所有MAC都获取到,然后生成注册码与和原始注册码进行比对,只要有一个校验通过,就认为通过。
2. 还是获取所有的MAC,将所有的MAC进行相应的运算,生成一个C-MAC,然后使用这个C-MAC与时间来生成一个注册码,与原始注册码(当然也是获取所有MAC生成的)进行比对。
以上都是以MAC为基础的情况下来生成注册码的解决方案。当然肯定还可以不以MAC来生成注册码,可以主板ID或CPU ID或硬盘码等等。
建议
软件层面的注册码:以主板ID或CPU的ID进行注册码,不失为更好的办法;主板和CPU于当前使用的电脑而言,一台电脑都仅有一块主板和CPU。
硬件层面来说,当然加密狗,其实是更好办法,在加密狗内使用指定的硬件进行加密,同时在软件上再次进行加密与校验,当前来说应该是一种最好的方式;如此可以大大增加破解的难度,以达到保护版权的目的。

浙公网安备 33010602011771号