在 windbg 中调试变量周围的堆栈损坏

Debugging the stack corruptuion around a variable in windbg

我正在尝试使用 windows 中的 .dll 来测试 windows 中的自定义登录。这是 source of dll.

注意:这更像是一个一般的调试问题(&我正在使用的 .dll 插件的工作可能不需要)

Dll 加载正常(我可以在 windows 登录屏幕上直观地验证这一点)但是当我输入密码和 Otp 并提交时,它给出了一个错误提示 stack around the variable onelinew is corrupted。据我所知,这意味着它要么是因为写入的数据太多而缓冲区无法容纳,要么是因为试图引用不在内存中的东西?

我尝试附加 windbg 调试器以查找堆栈损坏的来源并尝试查看堆栈 frames/call stacks/register 值等各种内容...等等。但是我我对如何理解这一点感到困惑,因为我对这种调试方式有点陌生(现在已经 2 天了)。

我将附上错误和堆栈调用的屏幕截图,希望有人可以从这里告诉我们从哪里继续。

此插件创建的日志文件中的最后一条日志是MultiotpCredential::Dll compiled with SKIP_OTP_CHECK !!!!!!!!",即defined here

出现在错误框中的变量onelinewdefined here为:

void PrintLn(const wchar_t *message, int line)
{
    INIT_ZERO_CHAR(date_time, MAX_TIME_SIZE);
    GetCurrentTimeAndDate(date_time);
    WriteLogFile(date_time);

    // MessageBox(NULL, (LPCWSTR)message, NULL, MB_ICONWARNING);

    wchar_t onelinew[1024];
    swprintf_s(onelinew, sizeof(onelinew), message, line);

    //  OutputDebugStringW(message);
    WriteLogFile(onelinew);
    WriteLogFile("\n");
}

你已经完成了更困难的部分,即找到罪魁祸首。错误消息告诉您有基于堆栈的缓冲区溢出。

    wchar_t onelinew[1024];
    swprintf_s(onelinew, sizeof(onelinew), message, line);

请注意,在您的情况下,由于代码使用 wchar_t,因此每个字符有 2 个字节。简单地说,你的缓冲区最多可以包含1024wchar_t。如果 message 大于 1024 wchar_t(2048 字节,包括空字符)那么你的缓冲区溢出了。

swprintf_s is not very clear, but if I'm not mistaken (I think it's clearer in the documentation for swprintf) 的文档第二个参数是字符数,而不是字节数。

问题是 sizeof 运算符将 return 字节数(在本例中为 2048)告诉 API该缓冲区是 2048 个字符,但您的缓冲区只有 1024 个字符.

因此您应该这样指定(或使用 _countof 宏):

    wchar_t onelinew[1024];
    swprintf_s(onelinew, sizeof(onelinew) / sizeof(wchar_t), message, line);