绕过C#的类型安全措施并在字符串中存储整数

时间:2013-07-14 17:19:50

标签: c# debugging unsafe

查看以下代码:

static void Main(string[] args)
{
    string s = null;
    string[] myArray = new string[1];

    { } // do something evil here

    if (s.GetType() == typeof(int))
    {
        Console.WriteLine("This should not happen!"); 
    }
    Console.ReadLine();
}

有没有办法让This should not happen写出来?人们会假设没有。但是,可以使用调试器完成:将断点放入行{ } // do something evil here并在立即窗口中执行以下命令,然后继续:

((object[])myArray)[0] = 99;
s = myArray[0];

继续执行并打印This should not happen。使用Visual Studio 2008测试;这是截图:

screenshot

这种技巧只能用于调试器吗?还是有某种方法可以在代码中进行这种“不安全的分配”?

(显然,我只是出于科学的好奇心。This question和相关的评论让我问这个问题。)

1 个答案:

答案 0 :(得分:2)

一种技术是使用LayoutKind.Explicit来实现一个联合,可以用来重新解释将任意对象转换为字符串。首先选择一个int,然后将其分配给union的object字段,然后读出字符串字段。

[StructLayout(LayoutKind.Explicit)]
public struct Evil
{
    [FieldOffset(0)]
    public string s;

    [FieldOffset(0)]
    public object o;
}

string ReinterpretCastToString(object o)
{
    Evil evil=new Evil();
    evil.o=o;
    return evil.s;
}

void Main()
{
    string s = ReinterpretCastToString(1);

    if (s.GetType() == typeof(int))
    {
        Console.WriteLine("This should not happen!"); 
    }
}

这很可能是未定义的行为,可能随时停止工作。显然你不应该在真正的程序中使用它。