- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
.NET 应用程序分布在名为程序集的文件中,其中包含元数据和通用中间语言 (CIL) 代码。 .NET 遵循的标准, ECMA-335 ,II.3,注意到两个发音相似的术语之间的区别:
如果程序集符合标准,则该程序集有效。
Validation refers to the application of a set of tests on any file to check that the file’s format, metadata, and CIL are self-consistent. These tests are intended to ensure that the file conforms to the normative requirements of this specification.
如果程序集有效,并且可以通过标准描述的静态分析算法证明该程序集是类型安全的,则该程序集是可验证的。
Verification refers to the checking of both CIL and its related metadata to ensure that the CIL code sequences do not permit any access to memory outside the program’s logical address space. In conjunction with the validation tests, verification ensures that the program cannot access memory or other resources to which it is not granted access.
所有可验证的程序集都是有效的,但并非所有有效的程序集都是可验证的。此外,某些有效的程序集实际上可能是类型安全的,但验证算法无法证明它们本身是类型安全的,因此它们不可验证。要使用标准中的图表:
.NET SDK 提供了一个工具来静态确定程序集是否可验证:PEVerify 。由于可验证的程序集也必须有效,因此如果程序集无效,此工具也会报告错误。
但是,似乎没有等效的工具或过程来确定程序集是否只是有效。例如,如果我已经知道程序集无法验证,并且我对此表示同意,那么如何确保运行时不会因程序无效而出错?
我的测试用例:
.assembly extern mscorlib
{
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 )
.ver 4:0:0:0
}
.assembly MyAsm { }
.module MyAsm.exe
.corflags 0x00020003 // ILONLY 32BITPREFERRED
.class public Program
{
.method public static int32 EntryPoint(string[] args) cil managed
{
.maxstack 2
.entrypoint
call string [MyAsm]Program::normal()
call void [mscorlib]System.Console::WriteLine(string)
call string [MyAsm]Program::unverifiable_init()
call void [mscorlib]System.Console::WriteLine(string)
call string [MyAsm]Program::unverifiable_jmp()
call void [mscorlib]System.Console::WriteLine(string)
call string [MyAsm]Program::invalid()
call void [mscorlib]System.Console::WriteLine(string)
ldc.i4.0
ret
}
.method public static string normal() cil managed
{
.maxstack 2
.locals init ([0] int32 initialized)
ldstr "From normal: "
ldloca initialized
call instance string [mscorlib]System.Int32::ToString()
call string [mscorlib]System.String::Concat(string, string)
ret
}
.method public static string unverifiable_jmp() cil managed
{
.maxstack 1
ldstr "Printing from unverifiable_jmp!"
call void [mscorlib]System.Console::WriteLine(string)
jmp string [MyAsm]Program::normal() // jmp is always unverifiable
}
.method public static string unverifiable_init() cil managed
{
.maxstack 2
.locals ([0] int32 hasGarbage) // uninitialized locals are unverifiable
ldstr "From unverifiable_init: "
ldloca hasGarbage
call instance string [mscorlib]System.Int32::ToString()
call string [mscorlib]System.String::Concat(string, string)
ret
}
.method public static string invalid() cil managed
{
.maxstack 1
ldstr "Printing from invalid!"
call void [mscorlib]System.Console::WriteLine(string)
ldstr "From invalid"
// method fall-through (no ret) is invalid
}
}
我使用ilasm
组装它,生成MyAsm.exe
。
虽然我可以运行程序集,但 .NET 运行时仅在调用 invalid()
方法时才会出错,而在加载程序集时不会出错。如果我删除该调用,则程序将顺利运行完成,因此仅加载并运行程序集并不能保证它完全有效。
在程序集上运行 PEVerify 会产生三个错误。虽然对于人眼来说很容易看出,在这种情况下,前两个错误是验证错误,最后一个错误是验证错误,但看起来没有一种简单的方法可以自动进行区分(例如,检查每一行的 verifi
似乎太宽泛了)。
Microsoft (R) .NET Framework PE Verifier. Version 4.0.30319.0
Copyright (c) Microsoft Corporation. All rights reserved.
[IL]: Error: [C:\...\MyAsm.exe : Program::unverifiable_jmp][offset 0x0000000A] Instruction cannot be verified.
[IL]: Error: [C:\...\MyAsm.exe : Program::unverifiable_init][offset 0x00000005] initlocals must be set for verifiable methods with one or more local variables.
[IL]: Error: [C:\...\MyAsm.exe : Program::invalid][offset 0x0000000A] fall through end of the method without returning
3 Error(s) Verifying MyAsm.exe
最佳答案
根据 @Damien_The_Unknowners 评论,我编写了这个使用 RuntimeHelpers.PrepareMethod Method 的小片段。编译每个方法。它不会处理所有情况(嵌套类型、泛型、引用解析……),但作为一个起点,它可以工作:
var b = File.ReadAllBytes("MyAsm.exe");
var asm = Assembly.Load(b);
foreach(var m in asm.GetModules())
{
foreach(var t in m.GetTypes())
{
foreach(var mb in t.GetMethods((BindingFlags)62).Cast<MethodBase>().Union(t.GetConstructors((BindingFlags)62)))
{
try
{
RuntimeHelpers.PrepareMethod(mb.MethodHandle);
}
catch (InvalidProgramException ex)
{
Console.WriteLine($"{mb.DeclaringType}::{mb.Name} - {ex.Message}");
}
}
}
}
将输出:
Program::invalid - Common Language Runtime detected an invalid program.
关于.net - 如何确保无法验证的 .NET 程序集有效?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48017599/
我遇到了一个奇怪的问题。我有这个: $(document).ready(function () {
我正在编写一个程序,它从列表中读取一些 ID,从中找出不同的 URL,然后将图像保存到我的 C: 驱动器中。 如果我在浏览器中导航到图像 URL,它们就会起作用。此外,如果我尝试从不同的服务器获取图像
我编写了一个 REST WCF RIA Silverlight 4.0 兼容服务,我可以从 javascript + jQuery.1.4.2.js + JSON2.js(当然,还可以从 .NET 4
我很确定这个网站实际上还没有得到回答。一劳永逸地,与 32 位有符号整数范围内的数字字符串匹配的最小正则表达式是什么,范围是 -2147483648至 2147483647 . 我必须使用正则表达式进
我有两个data.table;我想从那些与键匹配的元素中随机分配一个元素。我现在这样做的方式相当慢。 让我们具体点;这是一些示例数据: dt1<-data.table(id=sample(letter
我已经安装了 celery 、RabitMQ 和花。我可以浏览到花港。我有以下简单的工作人员,我可以将其附加到 celery 并从 python 程序调用: # -*- coding: utf-8 -
我正在使用 ScalaCheck 在 ScalaTest 中进行一些基于属性的测试。假设我想测试一个函数,f(x: Double): Double仅针对 x >= 0.0 定义的, 并返回 NaN对于
我想检查文件是否具有有效的 IMAGE_DOS_SIGNATURE (MZ) function isMZ(FileName : String) : boolean; var Signature: W
在 Herbert Schildt 的“Java:完整引用,第 9 版”中,有一个让我有点困惑的例子。它的关键点我无法理解可以概括为以下代码: class Test { public stat
我在工作中查看了一些代码,发现了一些我以前没有遇到过的东西: for (; ;) { // Some code here break; } 我们一直调用包含这个的函数,我最近才进去看看它是
在 Herbert Schildt 的“Java:完整引用,第 9 版”中,有一个让我有点困惑的例子。它的关键点我无法理解可以概括为以下代码: class Test { public stat
我试图编写一个函数,获取 2D 点矩阵和概率 p 并以概率 p 更改或交换每个点坐标 所以我问了一个question我试图使用二进制序列作为特定矩阵 swap_matrix=[[0,1],[1,0]]
这个问题在这里已经有了答案: Using / or \\ for folder paths in C# (5 个答案) 关闭 7 年前。 我在某个Class1中有这个功能: public v
PostgreSQL 10.4 我有一张 table : Column | Type ------------------------- id | integer| title
我正在 Postgresql 中编写一个函数,它将返回一些针对特定时区(输入)计算的指标。 示例结果: 主要问题是这只是一个指标。我需要从其他表中获取其他 9 个指标。 对于实现此目标的更简洁的方法有
我需要在 python 中模拟超几何分布(用于不替换采样元素的花哨词)。 设置:有一个装满人口许多弹珠的袋子。弹珠有两种类型,红色和绿色(在以下实现中,弹珠表示为 True 和 False)。从袋子中
我正在使用 MaterializeCSS 框架并动态填充文本输入。我遇到的一个问题是,在我关注该字段之前,valid 和 invalid css 类不会添加到我的字段中。 即使我调用 M.update
是否有重叠 2 个 div 的有效方法。 我有以下内容,但无法让它们重叠。 #top-border{width:100%; height:60px; background:url(image.jpg)
我希望你们中的一位能向我解释为什么编译器要求我在编译单元中重新定义一个静态固定长度数组,尽管我已经在头文件中这样做了。这是一个例子: 我的类.h: #ifndef MYCLASS_H #define
我正在使用旧线程发布试图解决相同问题的新代码。什么是安全 pickle ? this? socks .py from socket import socket from socket import A
我是一名优秀的程序员,十分优秀!