我正在尝试使用C#为学校项目创建缓冲区溢出:
unsafe
{
fixed (char* ptr_str = new char[6] {'H', 'a', 'l', 'l', 'o', ','})
{
fixed (char* ptr_str2 = new char[6] {'W', 'e', 'r', 'e', 'l', 'd'})
{
fixed (char* ptr_str3 = new char[6] {'!', '!', '!', '!', '!', '!'})
{
for (int i = 0; i < 8; i++)
{
ptr_str2[i] = 'a';
}
for (int i = 0; i < 6; i++)
{
this.Label2.Text += ptr_str[i];
this.Label3.Text += ptr_str2[i];
this.Label4.Text += ptr_str3[i];
}
}
}
}
}
我认为这会淹没ptr_str2
,从而覆盖ptr_str
中的字符。然而,这似乎没有发生。它确实执行但ptr_str
中的值不会被覆盖。
任何人都可以帮助实现这一目标吗?我不明白我做错了什么。
答案 0 :(得分:6)
堆栈溢出是调用堆栈的溢出。 这样做容易得多:
int Test ()
{
return Test ();
}
Console.WriteLine (Test ());
如果您的意思是缓冲区溢出,则会有similar question。
答案 1 :(得分:6)
利用缓冲区溢出的传统攻击会溢出堆栈缓冲区;你溢出了一个堆缓冲区。当一个缓冲区在堆栈上同时写入另一个缓冲区时,很容易看到写入一个缓冲区。尝试使用stackalloc而不是new char来强制分配到堆栈中。
答案 2 :(得分:5)
您错过了数组本身就是对象的事实。它们具有像任何托管引用类型的对象标头和存储数组大小的私有字段。在开始覆盖数组元素之前,必须先覆盖它们。在32位机器上,您将开始使用以下内容覆盖ptr_str2的第一个元素:
for (int i = 0; i < 13; i++) {
ptr_str[i] = 'a';
}
当然,它必须是13。
通过在for循环上设置断点来观察它。 Debug + Windows + Memory + Memory 1,在地址框中输入“ptr_str”。步骤代码以查看内存是否已更改。您将在此之后看到ptr_str2,syncblk为4个字节,方法表指针为4个字节,数组长度为4个字节。总共12个字节,6个字符。
答案 3 :(得分:0)
你似乎没有在这里制作Stackoverflow - 你根本就没有真正使用堆栈。你似乎试图创建一个缓冲区溢出,我认为不安全的C#就像C,它很相似,但有几个重要的区别。
可以简单地进行stackoverflow:
public void Stackoverflow()
{
Stackoverflow();
}
然后在某处调用Stackoverflow()
。