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

How can I detect that a .NET assembly I am loading contains unsafe code?

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

元数据中是否存在不安全标记持续存在的位置?是否存在不安全的特定 CIL 指令?是否有另一种方法可以确定随机 DLL 是否包含不安全代码?

当然,不安全的代码不是唯一的安全问题,但这是我现在要处理的问题。

我会使用这种启发式方法来检测不安全代码:检查固定块以获取其地址的对象。

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

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

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

请注意,除 C# 之外的编译器可以自由使用这些作为安全方法正常编译的一部分,但是,对于 C#,这种启发式方法应该可以完美运行。