指纹的提取有两种方法:其一,通过软件的试用版。试用版中设计申请注册的模块,用户通过此模块提取本机的指纹数据。软件的试用版文件的制作不是针对目标机器的指纹制作的,可以在任何机器上运行。为了防止Cracker找到DLL的解密密钥后,将试用版破解。通常可以对试用版软件设置功能限制(如:去掉部分关键代码),这样即使试用版被破解,也无法投入正式的应用。
方法二:使用专用于注册申请的程序。对于网络版的应用服务程序,如果没有用户界面,或无须试用的用户,只能使用由开发商提供的专用注册程序来提取机器指纹。
5.2计算注册码
这种加壳技术本来可以省去输入注册码手工注册这个过程,因为每一个发布的版本只能在指定的机器上运行,但为了定制用户单位信息以及对用户数进行限制,还是要有注册过程的。注册码是由用户单位、机器指纹及用户数限制等信息经过加密处理后得到的,处理可以用自制的注册码计算工具来实现。
5.3加密DLL文件
本加壳技术的核心之一是加密DLL文件,加密过程可以用自制的加密工具完成。加密算法可以选择.NET框架中提供任何加密算法或者自行设计加密算法。算法可以不用公开的算法,因为加密解密都是在自己的程序中进行。因此,此
方案的安全性完全可以由开发商自己保证,而不依赖于第三方。
5.4制作安装盘
制作之前,只需用专为此用户加密的DLL文件及授权文件等替换安装工程中相应的文件,再生成安装盘。安装盘中可以单独存放一份加密DLL文件和授权文件,以备客户升级正式版时用户直接拷贝。
一般而言,安装文件中不能直接包含注册码或授权文件的,但在这种技术下,可以将授权文件打包到安装盘中,因为,即使安装文件被复制,也无法在非授权的机器上运行。
5.5正式版安装
对于没有安装过试用版的机器,可以直接使用安装盘安装正式版。对安装过试用版的机器,可以用安装盘中的正式版文件替换相应文件即可变成正式版。
5.6用户注册
调用正式版中“帮助”à“关于”à“注册”功能,输入注册码或选择授权文件进行注册。由于安装文件中包含授权文件,也可以在正式版首次运行时,通过授权文件自动注册,免去了手工注册的过程。
6程序运行时脱壳的实现
脱壳实际上是将加密的程序代码解密并加载到内存程序区,脱壳需要特定的解密密钥或特定的解密算法。对于较简单的程序,如果只有一两个DLL,可以由壳程序进行一次性脱壳,全部放在内存中,这没有什么技术上的难度,只是内存消耗较多。对于有多个DLL的程序,DLL不一定都要使用,有时可能只用其中部分,所以没有必要一次脱壳,全部占据在内存中,可以根据需要来脱壳。脱壳涉及到DLL解密、DLL调用请求的捕获等技术。
6.1DLL的解密
一般的加壳技术使用与用户无关的密钥,密钥是固定中壳代码中的,所以脱壳可以在任何一台机器上实现,无法实现软件防拷贝。而在本方案中,DLL加密密钥与用户计算机硬件指纹相关,当然解密密钥也不是壳代码中固定的,而需要临时从目标计算机上提取指纹生成密钥,才能解密,所以脱壳只能在授权的计算机上进行,从而可以很好地防止软件的非法拷贝。
解密密钥的是由硬件指纹生成的,指纹的提取与申请注册时提取指纹的算法相同,并且,指纹通过相同的保密算法转换后生成加密解密密钥。因此,指纹的提取算法存在于壳和专用的注册申请程序以软件的试用版中,为了防止这些算法的破解,需要使用第三方工具(如:XenoCode,MaxtoCode)对这些程序的MSIL代码进行混淆或加密。对于网络版软件,解密密钥最好是由壳临时从应用程序服务器获取;但为了简单起见,也可以将解密密钥存入授权文件中,授权文件经加密后随客户端软件一起安装,脱壳时从授权文件中提取解密密钥。
DLL的解密只能在内存中进行,不能生成临时文件,避免Cracker截获解密后的DLL。这就要用到文件流与加密流的技术,脱壳的部分代码如下:
publicstaticAssemblyasml
oad(stringasmName)
{Assemblyasmsvr=null;
FileStreamfsr=null;
byte[]byVec=newbyte[16],byKey=newbyte[32];
//asmName待加载的程序集名,由参数带入
stringtoLoad=AppDomain.CurrentDomain.BaseDirectory+asmName+"e.dll";
if(!File.Exists(toLoad))returnnull;
fsr=newFileStream(toLoad,FileMode.Open,FileAccess.Read);
byte[]rawAssembly=newbyte[fsr.Length];