我的程序在app验证程序中崩溃,我不完全理解崩溃。我有一个缓冲区,由文件中的字节数动态分配:
DWORD dwSizeBytes = (DWORD)liSize.QuadPart+2;
TCHAR* JSONBufferW = new TCHAR [dwSizeBytes/sizeof(TCHAR)];
memset(JSONBufferW, 0, dwSizeBytes);
dwSizeBytes
(我可以在崩溃转储中看到这个)是38
。在此之后,我从文件中读取了一些数据:
if(!ReadFile(hFile, JSONBufferW, dwSizeBytes, &dwSizeBytes, NULL))
{
status = GetLastError();
TRACE_ERROR(g_hTrace, "ReadFile() failed for %S, error code=%d", strCompletePath, status);
}
这会将36
分配给dwSizeBytes
,将缓冲区中的最后两个字节留空,以便缓冲区以NULL结尾。但是,在app verifier下,当我尝试从缓冲区构造std::wstring
时,这会导致崩溃。
当我在windbg中查看缓冲区的分配块时,我发现它看起来像这样:
0:022> dd 0x00000000`07560fd0-0x48 0x00000000`07560fd0
00000000`07560f88 00001000 00000000 abcdbbbb 00000000
00000000`07560f98 07191000 00000000 00000026 00000000
00000000`07560fa8 00001000 00000000 00000000 00000000
00000000`07560fb8 00000000 00000000 0025a230 00000000
00000000`07560fc8 00001000 dcbabbbb 0022007b
注意显示我的缓冲区的0x26
应该是38个大小。现在我看看它自己的缓冲区并看到:
0:022> dc 0x00000000`07560fd0
00000000`07560fd0 0022007b 006f006d 00650064 003a0022 {.".m.o.d.e.".:.
00000000`07560fe0 006d0022 006e0061 00610075 0022006c ".m.a.n.u.a.l.".
00000000`07560ff0 000a007d d0d0fafa d0d0d0d0 d0d0d0d0 }...............
这表明我的缓冲区已被ReadFile
填充,但NULL
应该留在buf[36]
和buf[37]
(请记住memset)有一个应用程序验证者填充代码fafa
(请记住,unicode字节被翻转,因此d0d0
实际上是在fafa
之后。
我看了here:它向我展示了分配后app验证程序如何留下这些填充代码。但fafa
未列出,那是什么意思?为什么它应该在memset
应该清除的地方?
答案 0 :(得分:1)
我目前没有这方面的资源,但AppVerifier所做的功能之一就是在调用ReadFile之前用一个模式完全填充缓冲区。您请求读取38个字节,AppVerifier使用38个字节的模式填充缓冲区,而ReadFile仅从文件中读取36个字节。因此,您的最后2个字节是填充模式而不是预期的NULL字符。