要用到文件流与加密流的技术,脱壳的部分代码如下: public static Assembly
asmload(string asmName) { Assembly asmsvr = null;
FileStream fsr = null; byte[] byVec=new byte[16], byKey=new byte[32]; //asmName待加载的程序集名,由参数带入 string
toLoad=AppDomain.CurrentDomain.BaseDirectory+asmName +"e.dll"; if ( ! File.Exists( toLoad ) ) return null; fsr = new FileStream( toLoad, FileMode.Open, FileAccess.Read ); byte[] rawAssembly = new byte[ fsr.Length ]; //提取机器指纹并生成DES加密密钥与初向量 createDesKeyVec( ref byVec,ref byKey );
SymmetricAlgorithm des=SymmetricAlgorithm.Create(); CryptoStream encStream=new CryptoStream(fsr, des.Create Decryptor ( byKey, byVec), CryptoStream Mode.Read ); //读取并解密到到缓冲区 encStream.Read( rawAssembly, 0, (int)fsr.Length ); encStream.Close(); fsr.Close(); asmsvr = AppDomain.CurrentDomain.Load(rawAssembly ); } 6.2 DLL调用请求的捕获
根据需要来脱壳也就是当程序集被调用时,临时脱壳并加载,程序集一旦加载,以后需要调用其中的功能时就可以直接从内存中运行,这就既避免了内存的浪费又不会影响程序运行速度。关键是程序集的调用不一定从壳中调用,可以从任何一个已经运行的程序集中调用,怎么才能截获程序集的调用请求呢?
首先要了解应用程序域,它由AppDomain对象来表示,为执行托管代码提供隔离、卸载和安全边界。多个应用程序域可以在一个进程中运行;但是,在应用程序域和线程之间没有一对一的关联。多个线程可以属于一个应用程序域,尽管给定的线程并不局限于一个应用程序域,但在任何给定时间,线程都在一个应用程序域中执行。每当程序运行时,便会自动创建应用程序域。AppDomain实例用于加载和执行程序集(Assembly),
AppDomain 类实现一组事件,这些事件使应用程序可以在加载程序集、卸载应用程序域或引发未处理的异常时进行响应。本方案中就是通过事件AssemblyResolve来捕获程序集调用请求的。
实现方法是:首先,在壳的main()函数中注册事件AssemblyResolve的响应代码,形如:
AppDomain.CurrentDomain.AssemblyResolve += new
ResolveEventHandler( CurrentDomain_AssemblyResolve );
然后,再编写一段事件响应代码,来实现程序集脱壳与加载。这样,在调用任何程序集时,就可以直接调用了,因为程序集的脱壳会自动进行。下面是事件响应的部分代码: ///
返回找到的或临时加载的程序集 private static Assembly CurrentDomain_AssemblyResolve (object sender, ResolveEventArgs args) {
Assembly ret = null;
try{
AppDomain dm=(AppDomain)sender;
string dllName= args.Name.Split(#39;,#39;)[0];
//用xx开头的文件表示加密过和DLL,区别于其它的DLL
if (dllName.StartsWith("xx")&;&;!dllName.EndsWith ("resources") )
ret = asmload( dllName );
}
catch (Exception ae )
{ MessageBox.Show("加载数据集" + args.Name + "时出错" ); }
return ret; } 7 总结
以上软件保护
方案的安全性能由DES算法(若采用)和机器指纹的安全性决定。DES算法的安全主要决定于对密钥保护。另外,由于密钥来自于机器指纹,而指纹数据来自于机器硬件信息,虽然,取指纹的算法要随软件外壳程序一起发布,但从指纹到密钥要经过自己设计的保密算法来转换,且保密算法不公开,所以算法本身是安全的。因此,密钥的安全还取决于指纹提取算法的安全性和指纹转密钥的算法安全性,而它们的安全性又取决于第三方加密或混淆的强度了,这是本方案所无法控制的,这也许就是此方案安全性最薄弱的环节。
对于用商业加壳软件的攻击较多,所以一旦商业加壳技术被破解,用它加密过的软件便没有安全了。但对于自编的加壳技术,加密技术可以自行设计(保密),并且可以随时调整,而且,用户数不多,因此,攻击者比较少,用这种技术加密的软件安全性也就相对更好。使用本文中的加壳技术,可以更有效地抵抗拷贝、反编译、分发序列号、注册机各种
常用的软件破解方法。然而,这种自编加壳技术虽然安全,但软件分发起来却十分复杂,这也是此方案的美中不足之处。