C# 为什么CLR不检查链接到强名称dll的netmodules的哈希值

C# 为什么CLR不检查链接到强名称dll的netmodules的哈希值,c#,.net,dll,hash,C#,.net,Dll,Hash,为什么CLR不检查链接到强名称dll的netmodules的哈希值 现在整个故事 有两个独立的C#源文件simple.cs和complex.cs,它们被编译成两个NetModule csc /target:module complex.cs csc /target:module simple.cs 然后链接到强名称math.dll中 al /target:library /keyfile:keyfile.snk /out:math.dll /version:0.0.0.0 complex.n

为什么CLR不检查链接到强名称dll的netmodules的哈希值

现在整个故事

有两个独立的C#源文件simple.cs和complex.cs,它们被编译成两个NetModule

csc /target:module complex.cs
csc /target:module simple.cs
然后链接到强名称math.dll中

al /target:library /keyfile:keyfile.snk /out:math.dll /version:0.0.0.0 
complex.netmodule simple.netmodule
keyfile.snk已在前面通过运行以下命令创建:

sn /k keyfile.snk
已检查math.dll清单中对应于complex.netmodule和simple.netmodule的哈希值:

.file complex.netmodule
.hash = (D2 B4 1D 11 B1 50 C2 29 01 91 49 10 2C 28 91 45   // .....P.)..I.,(.E
         24 44 A3 B5 )                                     // $D..
.file simple.netmodule
.hash = (29 85 33 28 35 94 03 32 68 E4 30 B6 02 42 B2 8F   // ).3(5..2h.0..B..
         E8 0B A8 8F ) 
正在生成客户端exe:

csc /target:exe /reference:math.dll mathclient.cs
正在运行mathclient.exe和输出:

2+2=4 3平方=9


然后修改complex.cs并重新编译。在这里,我理解complex.netmodule的散列值应该更改

再次运行mathclient并期望引发异常,因为new complex.netmodule的哈希值与math.dll清单中的哈希值不匹配。然而结果是

2+2=2 3平方=10

因此,使用了complex.netmodule的新版本


知道CLR为什么没有对包含的NetModule执行哈希验证吗?

出于性能原因。如果必须计算所有二进制文件的哈希值,则加载应用程序将花费太长的时间。

“我知道complex.netmodule的哈希值应该更改。”-您是否确实检查了哈希值是否不同?我是否遗漏了什么,或者,当您“修改并重新编译”时,新的散列值是为最新版本的模块计算并放入新程序集中的,对吗?当对程序集的内容运行相同的哈希时,它将生成放入清单中的值?如果您尝试在不重新链接的情况下对模块的内容进行二进制替换,则应该失败。至于检查math.dll程序集,这是在程序集签名期间生成的程序集作用域上完成的。如果math.exe的FQN正确且程序集加载签名验证成功,则math.exe将拾取math.dll。(或者为该asseembly/keytoken启用了验证跳过)程序集是否在完全信任上下文中运行?如果是这样,出于性能原因,可能会绕过强名称验证。尝试通过以下操作禁用旁路。