我正在尝试对程序集进行篡改,以便能够模拟不易被模仿的代码,such as SharePoint assemblies。
作为一个原型,我有一个解决方案,在这个解决方案中,测试代码通过使用ILRepack和Mono.Cecil的自定义构建操作进行篡改,因此实际代码不是最初编写的代码。
当包含测试代码的程序集没有签名时,一切正常工作。在对程序集进行签名时,我看到了预期中的错误:
所定位的程序集的清单定义与程序集引用不匹配。
由于程序集是被篡改的,很明显,密钥要么不相同(如果在篡改后签名),要么不存在。
我认为通过AppDomain.CurrentDomain.AssemblyResolve事件可以强制被篡改的程序集被接受,但事实并非如此。
如何让.NET框架在完全信任地运行的单元测试中忽略程序集匹配的检查,并在期望对它们进行签名时接受未签名的程序集?
据我所知,问题不是强名称验证。不仅错误是不同的,而且sn –Vr也没有影响:错误仍然存在。
实际问题似乎是在程序集绑定级别。这也是为什么我惊讶地看到AppDomain.CurrentDomain.AssemblyResolve事件被引发,但它的结果仍然被忽略;很可能,它没有做我一直认为它所做的事情。
发布于 2015-08-09 11:27:33
解决办法比我想的容易得多。正如我所猜测的,问题不是强名称验证,而是依赖公钥令牌的程序集绑定,因此可以在篡改程序集时替换令牌。
第一步是,在篡改之前,获取原始公钥和公钥令牌。它们都在AssemblyName内部。
var originalAssemblyBytes = File.ReadAllBytes(originalFilePath);
var originalAssemblyName = Assembly.Load(originalAssemblyBytes).GetName();下一步是篡改本身:首先使用ILRepack合并两个程序集,然后使用Mono.Cecil进行更多的粒度更改。在第二步中,使用Mono.Cecil替换公钥和公钥令牌:
var assemblyName = mergedModule.Assembly.Name;
assemblyName.HasPublicKey = true;
assemblyName.PublicKey = originalAssemblyName.GetPublicKey();
assemblyName.PublicKeyToken = originalAssemblyName.GetPublicKeyToken();必须同时进行更改:如果只更改了令牌,则一旦使用程序集,就会引发错误“无效程序集公钥”。
这对于使用.snk和.pfx签名的两个程序集都有效:因为测试是完全信任地运行的,所以验证没有完成,这意味着公钥与私钥不对应这一事实与此无关。
https://stackoverflow.com/questions/31900069
复制相似问题