在 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
出现在错误框中的变量onelinew
是defined 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);
我正在尝试使用 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
出现在错误框中的变量onelinew
是defined 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);