C# 如何检测正在加载的.NET程序集包含不安全代码?

C# 如何检测正在加载的.NET程序集包含不安全代码?,c#,.net,dll,cil,unsafe,C#,.net,Dll,Cil,Unsafe,我正在编写一个插件系统,它要求我将.net DLL加载到环境中。我需要知道它们是否包含任何指针用法或“不安全”关键字的任何其他用法。我运行了一个很好的反射浏览器,这样我可以查找程序集中的所有类型、所有方法、所有外部引用,甚至DLL中的所有CIL指令。然而,据我所知,在使用unsafe关键字确定是否可以编译DLL之后,它并没有被保留 元数据中是否存在不安全标记持续存在的位置?是否有不安全的特定CIL说明?是否有其他方法确定随机DLL具有不安全代码 当然,不安全代码并不是唯一的安全问题,但它是我现在

我正在编写一个插件系统,它要求我将.net DLL加载到环境中。我需要知道它们是否包含任何指针用法或“不安全”关键字的任何其他用法。我运行了一个很好的反射浏览器,这样我可以查找程序集中的所有类型、所有方法、所有外部引用,甚至DLL中的所有CIL指令。然而,据我所知,在使用unsafe关键字确定是否可以编译DLL之后,它并没有被保留

元数据中是否存在不安全标记持续存在的位置?是否有不安全的特定CIL说明?是否有其他方法确定随机DLL具有不安全代码


当然,不安全代码并不是唯一的安全问题,但它是我现在正试图解决的问题。

我将使用这个启发式方法来检测不安全代码:检查固定块,其中对象被固定以获取其地址

为此,请思考程序集中的方法并获取它们的LocalVariableInfos。如果它们的任何IsPinned属性为true,则该方法是不安全的

这样做会错过的唯一不安全操作是stackalloc,因为它不需要固定。您可以通过检查方法体中是否存在用于在堆栈上分配空间的Localloc操作码来捕获这一点

执行这两项检查,您应该错过的唯一不安全的方法是通过指向局部变量的指针操纵堆栈上的值类型的方法。不幸的是,获取局部变量的地址是用于许多常规任务的常规编译器操作,您无法过滤掉它


请注意,C#以外的编译器可以自由地将其作为安全方法的正常编译的一部分使用,但是,对于C#来说,这种启发式方法应该可以完美地工作。

不安全是C#的特性,而不是.net特性啊,这很不幸。你知道有没有一种方法可以检测到C#中使用的编程特性来表示吗?没有我最初认为的那么多重复,但请参见,因为它包含了与相关文档链接的讨论。特别是,您实际想要知道的可能是如何检测程序集是否可验证。请注意,通常情况下,如果您自己的程序集提供了可验证的保证,它将无法加载不可验证的程序集。有关防止执行不安全代码的有用信息,请参见和。有一些特定的IL指令会导致无法验证的模块,但也有更多情况,如没有
init的
.locals
指令。还有
System.Security.UnverifiableCodeAttribute
,但如果有人有恶意,它可能会被删除。太棒了,谢谢!我现在正在侦破这两起案件。有一种情况是,这种方法忽略了。。。公共不安全的int-UnsafeMethod2(int-input){int*thePointer=(int*)input;thePointer=42;return*thePointer;}此函数必须不安全才能编译,但它不需要固定(显然是错误的)。我想我会说所有带“”的类型都是被禁止的,但我想你可能会对这种情况感兴趣,也可能会有其他想法。@JesseJoudrey-我认为获取值类型参数和局部变量的地址是C#编译器偶尔会做的事情。我记得见过它,但不知道在哪里。