gpt4 book ai didi

c# - 为什么这段代码在没有 unsafe 关键字的情况下也能工作?

转载 作者:IT王子 更新时间:2023-10-29 04:44:11 27 4
gpt4 key购买 nike

an answer到他自己的controversial question , Mash已经说明您不需要“不安全”关键字来直接读取和写入任何 .NET 对象实例的字节。您可以声明以下类型:

   [StructLayout(LayoutKind.Explicit)]
struct MemoryAccess
{

[FieldOffset(0)]
public object Object;

[FieldOffset(0)]
public TopBytes Bytes;
}

class TopBytes
{
public byte b0;
public byte b1;
public byte b2;
public byte b3;
public byte b4;
public byte b5;
public byte b6;
public byte b7;
public byte b8;
public byte b9;
public byte b10;
public byte b11;
public byte b12;
public byte b13;
public byte b14;
public byte b15;
}

然后您可以执行诸如更改“不可变”字符串之类的操作。以下代码在我的机器上打印“bar”:

 string foo = "foo";
MemoryAccess mem = new MemoryAccess();
mem.Object = foo;
mem.Bytes.b8 = (byte)'b';
mem.Bytes.b10 = (byte)'a';
mem.Bytes.b12 = (byte)'r';
Console.WriteLine(foo);

您还可以触发 AccessViolationException通过使用相同的技术破坏对象引用。

问题:我认为(在纯托管 C# 代码中)unsafe关键字是做这样的事情所必需的。为什么这里没有必要? 这是否意味着纯托管“安全”代码根本不安全?

最佳答案

好吧,这很讨厌……使用工会的危险。这可能行得通,但不是一个好主意——我想我会把它比作反射(你可以做大部分事情)。我很想看看这是否适用于受限访问环境 - 如果是这样,它可能代表一个更大的问题......


我刚刚在没有“完全信任”标志的情况下对其进行了测试,运行时拒绝了它:

Could not load type 'MemoryAccess' from assembly 'ConsoleApplication4, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' because objects overlapped at offset 0 and the assembly must be verifiable.

要拥有这个标志,您已经需要高度信任 - 所以您已经可以做更多令人讨厌的事情了。字符串的情况略有不同,因为它们不是普通的 .NET 对象——但是还有其他改变它们的方法的例子——不过,“联合”方法是一种有趣的方法。对于另一种 hacky 方式(有足够的信任):

string orig = "abc   ", copy = orig;
typeof(string).GetMethod("AppendInPlace",
BindingFlags.NonPublic | BindingFlags.Instance,
null, new Type[] { typeof(string), typeof(int) }, null)
.Invoke(orig, new object[] { "def", 3 });
Console.WriteLine(copy); // note we didn't touch "copy", so we have
// mutated the same reference

关于c# - 为什么这段代码在没有 unsafe 关键字的情况下也能工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/792735/

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