首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Peverify和ILVerify对不安全的ILVerify返回类型的验证错误

使用Peverify和ILVerify对不安全的ILVerify返回类型的验证错误
EN

Stack Overflow用户
提问于 2018-01-22 13:47:05
回答 1查看 356关注 0票数 7

在验证一些包含返回指针的不安全方法的代码时,我遇到了这个问题。

该示例可以表示如下:

代码语言:javascript
复制
public class A
{
    public static unsafe int* GetAnswer()
    {
        int fakeValue = 42;
        return &(fakeValue);
    }

    public static void Main()
    {
        int i = 0;
        unsafe { i = *A.GetAnswer(); }
        System.Console.WriteLine(i);
    }
}

我正在使用两个独立的验证工具,即ILVerify和Peverify。

复制步骤:

  1. 使用csc example.cs /t:library /unsafe编译示例代码
  2. 验证peverify example.dll
  3. 验证ILVerify.exe -r C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscorlib.dll example.dll

2和3都将导致以下错误消息:

IL: Error: C:\src\test\example.dll :a::GetAnswer()找到堆栈上Int32期望的数字类型的地址。 IL: Error: C:\src\test\example.dll :a::Main()在堆栈上找到了本机Int期望的ByRef。验证C:\src\test\example.dll的2错误

神秘的是,所有的东西都会像预期的那样编译和运行,它不会进行验证。有谁对为什么会这样有洞察力吗?

EN

回答 1

Stack Overflow用户

发布于 2018-01-22 14:23:32

从根本上说,不安全的代码是不可验证的。你得到的确切信息通常是模糊和混乱的,但话又说回来:不安全的代码(badum )也是如此!

更糟糕的是:问题中的代码是主动中断的--当您从已退出的堆栈帧访问指针时,没有定义的行为。在这种情况下,您通常会忽略它,并看到最后的值,但是:它没有定义。

如果您需要可验证的代码,则需要切换到ref return;例如:

代码语言:javascript
复制
static ref int GetAnswer(int[] arr)
{
    return ref arr[0];
}

static void Main()
{
    int i = 0;
    int[] j = new int[] { 42 };
    i = A.GetAnswer(j);
    System.Console.WriteLine(i);
}

这不使用不安全的代码。GetAnswer返回对数组中第一个元素的引用(而不是,第一个元素的值)-作为托管指针(ref T是托管指针;T*是非托管指针)。分配i = {someRef} (而不是i = ref {someRef})可以推断托管指针,就像i = *{somePtr}对非托管指针所做的那样。

这清楚地验证了:

代码语言:javascript
复制
Microsoft (R) .NET Framework PE Verifier.  Version  4.0.30319.0
Copyright (c) Microsoft Corporation.  All rights reserved.

All Classes and Methods in ConsoleApp35.exe Verified.
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48383066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档