2

我想编写一个易受攻击的程序,以更好地理解 C# 中的堆栈溢出(原因),也用于教育目的。基本上,我“只是”想要一个堆栈溢出,它会覆盖 EIP,所以我可以控制它并且可以指向我自己的代码。我的问题是:哪些对象使用堆栈作为内存位置?例如:程序使用递归逐字节读取来解析文本文件,直到找到换行符(是的,我认为没有人会这样做,但这只是为了学习......)。目前,我在文本文件中附加了一个带有 chars 十六进制值的字符串。此字符串是调用 main() 后实例化的对象的字段。使用 WinDbg,在堆栈从(几乎)无限递归中溢出后,我得到了这些值:

(14a0.17e0): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=00000000 ecx=0023f618 edx=778570b4 esi=fffffffe edi=00000000
eip=778b04f6 esp=0023f634 ebp=0023f660 iopl=0

顺便说一句,如果出于兴趣,我正在使用 Win7x86 AMD 机器。我见过很多使用 strcpy 导致堆栈溢出的 C++ 示例,c# 中是否有类似的方法?

最好的问候,游牧民族

编辑:我使用此代码导致堆栈溢出。

class FileTest
{
    FileStream fs = new FileStream("test.txt", FileMode.Open, FileAccess.Read);
    string line = String.Empty;
    public FileTest()
    {
        Console.WriteLine(ReadTillBreak());
    }

    private string ReadTillBreak()
    {
        int b = 0;
        b = fs.ReadByte();
        line += (char)b;
        if (b != 13)
            ReadTillBreak();
        return line;
    }
}

是否可以溢出堆栈并使用行字符串写入eip(因此,test.txt的内容)?

4

2 回答 2

4

您可以在 C 和 C++ 中利用堆栈损坏的原因是您自己处理内存,并且该语言允许您做各种疯狂的事情。C# 运行在一个专门设计用于防止很多此类问题的环境中。即,虽然您可以在 C# 中轻松生成堆栈溢出,但您无法使用托管代码以这种方式修改程序的控制流。

可以说,针对托管环境的利用通常是通过突破沙箱来发挥作用的。只要代码在沙箱中运行,就有很多这些技巧根本行不通。

如果您想了解堆栈损坏,我建议您坚持使用 C 或 C++。

于 2012-03-17T17:32:31.373 回答
0

我对你所尝试的内容的描述并不完全清楚。堆栈溢出通常不会“覆盖 EIP”。

要导致堆栈溢出,最直接的方法是这样的。

void RecursiveMethod()
{
    RecursiveMethod();
}

由于每次调用该方法都将返回地址存储在堆栈中,像这样无休止地调用它而不返回最终会耗尽所有堆栈空间。当然,现代 Windows 应用程序有大量的堆栈空间,因此可能需要一段时间。您可以通过在方法中添加参数或局部变量来增加每次调用的堆栈使用量。

于 2012-03-17T17:12:03.293 回答