Application Verifier打破了非常简单的USER32程序

时间:2013-01-28 16:07:02

标签: windows winapi memory heap-corruption memory-corruption

我发现Microsoft Application Verifier正以意想不到的方式改变行为。我有一个程序在系统编辑控件上执行superclassing。当我在Application Verifier下使用Basics / Heaps / UseLFHGuardPages = TRUE运行它时(因为我在使用Low Frag Heap的Windows 7上),EDIT WindowProc在WM_NCCREATE上返回0(FALSE),阻止创建控件。这打破了整个应用程序,因为它无法继续前进。

这是一个极简主义的来源,可用于在Application Verifier上重现问题:

#include <windows.h>
#include <stdio.h>

LRESULT CALLBACK DialogWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    return DefWindowProc(hWnd, Msg, wParam, lParam);
}

static WNDCLASS wcEDIT;

LRESULT CALLBACK EditWindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) {
    LRESULT result = CallWindowProc(wcEDIT.lpfnWndProc, hWnd, Msg, wParam, lParam);
    if (Msg == WM_NCCREATE && result == 0) {
        puts("UNEXPECTED: WindowProc of EDIT returned 0 (FALSE) on WM_NCCREATE");
    }
    return result;
}

int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {

    WNDCLASS wcDialog;
    memset(&wcDialog, 0, sizeof wcDialog);
    wcDialog.hInstance = hInstance;
    wcDialog.lpszClassName = "MyDialog";
    wcDialog.lpfnWndProc = DialogWindowProc;
    wcDialog.style = CS_DBLCLKS;

    if (RegisterClass(&wcDialog) == 0) {
        printf("Unable to register class %s\n", wcDialog.lpszClassName);
        return 0;
    }

    HWND hForm;
    {
        const char *lpClassName = wcDialog.lpszClassName;
        const char *lpWindowName = NULL;
        DWORD dwStyle = WS_MAXIMIZEBOX|WS_MINIMIZEBOX|WS_THICKFRAME|WS_SYSMENU|WS_DLGFRAME|WS_BORDER|WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
        DWORD dwExStyle = 0;
        int X = 0;
        int Y = 0;
        int nWidth = 320;
        int nHeight = 240;
        HWND hWndParent = 0;
        HMENU hMenu = 0;
        LPVOID lpParam = NULL;

        hForm = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
        if (hForm == 0) {
            printf("Unable to create window of class %s\n", wcDialog.lpszClassName);
            return 0;
        }
    }

    memset(&wcEDIT, 0, sizeof wcDialog);
    wcEDIT.lpszClassName = "EDIT";
    if (!GetClassInfo(NULL, wcEDIT.lpszClassName, &wcEDIT)) {
        printf("Unable to get class info of %s\n", wcEDIT.lpszClassName);
        return 0;
    }

    WNDCLASS wcMyEDIT;
    memcpy(&wcMyEDIT, &wcEDIT, sizeof WNDCLASS);
    wcMyEDIT.hInstance = hInstance;
    wcMyEDIT.lpszClassName = "MyEDIT";
    wcMyEDIT.lpfnWndProc = EditWindowProc;
    wcMyEDIT.style |= CS_DBLCLKS|CS_HREDRAW|CS_VREDRAW;

    if (RegisterClass(&wcMyEDIT) == 0) {
        printf("Unable to register class %s\n", wcMyEDIT.lpszClassName);
        return 0; 
    }

    HWND hEdit;
    {
        const char *lpClassName = wcMyEDIT.lpszClassName;
        const char *lpWindowName = NULL;
        DWORD dwStyle = WS_CLIPSIBLINGS|WS_CHILD|ES_AUTOVSCROLL|ES_AUTOHSCROLL;
        DWORD dwExStyle = WS_EX_CLIENTEDGE;
        int X = 0;
        int Y = 0;
        int nWidth = 121;
        int nHeight = 21;
        HWND hWndParent = hForm;
        HMENU hMenu = 0;
        LPVOID lpParam = NULL;

        hEdit = CreateWindowEx(dwExStyle, lpClassName, lpWindowName, dwStyle, X, Y, nWidth, nHeight, hWndParent, hMenu, hInstance, lpParam);
        if (hEdit == 0) {
            printf("Unable to create window of class %s\n", wcMyEDIT.lpszClassName);
            return 0;
        }
    }

    puts("success");
    return 0;
}

0 个答案:

没有答案