Предисловие: привет amirul ;)
Давече дописывал тут одну свою фриварную тулзу (HKM) и напоролся на бсод, вызываемый юзермодным кодом без админских прав. workaround от бсода я придумал, ибо негоже мелкой тулзе винду убивать, но сам бсод - есть баг микрософтовский. И вот относительно минимальный, исключительно юзермодный код, которым он воспроизводится:
Готовый проект для VC6 (с откомпиленными бинарями) можно скачать тут: http://slil.ru/26296017
Исходники, а то долго рассказывать что код делает:
hookproc.dll:
,
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
return TRUE;
}
extern "C" __declspec(dllexport) LRESULT CALLBACK DummyHookProc(int nCode, WPARAM wParam,LPARAM lParam)
{
::Sleep(0);
return ::CallNextHookEx(0, nCode, wParam, lParam);
}
---,
launch.exe:
,
extern "C" __declspec(dllimport) LRESULT CALLBACK DummyHookProc(int nCode, WPARAM wParam,LPARAM lParam);
HANDLE g_stop_event = CreateEvent(NULL, TRUE, FALSE, NULL);
DWORD CALLBACK WinThreadProc(PVOID p)
{
TCHAR name[32];
if (p)
wsprintf(name, "desk_%x", p);
else
wsprintf(name, "default");
HDESK desk = ::CreateDesktop(name, 0, 0, 0, GENERIC_ALL, 0);
HDESK old_desk = ::GetThreadDesktop(::GetCurrentThreadId());
::SetThreadDesktop(desk);
for(int i=0; i<8; i++)
{
CreateWindow(TEXT("STATIC"), TEXT("dummy"),
WS_VISIBLE, 10, i*30, 200, 30, 0, 0, 0, 0);
}
MSG msg;
while (1)
{
::GetMessage(&msg, NULL, 0, 0);
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
::SetThreadDesktop(old_desk);
::CloseDesktop(desk);
return 0;
}
DWORD CALLBACK ThreadProc(PVOID p)
{
TCHAR name[32];
if (p)
wsprintf(name, "desk_%x", p);
else
wsprintf(name, "default");
HDESK desk = ::CreateDesktop(name, 0, 0, 0, GENERIC_ALL, 0);
::SwitchDesktop(desk);
::Sleep(0);
HDESK old_desk = ::GetThreadDesktop(::GetCurrentThreadId());
::SetThreadDesktop(desk);
HINSTANCE dll = ::GetModuleHandle(TEXT("HOOKPROC.dll"));
HHOOK hk1 = ::SetWindowsHookEx(WH_MOUSE, DummyHookProc, dll, 0);
HHOOK hk2 = ::SetWindowsHookEx(WH_CALLWNDPROC, DummyHookProc, dll, 0);
HHOOK hk3 = ::SetWindowsHookEx(WH_CALLWNDPROCRET, DummyHookProc, dll, 0);
HHOOK hk4 = ::SetWindowsHookEx(WH_GETMESSAGE, DummyHookProc, dll, 0);
for (;;)
{
MSG msg;
while (::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
::TranslateMessage(&msg);
::DispatchMessage(&msg);
}
if (::MsgWaitForMultipleObjects(1, &g_stop_event,
FALSE, INFINITE, QS_ALLINPUT) == WAIT_OBJECT_0)
{
break;
}
}
::SwitchDesktop(old_desk);
::Sleep(0);
::UnhookWindowsHookEx(hk1);
::UnhookWindowsHookEx(hk2);
::UnhookWindowsHookEx(hk3);
::UnhookWindowsHookEx(hk4);
::PostMessage(HWND_BROADCAST, WM_NULL, 0, 0);
::SendNotifyMessage(HWND_BROADCAST, WM_NULL, 0, 0);
::SetThreadDesktop(old_desk);
::CloseDesktop(desk);
return 0;
}
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
int i;
for(i=0; i<4; i++)
{
::CloseHandle(::CreateThread(NULL, 0, WinThreadProc, (LPVOID)i, 0, NULL));
}
::Sleep(1000);;
while((::GetAsyncKeyState(VK_ESCAPE)&32768)==0)
{
for(i=0; i<4; i++)
{
HANDLE trd = ::CreateThread(NULL, 0, ThreadProc, (LPVOID)i, 0, NULL);
::Sleep(500);
::SetEvent(g_stop_event);
::WaitForSingleObject(trd, INFINITE);
::ResetEvent(g_stop_event);
::CloseHandle(trd);
}
}
return 0;
}
---,
BSOD'ятся или жестко зависают в течении нескольких минут работы проги 2к3 на одноядерном атлоне, и Vista x86 на двухядерном интеле.
Стек бсода с висты:
ChildEBP RetAddr Args to Child
8f5ac728 81e835a0 0000008e c0000005 97915cd3 nt!KeBugCheckEx+0x1e
8f5acaf8 81ea563a 8f5acb14 00000000 8f5acb68 nt!KiDispatchException+0x1a9
8f5acb60 81ea55ee 8f5acc5c 97915cd3 badb0d00 nt!CommonDispatchException+0x4a (FPO: [0,20,0])
8f5acb80 81f02215 0000000b 948f53f0 00000000 nt!KiExceptionExit+0x186
8f5acc5c 97991dad 15e02058 00000000 00000000 nt!EtwTraceContextSwap+0x14a
8f5acc78 979d9b8b 00000000 00000000 00000000 win32k!xxxCallNextHookEx+0x35 (FPO: [Non-Fpo])
8f5acccc 979166ed fbe024f0 00000005 00000000 win32k!fnHkINLPCWPEXSTRUCT+0x5d (FPO: [Non-Fpo])
8f5acce8 9793d674 fbe024f0 00000005 00000000 win32k!NtUserfnDWORD+0x27 (FPO: [Non-Fpo])
8f5acd20 81ea4a7a 005d00bc 00000005 00000000 win32k!NtUserMessageCall+0xc6 (FPO: [Non-Fpo])
8f5acd20 77549a94 005d00bc 00000005 00000000 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8f5acd44)
06ecea5c 76b48871 76b70b70 005d00bc 00000005 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
06ecea60 76b70b70 005d00bc 00000005 00000000 USER32!NtUserMessageCall+0xc (FPO: [Non-Fpo])*WARNING: Unable to verify checksum for hookproc.dll*ERROR: Symbol file could not be found. Defaulted to export symbols for hookproc.dll -
06ecea90 1000102f 00000000 00000000 00000000 USER32!CallNextHookEx+0x10b (FPO: [Non-Fpo])
WARNING: Stack unwind information not available. Following frames may be wrong.
06ecead8 76b929ff 00040000 00000000 06eceaf0 hookproc!DummyHookProc+0x1f
06eceb00 76b50a65 084124f0 00000005 00000000 USER32!fnHkINLPCWPSTRUCTA+0x4f (FPO: [Non-Fpo])
06eceb28 775499ce 06eceb40 00000018 06ecf208 USER32!__fnDWORD+0x24 (FPO: [Non-Fpo])
06eceb54 76b43cf7 76b43b94 00000088 06ecee80 ntdll!KiUserCallbackDispatcher+0x2e (FPO: [0,0,0])
06eceb58 76b43b94 00000088 06ecee80 06eceba8 USER32!NtUserCreateWindowEx+0xc (FPO: [Non-Fpo])
06ecedfc 76b43cc3 00000088 06ecee80 06ecee94 USER32!VerNtUserCreateWindowEx+0x1ac (FPO: [Non-Fpo])
06eceea8 76b43d9a 00000088 6ff5239c 06ecee94 USER32!_CreateWindowEx+0x1f9 (FPO: [Non-Fpo])
---
|