1.4.1 IL和验证
IL 是基于栈的,也就是它的所有指令都要将操作数压入(push)一个执行栈,并从栈弹出(pop)结果.
IL 指令是”无类型”(typeless)的,例如IL提供了一个add指令,它的作用是判断栈中最后两个操作数的类型并且将它们加到一起.
将IL编译成本地CPU指令时,CLR会执行一个名为验证(verification)的过程,这个过程确定代码所做的一切都是安全的,这也就是IL的优势之一:健壮性和安全性.例如,验证正确的数量参数,返回值的正确使用等等.
将每个windows进程都放到一个独立的地址空间可以获得健壮性与稳定性:进程间不互相干扰.
进程数量太多,会损害性能并制约可用的资源.
通过验证托管代码,可确保代码不会不正确地访问内存和干扰其他应用程序的代码,这就可放心的将多个托管应用程序放到一个windows虚拟地址空间中运行,从而增强性能,减少需要的资源,而且健壮性也没有丝毫下降.托管代码比较非托管代码的另一个优势.
CLR提供了一个操作系统进程中执行多个托管应用程序的能力,每个托管的应用程序都在一个AppDomain中执行,默认情况下,每个托管的EXE文件都在它自己的独立地址空间中运行,这个地址空间只有一个AppDomain.
1.4.2 不安全的代码
不安全的代码会破坏数据结构危害安全性或造成新的安全漏洞.
C#编译器默认生成的是安全(safe)的代码, C#编译器要求包含不安全代码的所有方法都用unsafe关键字标记,还要求使用/unsafe编译器开关来编译源代码.
JIT编译器编译unsafe方法时会验证System.Security.Permissions.SecurityPermission权限以及System.Security.Permission.SecurityPermissionFlag的SkipVerification标志已被设置,若通过验证,则会编译不安全的代码并执行它,如果验证失败,JIT会抛出个System.InvalidProgramException或System.Security.VerificationException异常,禁止方法执行.
Microsoft提供了一个名为PEVerify.exe的程序,检查程序集的所有方法,并报告其中含有的不安全代码的方法.使用它来验证时,它必须能够定位并加载这个程序集所引用的所有程序集.
IL代码和知识产权保护,因为IL是可以通过反汇编器来进行逆向工程,还远代码的.可以用混淆器进行混淆,但是这保护是有限的,因为IL必须在某个时候提供给CLR进行JIT编译.可考虑用非托管模块实现想保密的算法,然后再利用CLR的互操作功能来实现托管与非托管部分的通行.