gpt4 book ai didi

c# - 使用 Peverify 和 ILVerify 对不安全的 c# 返回类型进行验证错误

转载 作者:太空狗 更新时间:2023-10-29 20:19:20 25 4
gpt4 key购买 nike

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

例子可以这样表示:

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()][offset 0x00000006][found address of Int32] Expected numeric type on the stack.

[IL]: Error: [C:\src\test\example.dll : A::Main()][offset 0x00000009][found Native Int] Expected ByRef on the stack.2 Error(s) Verifying C:\src\test\example.dll

奥秘在于,一切都按预期编译和运行,它不会验证。有谁知道为什么会这样吗?

最佳答案

从根本上说:不安全的代码是无法验证的。您返回的确切消息通常会含糊不清且令人困惑,但话又说回来:不安全代码也是如此 (badum tsh)!

更糟糕的是:问题中的代码被主动破坏了——对于从已退出的堆栈框架访问指针时发生的情况,没有定义的行为。在这种情况下,您通常会避开它并看到最后的值,但是:它没有定义。

如果你想要可验证的代码,你将需要切换到ref return;例如:

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})deferences 托管指针,就像 i = * {somePtr} 用于非托管指针。

这清楚地验证了:

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.

关于c# - 使用 Peverify 和 ILVerify 对不安全的 c# 返回类型进行验证错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48383066/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com