diff --git a/NotMyFault/exe/IOCTLCMD.H b/NotMyFault/exe/IOCTLCMD.H new file mode 100644 index 0000000..3ed9bf7 --- /dev/null +++ b/NotMyFault/exe/IOCTLCMD.H @@ -0,0 +1,31 @@ +//====================================================================== +// +// ioctlcmd.h +// +// Copyright (C) 2002 Mark Russinovich +// +// This file contains driver IOCTLs and definitions shared by the +// driver and the GUI. +// +//====================================================================== + +// +// Device type +// +#define FILE_DEVICE_MYFAULT 0x00008336 + + +// +// IOCTLS +// +#define IOCTL_BUFFER_OVERFLOW (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x00, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_WILD_POINTER (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x01, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_PAGE_FAULT (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x02, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_DEADLOCK (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x03, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_TRASH_STACK (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x04, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_LEAK_PAGED (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x05, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_IRQL (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x06, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_HANG (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x07, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_HANG_IRP (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x08, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_LEAK_NONPAGED (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x09, METHOD_BUFFERED, FILE_ANY_ACCESS ) +#define IOCTL_BSOD_COLOR (ULONG) CTL_CODE( FILE_DEVICE_MYFAULT, 0x10, METHOD_BUFFERED, FILE_ANY_ACCESS ) diff --git a/NotMyFault/exe/NotMyfault.dep b/NotMyFault/exe/NotMyfault.dep new file mode 100644 index 0000000..2602bcc --- /dev/null +++ b/NotMyFault/exe/NotMyfault.dep @@ -0,0 +1,6 @@ +# Microsoft Developer Studio Generated Dependency File, included by NotMyfault.mak + +.\notmyfault.c : \ + ".\IOCTLCMD.H"\ + ".\notmyfault.h"\ + diff --git a/NotMyFault/exe/NotMyfault.sln b/NotMyFault/exe/NotMyfault.sln new file mode 100644 index 0000000..a049d6a --- /dev/null +++ b/NotMyFault/exe/NotMyfault.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35327.3 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "NotMyfault", "NotMyfault.vcxproj", "{7C86ACEC-4A92-4977-8346-F9A6C37896B8}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Debug|x64.ActiveCfg = Debug|x64 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Debug|x64.Build.0 = Debug|x64 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Debug|x86.ActiveCfg = Debug|Win32 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Debug|x86.Build.0 = Debug|Win32 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Release|x64.ActiveCfg = Release|x64 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Release|x64.Build.0 = Release|x64 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Release|x86.ActiveCfg = Release|Win32 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {D83E184A-B459-4859-A5B5-60D1FAAF04A1} + EndGlobalSection +EndGlobal diff --git a/NotMyFault/exe/NotMyfault.suo.old b/NotMyFault/exe/NotMyfault.suo.old new file mode 100644 index 0000000..2ed3914 Binary files /dev/null and b/NotMyFault/exe/NotMyfault.suo.old differ diff --git a/NotMyFault/exe/NotMyfault.vcproj b/NotMyFault/exe/NotMyfault.vcproj new file mode 100644 index 0000000..72f47c6 --- /dev/null +++ b/NotMyFault/exe/NotMyfault.vcproj @@ -0,0 +1,539 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/NotMyFault/exe/NotMyfault.vcxproj b/NotMyFault/exe/NotMyfault.vcxproj new file mode 100644 index 0000000..3861bd2 --- /dev/null +++ b/NotMyFault/exe/NotMyfault.vcxproj @@ -0,0 +1,280 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + 17.0 + {7C86ACEC-4A92-4977-8346-F9A6C37896B8} + NotMyfault + + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + Application + v143 + false + MultiByte + + + + + + + + + + + + + + + + + + + + + + + <_ProjectFileVersion>17.0.35327.3 + + + .\Debug\ + .\Debug\ + true + + + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + true + + + .\Release\ + .\Release\ + false + + + $(Platform)\$(Configuration)\ + $(Platform)\$(Configuration)\ + false + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Debug/NotMyfault.tlb + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + .\Debug/NotMyfault.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level3 + true + EditAndContinue + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\Debug/NotMyfault.exe + true + true + .\Debug/NotMyfault.pdb + Windows + false + + MachineX86 + + + true + .\Debug/NotMyfault.bsc + + + + + _DEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Debug/NotMyfault.tlb + + + + Disabled + WIN32;_DEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + EnableFastChecks + MultiThreadedDebug + .\Debug/NotMyfault.pch + .\Debug/ + .\Debug/ + .\Debug/ + Level3 + true + ProgramDatabase + + + _DEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\Debug/NotMyfault.exe + true + true + .\Debug/NotMyfault.pdb + Windows + false + + MachineX64 + + + true + .\Debug/NotMyfault.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + Win32 + .\Release/NotMyfault.tlb + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\Release/NotMyfault.pch + .\Release/ + .\Release/ + .\Release/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\Release/NotMyfault.exe + true + RequireAdministrator + .\Release/NotMyfault.pdb + Windows + false + + MachineX86 + + + true + .\Release/NotMyfault.bsc + + + + + NDEBUG;%(PreprocessorDefinitions) + true + true + X64 + .\Release/NotMyfault.tlb + + + + MaxSpeed + OnlyExplicitInline + WIN32;NDEBUG;_WINDOWS;_CRT_SECURE_NO_DEPRECATE;%(PreprocessorDefinitions) + true + MultiThreaded + true + .\x64\Release/NotMyfault.pch + .\x64\Release/ + .\x64\Release/ + .\x64\Release/ + Level3 + true + + + NDEBUG;%(PreprocessorDefinitions) + 0x0409 + + + .\x64\Release/NotMyfault.exe + true + RequireAdministrator + .\x64\Release/NotMyfault.pdb + Windows + false + + MachineX64 + + + true + .\Release/NotMyfault.bsc + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/NotMyFault/exe/NotMyfault.vcxproj.filters b/NotMyFault/exe/NotMyfault.vcxproj.filters new file mode 100644 index 0000000..2a0ae0f --- /dev/null +++ b/NotMyFault/exe/NotMyfault.vcxproj.filters @@ -0,0 +1,46 @@ + + + + + {8244ffb9-4ad7-454f-a48b-e69f5b138640} + cpp;c;cxx;rc;def;r;odl;idl;hpj;bat + + + {a3b94c08-2c31-4b38-b78c-8d56007a276d} + h;hpp;hxx;hm;inl + + + {965922dc-decf-4f13-9801-8ec2169ac873} + ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe + + + + + Source Files + + + Source Files + + + + + Header Files + + + Header Files + + + Header Files + + + + + Resource Files + + + + + Resource Files + + + \ No newline at end of file diff --git a/NotMyFault/exe/driver.c b/NotMyFault/exe/driver.c new file mode 100644 index 0000000..66ab16c --- /dev/null +++ b/NotMyFault/exe/driver.c @@ -0,0 +1,258 @@ +/****************************************************************************** +* +* Regmon - Registry Monitor for Windows 95/98/Me/NT/2K/XP/IA64 +* +* Copyright (c) 1996-2002 Mark Russinovich and Bryce Cogswell +* See readme.txt for terms and conditions. +* +* Displays Registry activity in real-time. +* +******************************************************************************/ +#include +#include +#include + + +// Driver handle +HANDLE SysHandle = INVALID_HANDLE_VALUE; + + +/**************************************************************************** +* +* FUNCTION: InstallDriver( IN SC_HANDLE, IN LPCTSTR, IN LPCTSTR) +* +* PURPOSE: Creates a driver service. +* +****************************************************************************/ +BOOL InstallDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName, IN LPCTSTR ServiceExe) +{ + SC_HANDLE schService; + + // + // NOTE: This creates an entry for a standalone driver. If this + // is modified for use with a driver that requires a Tag, + // Group, and/or Dependencies, it may be necessary to + // query the registry for existing driver information + // (in order to determine a unique Tag, etc.). + // + + schService = CreateService(SchSCManager, // SCManager database + DriverName, // name of service + DriverName, // name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_KERNEL_DRIVER, // service type + SERVICE_DEMAND_START, // start type + SERVICE_ERROR_IGNORE, // error control type + ServiceExe, // service's binary + NULL, // no load ordering group + NULL, // no tag identifier + NULL, // no dependencies + NULL, // LocalSystem account + NULL // no password + ); + if (schService == NULL) + return FALSE; + + CloseServiceHandle(schService); + + return TRUE; +} + + +/**************************************************************************** +* +* FUNCTION: StartDriver( IN SC_HANDLE, IN LPCTSTR) +* +* PURPOSE: Starts the driver service. +* +****************************************************************************/ +BOOL StartDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName) +{ + SC_HANDLE schService; + BOOL ret; + + schService = OpenService(SchSCManager, + DriverName, + SERVICE_ALL_ACCESS + ); + if (schService == NULL) + return FALSE; + + ret = StartService(schService, 0, NULL) + || GetLastError() == ERROR_SERVICE_ALREADY_RUNNING + || GetLastError() == ERROR_SERVICE_DISABLED; + + CloseServiceHandle(schService); + return ret; +} + + +/**************************************************************************** +* +* FUNCTION: OpenDevice( IN LPCTSTR, HANDLE *) +* +* PURPOSE: Opens the device and returns a handle if desired. +* +****************************************************************************/ +BOOL OpenDevice(IN LPCTSTR DriverName, HANDLE* lphDevice) +{ + TCHAR completeDeviceName[64]; + HANDLE hDevice; + + // + // Create a \\.\XXX device name that CreateFile can use + // + // NOTE: We're making an assumption here that the driver + // has created a symbolic link using it's own name + // (i.e. if the driver has the name "XXX" we assume + // that it used IoCreateSymbolicLink to create a + // symbolic link "\DosDevices\XXX". Usually, there + // is this understanding between related apps/drivers. + // + // An application might also peruse the DEVICEMAP + // section of the registry, or use the QueryDosDevice + // API to enumerate the existing symbolic links in the + // system. + // + + if ((GetVersion() & 0xFF) >= 5) + { + // + // We reference the global name so that the application can + // be executed in Terminal Services sessions on Win2K + // + wsprintf(completeDeviceName, TEXT("\\\\.\\Global\\%s"), DriverName); + } + else + { + wsprintf(completeDeviceName, TEXT("\\\\.\\%s"), DriverName); + } + + hDevice = CreateFile(completeDeviceName, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL, + NULL + ); + if (hDevice == ((HANDLE)-1)) + return FALSE; + + // If user wants handle, give it to them. Otherwise, just close it. + if (lphDevice) + *lphDevice = hDevice; + else + CloseHandle(hDevice); + + return TRUE; +} + + +/**************************************************************************** +* +* FUNCTION: StopDriver( IN SC_HANDLE, IN LPCTSTR) +* +* PURPOSE: Has the configuration manager stop the driver (unload it) +* +****************************************************************************/ +BOOL StopDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName) +{ + SC_HANDLE schService; + BOOL ret; + SERVICE_STATUS serviceStatus; + + schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS); + if (schService == NULL) + return FALSE; + + ret = ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus); + + CloseServiceHandle(schService); + + return ret; +} + + +/**************************************************************************** +* +* FUNCTION: RemoveDriver( IN SC_HANDLE, IN LPCTSTR) +* +* PURPOSE: Deletes the driver service. +* +****************************************************************************/ +BOOL RemoveDriver(IN SC_HANDLE SchSCManager, IN LPCTSTR DriverName) +{ + SC_HANDLE schService; + BOOL ret; + + schService = OpenService(SchSCManager, + DriverName, + SERVICE_ALL_ACCESS + ); + + if (schService == NULL) + return FALSE; + + ret = DeleteService(schService); + CloseServiceHandle(schService); + return ret; +} + + +/**************************************************************************** +* +* FUNCTION: UnloadDeviceDriver( const TCHAR *) +* +* PURPOSE: Stops the driver and has the configuration manager unload it. +* +****************************************************************************/ +BOOL UnloadDeviceDriver(const TCHAR* Name) +{ + SC_HANDLE schSCManager; + + schSCManager = OpenSCManager(NULL, // machine (NULL == local) + NULL, // database (NULL == default) + SC_MANAGER_ALL_ACCESS // access required + ); + + StopDriver(schSCManager, Name); + RemoveDriver(schSCManager, Name); + + CloseServiceHandle(schSCManager); + + return TRUE; +} + +/**************************************************************************** +* +* FUNCTION: LoadDeviceDriver( const TCHAR, const TCHAR, HANDLE *) +* +* PURPOSE: Registers a driver with the system configuration manager +* and then loads it. +* +****************************************************************************/ +BOOL LoadDeviceDriver(const TCHAR* Name, const TCHAR* Path, + HANDLE* lphDevice, PDWORD Error) +{ + SC_HANDLE schSCManager; + BOOL okay; + + schSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS); + + // Remove old instances + RemoveDriver(schSCManager, Name); + + // Ignore success of installation: it may already be installed. + InstallDriver(schSCManager, Name, Path); + + // Ignore success of start: it may already be started. + StartDriver(schSCManager, Name); + + // Do make sure we can open it. + okay = OpenDevice(Name, lphDevice); + *Error = GetLastError(); + CloseServiceHandle(schSCManager); + + return okay; +} diff --git a/NotMyFault/exe/icon1.ico b/NotMyFault/exe/icon1.ico new file mode 100644 index 0000000..9811033 Binary files /dev/null and b/NotMyFault/exe/icon1.ico differ diff --git a/NotMyFault/exe/notmyfault.c b/NotMyFault/exe/notmyfault.c new file mode 100644 index 0000000..2510043 --- /dev/null +++ b/NotMyFault/exe/notmyfault.c @@ -0,0 +1,531 @@ +//====================================================================== +// +// NotMyFault.c +// +// Copyright (C) 2002 Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// Simple interface to myfault device driver. +// +//====================================================================== +#include +#include +#include +#include "resource.h" +#include "ioctlcmd.h" +#include "notmyfault.h" + +COLORREF BsodFg = RGB(0xFF, 0xFF, 0xFF); +COLORREF BsodBg = RGB(0xFF, 0, 0); + +#pragma comment(linker,"\"/manifestdependency:type='win32' name='Microsoft.Windows.Common-Controls' version='6.0.0.0' processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"") + + +//---------------------------------------------------------------------- +// +// Abort +// +// Exit with a fatal error. +// +//---------------------------------------------------------------------- +LONG Abort(HWND hWnd, char* Msg, DWORD Error) +{ + LPVOID lpMsgBuf; + char errmsg[MAX_PATH * 2]; + DWORD error = GetLastError(); + + FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, Error, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPTSTR)&lpMsgBuf, 0, NULL); + UnloadDeviceDriver(SYS_NAME); + sprintf(errmsg, "%s: %s", Msg, lpMsgBuf); + if ((Error == ERROR_INVALID_HANDLE || Error == ERROR_ACCESS_DENIED || + Error == ERROR_FILE_NOT_FOUND)) + wsprintf(errmsg, "%s\nMake sure that you are an administrator and that NotMyFault is " + "not already running.", errmsg); + MessageBox(hWnd, errmsg, "NotMyFault", MB_OK | MB_ICONERROR); + PostQuitMessage(1); + LocalFree(lpMsgBuf); + return (DWORD)-1; +} + + +//---------------------------------------------------------------------- +// +// CenterWindow +// +// Centers the Window on the screen. +// +//---------------------------------------------------------------------- +VOID CenterWindow(HWND hDlg) +{ + RECT aRt; + + // center the dialog box + GetWindowRect(hDlg, &aRt); + OffsetRect(&aRt, -aRt.left, -aRt.top); + MoveWindow(hDlg, + ((GetSystemMetrics(SM_CXSCREEN) - + aRt.right) / 2 + 4) & ~7, + (GetSystemMetrics(SM_CYSCREEN) - + aRt.bottom) / 2, + aRt.right, aRt.bottom, 0); +} + +//---------------------------------------------------------------------- +// +// BsodColorsCallback +// +//---------------------------------------------------------------------- +UINT_PTR CALLBACK BsodColorsCallback(HWND hDlg, UINT uiMsg, WPARAM wParam, LPARAM lParam) +{ + static COLORREF newFg, newBg; + static UINT wm_colorOkString, wm_setRgbString; + HBRUSH hBack; + + switch (uiMsg) + { + case WM_INITDIALOG: + newFg = BsodFg; + newBg = BsodBg; + wm_colorOkString = RegisterWindowMessage(COLOROKSTRING); + wm_setRgbString = RegisterWindowMessage(SETRGBSTRING); + CheckRadioButton(hDlg, IDC_RADIOFG, IDC_RADIOBG, IDC_RADIOFG); + SendMessage(hDlg, wm_setRgbString, 0, newFg); + SetFocus(GetDlgItem(hDlg, IDC_DONE)); + break; + + case WM_CTLCOLORSTATIC: + if ((HWND)lParam == GetDlgItem(hDlg,IDC_PREVIEW)) + { + SetBkColor((HDC)wParam, newBg); + SetTextColor((HDC)wParam, newFg); + hBack = CreateSolidBrush(newBg); + return (BOOL)hBack; + } + break; + + case WM_COMMAND: + if (wParam == IDC_DONE) + { + BsodFg = newFg; + BsodBg = newBg; + PostMessage(hDlg, WM_COMMAND, IDABORT, 1); + return FALSE; + } + break; + + default: + if (uiMsg == wm_colorOkString) + { + CHOOSECOLOR* choose = (CHOOSECOLOR*)lParam; + if (IsDlgButtonChecked(hDlg, IDC_RADIOBG)) + { + newBg = choose->rgbResult; + InvalidateRect(GetDlgItem(hDlg,IDC_PREVIEW), NULL, TRUE); + //SendMessage( hDlg, wm_setRgbString, 0, newFg ); + return TRUE; + } + else + { + newFg = choose->rgbResult; + InvalidateRect(GetDlgItem(hDlg,IDC_PREVIEW), NULL, TRUE); + //SendMessage( hDlg, wm_setRgbString, 0, newBg ); + return TRUE; + } + } + break; + } + return 0; +} + + +//---------------------------------------------------------------------- +// +// StartMyFaultDriver +// +// Loads and starts the driver. +// +//---------------------------------------------------------------------- +LONG StartMyFaultDriver(HWND hDlg) +{ + char driverPath[MAX_PATH]; + char systemRoot[MAX_PATH]; + char path[MAX_PATH]; + WIN32_FIND_DATA findData; + HANDLE findHandle; + char* file; + DWORD error; + char msgbuf[MAX_PATH * 2]; + + // + // Load the myfault driver + // + GetCurrentDirectory(sizeof path, path); + sprintf(path + lstrlen(path), "\\%s", SYS_FILE); + + findHandle = FindFirstFile(path, &findData); + if (findHandle == INVALID_HANDLE_VALUE) + { + if (!SearchPath(NULL, SYS_FILE, NULL, sizeof(path), path, &file)) + { + sprintf(msgbuf, "%s was not found.", SYS_FILE); + return Abort(hDlg, msgbuf, GetLastError()); + } + } + else FindClose(findHandle); + + if (!GetEnvironmentVariable("SYSTEMROOT", systemRoot, sizeof(systemRoot))) + { + strcpy(msgbuf, "Could not resolve SYSTEMROOT environment variable"); + return Abort(hDlg, msgbuf, GetLastError()); + } + sprintf(driverPath, "%s\\system32\\drivers\\myfault.sys", systemRoot); + SetFileAttributes(driverPath, FILE_ATTRIBUTE_NORMAL); + CopyFile(path, driverPath, FALSE); + if (!LoadDeviceDriver(SYS_NAME, driverPath, &SysHandle, &error)) + { + if (!CopyFile(path, driverPath, FALSE)) + { + sprintf(msgbuf, "Unable to copy %s to %s\n\n" + "Make sure that %s is in the current directory.", + SYS_NAME, driverPath, SYS_FILE); + return Abort(hDlg, msgbuf, GetLastError()); + } + SetFileAttributes(driverPath, FILE_ATTRIBUTE_NORMAL); + if (!LoadDeviceDriver(SYS_NAME, driverPath, &SysHandle, &error)) + { + UnloadDeviceDriver(SYS_NAME); + if (!LoadDeviceDriver(SYS_NAME, driverPath, &SysHandle, &error)) + { + sprintf(msgbuf, "Error loading %s:", path); + DeleteFile(driverPath); + return Abort(hDlg, msgbuf, error); + } + } + } + return TRUE; +} + +//---------------------------------------------------------------------- +// +// IoctlThreadProc +// +//---------------------------------------------------------------------- +void IoctlThreadProc(PVOID Context) +{ + DWORD nb; + DeviceIoControl(SysHandle, (DWORD)Context, NULL, 0, NULL, 0, &nb, NULL); +} + + +//--------------------------------------------------------------------- +// +// LeakPool +// +//--------------------------------------------------------------------- +void LeakPool(UINT PoolType, DWORD allocSize) +{ + DWORD maxAlloc, bytesAllocated, nb; + DWORD tickCount = GetTickCount(); + + maxAlloc = allocSize; + bytesAllocated = 0; + while (bytesAllocated < maxAlloc && tickCount - GetTickCount() < 1000) + { + if (!DeviceIoControl(SysHandle, + PoolType ? IOCTL_LEAK_NONPAGED : IOCTL_LEAK_PAGED, &allocSize, sizeof(allocSize), + NULL, 0, &nb, NULL)) + { + // can't even allocate 1 byte + if (allocSize == 1) break; + + allocSize /= 2; + if (allocSize == 0) allocSize = 1; + } + else + { + bytesAllocated += allocSize; + } + } + + // one more try going from 2 to 8192 + if (bytesAllocated < maxAlloc) + { + allocSize = 8192; + while (allocSize > 1 && bytesAllocated < maxAlloc + && tickCount - GetTickCount() < 1000) + { + while (DeviceIoControl(SysHandle, + PoolType ? IOCTL_LEAK_NONPAGED : IOCTL_LEAK_PAGED, &allocSize, sizeof(allocSize), + NULL, 0, &nb, NULL) && bytesAllocated < maxAlloc) + { + bytesAllocated += allocSize; + } + allocSize /= 2; + } + } +} + + +//---------------------------------------------------------------------- +// +// MainDialog +// +// This is the main window. +// +//---------------------------------------------------------------------- +LRESULT APIENTRY MainDialog(HWND hDlg, UINT message, UINT wParam, + LONG lParam) +{ + char label[MAX_PATH]; + SYSTEM_INFO sysInfo; + DWORD i, nb, ioctl; + DWORD allocSize, maxAlloc; + static BOOLEAN leakPaged = FALSE; + static BOOLEAN leakNonpaged = FALSE; + CHOOSECOLOR colorArgs; + static DWORD rgbCurrent; + static COLORREF acrCustClr[16]; + + switch (message) + { + case WM_INITDIALOG: + + // + // Start driver + // + if (!StartMyFaultDriver(hDlg)) + { + return FALSE; + } + + // + // We can delete the driver and its Registry key now that its loaded + // + CheckDlgButton(hDlg, IDC_IRQL, BST_CHECKED); + CenterWindow(hDlg); + SetDlgItemText(hDlg, IDC_LEAKMB, "1000"); + break; + + case WM_TIMER: + + GetDlgItemText(hDlg, IDC_LEAKMB, label, _countof(label)); + allocSize = maxAlloc = (atoi(label) * 1024); + LeakPool(wParam, allocSize); + break; + + case WM_COMMAND: + switch (LOWORD(wParam)) + { + case IDOK: + + if (IsDlgButtonChecked(hDlg, IDC_BUFFEROVERFLOW) == BST_CHECKED) + { + ioctl = IOCTL_BUFFER_OVERFLOW; + } + else if (IsDlgButtonChecked(hDlg, IDC_WILDPOINTER) == BST_CHECKED) + { + ioctl = IOCTL_WILD_POINTER; + } + else if (IsDlgButtonChecked(hDlg, IDC_DEADLOCK) == BST_CHECKED) + { + ioctl = IOCTL_DEADLOCK; + } + else if (IsDlgButtonChecked(hDlg, IDC_HANG) == BST_CHECKED) + { + ioctl = IOCTL_HANG; + } + else if (IsDlgButtonChecked(hDlg, IDC_STACKTRASH) == BST_CHECKED) + { + ioctl = IOCTL_TRASH_STACK; + } + else if (IsDlgButtonChecked(hDlg, IDC_PAGEFAULT) == BST_CHECKED) + { + ioctl = IOCTL_PAGE_FAULT; + } + else if (IsDlgButtonChecked(hDlg, IDC_IRQL) == BST_CHECKED) + { + ioctl = IOCTL_IRQL; + } + else if (IsDlgButtonChecked(hDlg, IDC_HANGIRP) == BST_CHECKED) + { + _beginthread(IoctlThreadProc, 0, (PVOID)IOCTL_HANG_IRP); + break; + } + + // + // Execute hang and deadlock on each CPU + // + if (ioctl == IOCTL_HANG || ioctl == IOCTL_DEADLOCK) + { + GetSystemInfo(&sysInfo); + for (i = 0; i < sysInfo.dwNumberOfProcessors; i++) + { + DeviceIoControl(SysHandle, ioctl, NULL, 0, NULL, 0, &nb, NULL); + } + } + else + { + DeviceIoControl(SysHandle, ioctl, NULL, 0, NULL, 0, &nb, NULL); + } + break; + + case IDC_LEAK_PAGE: + + if (leakPaged) + { + KillTimer(hDlg, 0); + SetDlgItemText(hDlg, IDC_LEAK_PAGE, "Leak &Paged"); + } + else + { + SetTimer(hDlg, 0, 1000, NULL); + SetDlgItemText(hDlg, IDC_LEAK_PAGE, "Stop &Paged"); + } + leakPaged = !leakPaged; + break; + + case IDC_LEAK_NONPAGE: + + if (leakNonpaged) + { + KillTimer(hDlg, 1); + SetDlgItemText(hDlg, IDC_LEAK_NONPAGE, "Leak &Nonpaged"); + } + else + { + SetTimer(hDlg, 1, 1000, NULL); + SetDlgItemText(hDlg, IDC_LEAK_NONPAGE, "Stop &Nonpaged"); + } + leakNonpaged = !leakNonpaged; + break; + + case IDCOLOR: + { + COLORREF CustomColors[16]; + int i; + for (i = 0; i < 16; i++) + { + CustomColors[i] = RGB(255, 255, 255); + } + colorArgs.lStructSize = sizeof colorArgs; + colorArgs.Flags = CC_RGBINIT | CC_ENABLEHOOK | CC_ENABLETEMPLATE | CC_FULLOPEN; + colorArgs.hwndOwner = hDlg; + colorArgs.hInstance = (HWND)GetModuleHandle(NULL); + colorArgs.rgbResult = RGB(0, 0, 0); + colorArgs.lpCustColors = CustomColors; + colorArgs.lCustData = 0; + colorArgs.rgbResult = BsodFg; + colorArgs.lpTemplateName = "BSODCOLORS"; + colorArgs.lpfnHook = BsodColorsCallback; + if (ChooseColor(&colorArgs) == TRUE) + { + LARGE_INTEGER Color; + Color.LowPart = RGB(GetRValue(BsodBg)/4, + GetGValue(BsodBg)/4, + GetBValue(BsodBg)/4); + Color.HighPart = RGB(GetRValue(BsodFg)/4, + GetGValue(BsodFg)/4, + GetBValue(BsodFg)/4); + DeviceIoControl(SysHandle, IOCTL_BSOD_COLOR, &Color, sizeof(LARGE_INTEGER), NULL, 0, &nb, NULL); + } + } + break; + + case IDCANCEL: + + // + // Cancel + // + EndDialog(hDlg, 0); + PostQuitMessage(0); + break ; + } + break; + + case WM_CLOSE: + EndDialog(hDlg, 0); + PostQuitMessage(0); + break; + } + return DefWindowProc(hDlg, message, wParam, lParam); +} + + +//---------------------------------------------------------------------- +// +// WinMain +// +// Initialize a dialog window class and pop the autologon dialog. +// +//---------------------------------------------------------------------- +int WINAPI WinMain(HINSTANCE hInstance, + HINSTANCE hPrevInstance, + LPSTR lpCmdLine, + int nCmdShow) +{ + static TCHAR szAppName[] = TEXT("NOTMYFAULT"); + MSG msg; + HWND hMainDlg; + WNDCLASSEX wndclass; + PWSTR* cmdLine; + int numArgs, i; + DWORD nb; + + cmdLine = CommandLineToArgvW(GetCommandLineW(), &numArgs); + for (i = 0; i < numArgs; i++) + { + if (cmdLine[i][0] == '/' || + cmdLine[i][0] == '-') + { + if (!_wcsicmp(&cmdLine[i][1], L"crash")) + { + if (StartMyFaultDriver(NULL)) + { + DeviceIoControl(SysHandle, IOCTL_IRQL, NULL, 0, NULL, 0, &nb, NULL); + } + } + else + { + MessageBox(NULL, "Usage: notmyfault [/crash]\n" + "/crash Crashes the system.", "NotMyFault", MB_ICONERROR); + return -1; + } + } + } + + // + // Create the main window class + // + wndclass.cbSize = sizeof(WNDCLASSEX); + wndclass.style = CS_HREDRAW | CS_VREDRAW; + wndclass.lpfnWndProc = (WNDPROC)MainDialog; + wndclass.cbClsExtra = 0; + wndclass.cbWndExtra = DLGWINDOWEXTRA; + wndclass.hInstance = hInstance; + wndclass.hIcon = LoadIcon(hInstance, "APPICON"); + wndclass.hIconSm = LoadIcon(hInstance, "APPICON"); + wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); + wndclass.hbrBackground = (HBRUSH)(COLOR_BTNFACE + 1); + wndclass.lpszMenuName = NULL; + wndclass.lpszClassName = szAppName; + RegisterClassEx(&wndclass); + + // + // Create the dialog + // + hMainDlg = CreateDialog(hInstance, "NOTMYFAULT", NULL, (DLGPROC)MainDialog); + ShowWindow(hMainDlg, nCmdShow); + + while (GetMessage(&msg, NULL, 0, 0)) + { + if (!IsDialogMessage(hMainDlg, &msg)) + { + TranslateMessage(&msg); + DispatchMessage(&msg); + } + } + return (int)msg.wParam; +} diff --git a/NotMyFault/exe/notmyfault.h b/NotMyFault/exe/notmyfault.h new file mode 100644 index 0000000..739132a --- /dev/null +++ b/NotMyFault/exe/notmyfault.h @@ -0,0 +1,23 @@ +//====================================================================== +// +// NotMyFault.h +// +// Copyright (C) 2002 Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// Simple interface to myfault device driver. +// +//====================================================================== + + +#define SYS_FILE "MYFAULT.SYS" +#define SYS_NAME "MYFAULT" + +#define MYFAULT_DRIVER_KEY "System\\CurrentControlSet\\Services\\Myfault" + +extern HANDLE SysHandle; + + +BOOL LoadDeviceDriver(const char* Name, const char* Path, + HANDLE* lphDevice, PDWORD Error); +BOOL UnloadDeviceDriver(const char* Name); diff --git a/NotMyFault/exe/notmyfault.rc b/NotMyFault/exe/notmyfault.rc new file mode 100644 index 0000000..d678a6d --- /dev/null +++ b/NotMyFault/exe/notmyfault.rc @@ -0,0 +1,203 @@ +// Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#define APSTUDIO_HIDDEN_SYMBOLS +#include "windows.h" +#undef APSTUDIO_HIDDEN_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +///////////////////////////////////////////////////////////////////////////// +// English (U.S.) resources + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +#ifdef _WIN32 +LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) +#endif //_WIN32 + +///////////////////////////////////////////////////////////////////////////// +// +// Dialog +// + +NOTMYFAULT DIALOGEX 0, 0, 162, 260 +STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Not My Fault" +CLASS "NotMyFault" +FONT 8, "MS Sans Serif", 0, 0, 0x0 +BEGIN + CONTROL "High &IRQL fault (kernelmode)",IDC_IRQL,"Button",BS_AUTORADIOBUTTON | WS_GROUP,27,46,107,10 + CONTROL "&Buffer Overflow",IDC_BUFFEROVERFLOW,"Button",BS_AUTORADIOBUTTON,27,61,65,10 + CONTROL "&Code overwrite",IDC_WILDPOINTER,"Button",BS_AUTORADIOBUTTON,27,76,63,10 + CONTROL "&Stack trash",IDC_STACKTRASH,"Button",BS_AUTORADIOBUTTON,27,91,52,10 + CONTROL "&High IRQL fault (usermode)",IDC_PAGEFAULT,"Button",BS_AUTORADIOBUTTON,27,106,101,10 + CONTROL "H&ang IRP",IDC_HANGIRP,"Button",BS_AUTORADIOBUTTON,27,120,47,10 + CONTROL "&Deadlock",IDC_DEADLOCK,"Button",BS_AUTORADIOBUTTON,27,136,47,10 + CONTROL "Han&g",IDC_HANG,"Button",BS_AUTORADIOBUTTON,27,151,33,10 + DEFPUSHBUTTON "&Do Bug",IDOK,25,163,55,14 + PUSHBUTTON "Leak &Paged",IDC_LEAK_PAGE,14,196,63,14 + PUSHBUTTON "Leak &Nonpaged",IDC_LEAK_NONPAGE,82,196,63,14 + EDITTEXT IDC_LEAKMB,64,214,33,14,ES_AUTOHSCROLL | ES_NUMBER,WS_EX_RIGHT + PUSHBUTTON "E&xit",IDCANCEL,105,239,50,14 + LTEXT "Pick your poison:",IDC_STATIC,7,34,55,8 + LTEXT "NotMyFault\nDriver crash test program\nBy Mark Russinovich © 2002-2009",IDC_STATIC,5,5,119,25 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,7,182,148,2 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,7,234,148,2 + LTEXT " Leak Pool (leak freed on exit):",IDC_STATIC,7,186,97,8 + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDFRAME,7,31,148,2 + LTEXT "Leak/second:",IDC_STATIC,16,217,46,8 + LTEXT "KB",IDC_STATIC,99,218,10,8 + DEFPUSHBUTTON "&BSOD Colors",IDCOLOR,85,163,55,14 +END + +BSODCOLORS DIALOGEX 50, 50, 298, 162 +STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CONTEXTHELP | WS_POPUP | WS_CAPTION | WS_SYSMENU +CAPTION "Choose BSOD Colors" +FONT 8, "MS Shell Dlg", 0, 0, 0x1 +BEGIN + CONTROL "&FG",IDC_RADIOFG,"Button",BS_AUTORADIOBUTTON,80,103,25,10 + CONTROL "&BG",IDC_RADIOBG,"Button",BS_AUTORADIOBUTTON,107,103,25,10 + CONTROL "",720,"Static",SS_SIMPLE | WS_TABSTOP,4,14,140,86 + PUSHBUTTON "&Cancel",IDCANCEL,237,140,54,14 + DEFPUSHBUTTON "&OK",IDC_DONE,179,140,54,14 + LTEXT "&Color choices:",IDC_STATIC,4,4,140,9 + CONTROL "",710,"Static",SS_SIMPLE | SS_SUNKEN,152,16,118,39 + CONTROL "",702,"Static",SS_SIMPLE | SS_SUNKEN,280,16,8,39 + CONTROL "",709,"Static",SS_SIMPLE | SS_SUNKEN,151,60,40,26 + RTEXT "Color",730,151,87,20,9 + LTEXT "|S&olid",731,171,87,20,9 + RTEXT "Hu&e:",723,193,62,20,9 + EDITTEXT 703,215,60,18,12,WS_GROUP + RTEXT "&Sat:",724,193,76,20,9 + EDITTEXT 704,215,74,18,12,WS_GROUP + RTEXT "&Lum:",725,193,90,20,9 + EDITTEXT 705,215,88,18,12,WS_GROUP + RTEXT "&Red:",726,243,62,24,9 + EDITTEXT 706,269,60,18,12,WS_GROUP + RTEXT "&Green:",727,243,76,24,9 + EDITTEXT 707,269,74,18,12,WS_GROUP + RTEXT "Bl&ue:",728,243,90,24,9 + EDITTEXT 708,269,88,18,12,WS_GROUP + CTEXT " Preview ",IDC_PREVIEW,10,103,63,25,SS_CENTERIMAGE | SS_SUNKEN + CONTROL "",IDC_STATIC,"Static",SS_ETCHEDHORZ,9,133,284,1 + PUSHBUTTON "&Select",IDOK,79,113,50,14,WS_GROUP +END + + +///////////////////////////////////////////////////////////////////////////// +// +// DESIGNINFO +// + +#ifdef APSTUDIO_INVOKED +GUIDELINES DESIGNINFO +BEGIN + "NOTMYFAULT", DIALOG + BEGIN + LEFTMARGIN, 7 + RIGHTMARGIN, 155 + TOPMARGIN, 7 + BOTTOMMARGIN, 253 + END +END +#endif // APSTUDIO_INVOKED + + +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#define APSTUDIO_HIDDEN_SYMBOLS\r\n" + "#include ""windows.h""\r\n" + "#undef APSTUDIO_HIDDEN_SYMBOLS\r\n" + "\0" +END + +3 TEXTINCLUDE +BEGIN + "\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 3,0,0,0 + PRODUCTVERSION 3,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x40004L + FILETYPE 0x1L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "CompanyName", "Sysinternals - www.sysinternals.com" + VALUE "FileDescription", "Driver bug test program" + VALUE "FileVersion", "3.0" + VALUE "InternalName", "Sysinternals NotMyfault" + VALUE "LegalCopyright", "Copyright © 2004-2009 Mark Russinovich" + VALUE "OriginalFilename", "NotMyfault.exe" + VALUE "ProductName", "Sysinternals Notmyfault" + VALUE "ProductVersion", "3.0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + + +///////////////////////////////////////////////////////////////////////////// +// +// Icon +// + +// Icon with lowest ID value placed first to ensure application icon +// remains consistent on all systems. +APPICON ICON "icon1.ico" +#endif // English (U.S.) resources +///////////////////////////////////////////////////////////////////////////// + + + +#ifndef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 3 resource. +// + + +///////////////////////////////////////////////////////////////////////////// +#endif // not APSTUDIO_INVOKED + diff --git a/NotMyFault/exe/resource.h b/NotMyFault/exe/resource.h new file mode 100644 index 0000000..a1813cb --- /dev/null +++ b/NotMyFault/exe/resource.h @@ -0,0 +1,36 @@ +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by notmyfault.rc +// +#define IDI_ICON1 105 +#define IDC_BUFFEROVERFLOW 1000 +#define IDC_WILDPOINTER 1001 +#define IDC_DEADLOCK 1002 +#define IDC_STACKTRASH 1003 +#define IDC_HANG 1004 +#define IDC_PAGEFAULT 1005 +#define IDC_IRQL 1006 +#define IDC_LEAK 1007 +#define IDC_LEAK_PAGE 1007 +#define IDC_HANGIRP 1008 +#define IDC_LEAK_NONPAGE 1009 +#define IDC_EDIT1 1010 +#define IDC_LEAKMB 1010 +#define IDC_SPIN1 1011 +#define IDCOLOR 1012 +#define IDC_RADIOFG 1013 +#define IDC_RADIOBG 1014 +#define IDC_DONE 1015 +#define IDC_PREVIEW 1016 +#define IDC_STATIC -1 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 106 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1017 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/NotMyFault/sys/MAKEFILE b/NotMyFault/sys/MAKEFILE new file mode 100644 index 0000000..5818975 --- /dev/null +++ b/NotMyFault/sys/MAKEFILE @@ -0,0 +1,7 @@ +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the driver components of the Windows NT DDK +# + +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/NotMyFault/sys/SOURCES b/NotMyFault/sys/SOURCES new file mode 100644 index 0000000..31f51c5 --- /dev/null +++ b/NotMyFault/sys/SOURCES @@ -0,0 +1,5 @@ +TARGETNAME=myfault +TARGETTYPE=DRIVER + +SOURCES=myfault.c myfault.rc + diff --git a/NotMyFault/sys/myfault.c b/NotMyFault/sys/myfault.c new file mode 100644 index 0000000..b009a9b --- /dev/null +++ b/NotMyFault/sys/myfault.c @@ -0,0 +1,682 @@ +//---------------------------------------------------------------------- +// +// Myfault +// +// Copyright (C) 2002 Mark Russinovich +// Sysinternals - www.sysinternals.com +// +// Crash demonstration driver. +// +// * buffer overflow +// * wild pointer +// * paged pool at high irql +// * deadlock +// * trash stack +// * set callback and then unload +// +//---------------------------------------------------------------------- +#include "ntddk.h" +#include "..\exe\ioctlcmd.h" + + +//---------------------------------------------------------------------- +// +// DeadLock +// +// Try to grab a fast mutext when we already own it so that there's a +// deadlock. This can be debugged with CrashOnCtrlScroll and then +// using the ~ debugger command to look at the thread stack on each CPU. +// The XP Verifier's deadlock detection catches this. +// +//---------------------------------------------------------------------- +FAST_MUTEX Fmutex; + +VOID +DeadLock( + VOID + ) +{ + KIRQL prevIrql1, prevIrql2; + + ExInitializeFastMutex( &Fmutex ); + ExAcquireFastMutex( &Fmutex ); + ExAcquireFastMutex( &Fmutex ); +} + + +//---------------------------------------------------------------------- +// +// Hang +// +// This causes the execution of a DPC that stalls the system +// by executing in an infinite loop at raised IRQL. +// +//---------------------------------------------------------------------- +KDPC HangDpc; + +VOID +HangDpcRoutine( + PKDPC Dpc, + PVOID Context, + PVOID SystemArgument1, + PVOID SystemArgument2 + ) +{ + while( 1 ); +} + +VOID +Hang( + VOID + ) +{ + CCHAR i; + +#if AMD64 + for( i = 0; i < KeNumberProcessors; i++ ) { +#else + for( i = 0; i < *KeNumberProcessors; i++ ) { +#endif + + + KeInitializeDpc( &HangDpc, + HangDpcRoutine, + NULL ); + KeSetTargetProcessorDpc(&HangDpc, i ); + KeInsertQueueDpc( &HangDpc, + NULL, NULL ); + } +} + +//---------------------------------------------------------------------- +// +// HangIrp +// +// Never completes the IRP, resulting in an unkillable process. +// +//---------------------------------------------------------------------- +VOID +HangIrp( + VOID + ) +{ + // + // This can't be on the stack because the stack is pageable + // when the thread performs a user-mode wait + // + static KEVENT event; + + KeInitializeEvent( &event, SynchronizationEvent, FALSE ); + KeWaitForSingleObject( &event, UserRequest, UserMode, FALSE, NULL ); +} + + +//---------------------------------------------------------------------- +// +// PageFault +// +// Fault at high IRQL in user-mode. This is virtually impossible to +// debug, but Verifier with IRQL checking on XP catches it. +// +//---------------------------------------------------------------------- +VOID +PageFault( + VOID + ) +{ + KIRQL prevIrql; + + KeRaiseIrql( DISPATCH_LEVEL, &prevIrql ); +} + + +//---------------------------------------------------------------------- +// +// IrqlFault +// +// Fault at high IRQL. !analyze easily figures this one out. +// +//---------------------------------------------------------------------- +VOID +IrqlFault( + VOID + ) +{ + KIRQL prevIrql; + PCHAR memoryPtr; + int i = 0; + volatile int data; + +// +// Allocation size. Thist *must* be less than a page size minus a little +// (for verifier header info) for the Verifier to allocate it from +// special pool. +// +#define ALLOCATION_SIZE 2048 + + + // + // Allocate and then free memory + // + memoryPtr = ExAllocatePool( PagedPool, ALLOCATION_SIZE ); + ExFreePool( memoryPtr ); + + // + // Dereference the freed area at high IRQL and keep going + // on through pool touching at high IRQL. + // + KeRaiseIrql( DISPATCH_LEVEL, &prevIrql ); + while( 1 ) { + + data = *((PULONG) (memoryPtr+i)); + i += 4096; + } + KeLowerIrql( prevIrql ); +} + + + +//---------------------------------------------------------------------- +// +// TrashStack +// +// Just blast through the stack. The pending IRP on the current +// thread in the crash dump hints that this driver might be the cause, +// but otherwise there's no way to verify it. +// +//---------------------------------------------------------------------- +VOID +TrashStack( + VOID + ) +{ + volatile CHAR buffer[256]; + static int i; + + for( i = 0; i < sizeof(buffer)+32; i++ ) { + + buffer[i] = 0x0; + } +} + + + +//---------------------------------------------------------------------- +// +// WildPointer +// +// Overwrite some code. This is very hard to catch without verifier +// because the driver is not active when a crash occurs of +// write-protection is off ( >= 128MB on Win2K, >= 256MB on XP). +// Force write protection on by setting +// HKLM\System\CurrentControlSet\Session Manager\Memory Management\ +// LargePageMinimum to 0xFFFFFFFF. +// +//---------------------------------------------------------------------- +NTSYSAPI +NTSTATUS +NTAPI +NtReadFile( + IN HANDLE FileHandle, + IN HANDLE Event OPTIONAL, + IN PIO_APC_ROUTINE ApcRoutine OPTIONAL, + IN PVOID ApcContext OPTIONAL, + OUT PIO_STATUS_BLOCK IoStatusBlock, + OUT PVOID Buffer, + IN ULONG Length, + IN PLARGE_INTEGER ByteOffset OPTIONAL, + IN PULONG Key OPTIONAL + ); + +VOID +WildPointer( + VOID + ) +{ + *(PCHAR) IoGetCurrentProcess = 0x24; +} + + +//---------------------------------------------------------------------- +// +// BufferOverflow +// +// Write past the end of the buffer. Verifier will catch it, but +// without it the crash is impossible to diagnose. +// +//---------------------------------------------------------------------- +VOID +BufferOverflow( + VOID + ) +{ + PCHAR buffer; + int i; + CHAR overflow[] = "OVERFLOW"; + + // + // Allocate a buffer and zip past the end of it + // + buffer = ExAllocatePool( NonPagedPool, ALLOCATION_SIZE ); + for( i = 0; i < ALLOCATION_SIZE+40; i ++ ) { + + strcpy( &buffer[i], overflow ); + } + + // + // Leak the memory so that if we have to try again we + // get a fresh block of memory to overrun + // + // ExFreePool( buffer ); +} + + + + +//---------------------------------------------------------------------- +// +// PoolLeak +// +// Leak some pool. +// +//---------------------------------------------------------------------- + +ULONG_PTR *PagedLeakedPoolHead = NULL; +ULONG_PTR *NonPagedLeakedPoolHead = NULL; + +PVOID +PoolLeak( + POOL_TYPE PoolType, + ULONG LeakSize + ) +{ + ULONG_PTR *buffer; + ULONG_PTR *next; + + if( LeakSize < sizeof(ULONG_PTR) ) LeakSize = sizeof(ULONG_PTR); + + buffer = (ULONG_PTR *) ExAllocatePoolWithTag( PoolType, LeakSize, 'kaeL' ); + if( buffer ) { + + if( PoolType == PagedPool ) { + + next = PagedLeakedPoolHead; + *buffer = (ULONG_PTR) next; + PagedLeakedPoolHead = buffer; + + } else { + + next = NonPagedLeakedPoolHead; + *buffer = (ULONG_PTR) next; + NonPagedLeakedPoolHead = buffer; + } + } + return buffer; +} + +void +FreePoolLeak( void ) +{ + ULONG_PTR next; + + while( NonPagedLeakedPoolHead ) { + + next = *NonPagedLeakedPoolHead; + ExFreePool( NonPagedLeakedPoolHead ); + NonPagedLeakedPoolHead = (ULONG_PTR *) next; + } + while( PagedLeakedPoolHead ) { + + next = (ULONG_PTR) *PagedLeakedPoolHead; + ExFreePool( PagedLeakedPoolHead ); + PagedLeakedPoolHead = (ULONG_PTR *) next; + } +} + + +//---------------------------------------------------------------------- +// +// MyfaultDeviceControl +// +//---------------------------------------------------------------------- +NTSTATUS +MyfaultDeviceControl( + IN PFILE_OBJECT FileObject, + IN BOOLEAN Wait, + IN PVOID InputBuffer, + IN ULONG InputBufferLength, + OUT PVOID OutputBuffer, + IN ULONG OutputBufferLength, + IN ULONG IoControlCode, + OUT PIO_STATUS_BLOCK IoStatus, + IN PDEVICE_OBJECT DeviceObject + ) +{ + IoStatus->Status = STATUS_SUCCESS; + IoStatus->Information = 0; + switch ( IoControlCode ) { + + case IOCTL_BUFFER_OVERFLOW: + + BufferOverflow(); + break; + + case IOCTL_WILD_POINTER: + + WildPointer(); + break; + + case IOCTL_PAGE_FAULT: + + PageFault(); + break; + + case IOCTL_DEADLOCK: + + DeadLock(); + break; + + case IOCTL_HANG: + + Hang(); + break; + + case IOCTL_TRASH_STACK: + + TrashStack(); + break; + + case IOCTL_IRQL: + + IrqlFault(); + break; + + case IOCTL_LEAK_PAGED: + + if( InputBufferLength != sizeof(ULONG)) { + + IoStatus->Status = STATUS_INVALID_PARAMETER; + break; + } + if( !PoolLeak( PagedPool, *(PULONG) InputBuffer )) { + + IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES; + } + break; + + case IOCTL_LEAK_NONPAGED: + + if( InputBufferLength != sizeof(ULONG)) { + + IoStatus->Status = STATUS_INVALID_PARAMETER; + break; + } + if( !PoolLeak( NonPagedPool, *(PULONG) InputBuffer )) { + + IoStatus->Status = STATUS_INSUFFICIENT_RESOURCES; + } + break; + + default: + + IoStatus->Status = STATUS_NOT_SUPPORTED; + break; + } + return IoStatus->Status; +} + + +//---------------------------------------------------------------------- +// +// MyfaultDispatch +// +// In this routine we Myfault requests to our own device. The only +// requests we care about handling explicitely are IOCTL commands that +// we will get from the GUI. We also expect to get Create and Close +// commands when the GUI opens and closes communications with us. +// +//---------------------------------------------------------------------- +NTSTATUS +MyfaultDispatch( + IN PDEVICE_OBJECT DeviceObject, + IN PIRP Irp + ) +{ + PIO_STACK_LOCATION iosp; + PVOID inputBuffer; + PVOID outputBuffer; + ULONG inputBufferLength; + ULONG outputBufferLength; + ULONG ioControlCode; + NTSTATUS status; + + // + // Switch on the request type + // + iosp = IoGetCurrentIrpStackLocation (Irp); + switch (iosp->MajorFunction) { + + case IRP_MJ_CREATE: + status = STATUS_SUCCESS; + break; + + case IRP_MJ_CLOSE: + status = STATUS_SUCCESS; + FreePoolLeak(); + break; + + case IRP_MJ_DEVICE_CONTROL: + + inputBuffer = Irp->AssociatedIrp.SystemBuffer; + inputBufferLength = iosp->Parameters.DeviceIoControl.InputBufferLength; + outputBuffer = Irp->AssociatedIrp.SystemBuffer; + outputBufferLength = iosp->Parameters.DeviceIoControl.OutputBufferLength; + ioControlCode = iosp->Parameters.DeviceIoControl.IoControlCode; + + // + // Special case: handle the IRP hang so as not to complete the IRP + // + if( ioControlCode == IOCTL_HANG_IRP ) { + + HangIrp(); + return STATUS_PENDING; + + } else { + + status = MyfaultDeviceControl( iosp->FileObject, TRUE, + inputBuffer, inputBufferLength, + outputBuffer, outputBufferLength, + ioControlCode, &Irp->IoStatus, + DeviceObject ); + } + break; + + default: + + status = STATUS_INVALID_DEVICE_REQUEST; + break; + } + + // + // Complete the request + // + Irp->IoStatus.Status = status; + IoCompleteRequest( Irp, IO_NO_INCREMENT ); + return status; +} + + +//---------------------------------------------------------------------- +// +// MyfaultUnload +// +// Our job is done - time to leave. +// +//---------------------------------------------------------------------- +VOID +MyfaultUnload( + IN PDRIVER_OBJECT DriverObject + ) +{ + WCHAR deviceLinkBuffer[] = L"\\DosDevices\\MyFault"; + UNICODE_STRING deviceLinkUnicodeString; + + // + // Delete the symbolic link for our device + // + RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer ); + IoDeleteSymbolicLink( &deviceLinkUnicodeString ); + + // + // Delete the device object + // + IoDeleteDevice( DriverObject->DeviceObject ); +} + + + +//---------------------------------------------------------------------- +// +// Tiner crash +// +// This causes a crash during the boot process, after smss.exe +// has saved a boot log. +// +//---------------------------------------------------------------------- +KDPC TimerDpc; +KTIMER CrashTimer; +VOID +TimerDpcRoutine( + PKDPC Dpc, + PVOID Context, + PVOID SystemArgument1, + PVOID SystemArgument2 + ) +{ + IrqlFault(); +} + + +//---------------------------------------------------------------------- +// +// DriverEntry +// +// Installable driver initialization. Here we just set ourselves up. +// +//---------------------------------------------------------------------- +NTSTATUS +DriverEntry( + IN PDRIVER_OBJECT DriverObject, + IN PUNICODE_STRING RegistryPath + ) +{ + NTSTATUS status; + WCHAR deviceNameBuffer[] = L"\\Device\\Myfault"; + UNICODE_STRING deviceNameUnicodeString; + WCHAR deviceLinkBuffer[] = L"\\DosDevices\\Myfault"; + UNICODE_STRING deviceLinkUnicodeString; + PDEVICE_OBJECT interfaceDevice = NULL; + ULONG startType, demandStart; + RTL_QUERY_REGISTRY_TABLE paramTable[2]; + UNICODE_STRING registryPath; + LARGE_INTEGER crashTime; + + // + // Create a named device object + // + RtlInitUnicodeString (&deviceNameUnicodeString, + deviceNameBuffer ); + status = IoCreateDevice ( DriverObject, + 0, + &deviceNameUnicodeString, + FILE_DEVICE_MYFAULT, + 0, + TRUE, + &interfaceDevice ); + if (NT_SUCCESS(status)) { + + // + // Create a symbolic link that the GUI can specify to gain access + // to this driver/device + // + RtlInitUnicodeString (&deviceLinkUnicodeString, + deviceLinkBuffer ); + status = IoCreateSymbolicLink (&deviceLinkUnicodeString, + &deviceNameUnicodeString ); + + // + // Create dispatch points for all routines that must be Myfaultd + // + DriverObject->MajorFunction[IRP_MJ_CREATE] = + DriverObject->MajorFunction[IRP_MJ_CLOSE] = + DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyfaultDispatch; + DriverObject->DriverUnload = MyfaultUnload; + } + + if (!NT_SUCCESS(status)) { + + // + // Something went wrong, so clean up + // + if( interfaceDevice ) { + + IoDeleteDevice( interfaceDevice ); + } + } + + // + // Query our start type to see if we are supposed to monitor starting + // at boot time + // + registryPath.Buffer = ExAllocatePool( PagedPool, + RegistryPath->Length + sizeof(UNICODE_NULL)); + if(!registryPath.Buffer) { + + return STATUS_INSUFFICIENT_RESOURCES; + } + + registryPath.Length = RegistryPath->Length + sizeof(UNICODE_NULL); + registryPath.MaximumLength = registryPath.Length; + + RtlZeroMemory( registryPath.Buffer, registryPath.Length ); + RtlMoveMemory( registryPath.Buffer, RegistryPath->Buffer, + RegistryPath->Length ); + + demandStart = SERVICE_DEMAND_START; + startType = demandStart; + RtlZeroMemory( ¶mTable[0], sizeof(paramTable)); + paramTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; + paramTable[0].Name = L"Start"; + paramTable[0].EntryContext = &startType; + paramTable[0].DefaultType = REG_DWORD; + paramTable[0].DefaultData = &demandStart; + paramTable[0].DefaultLength = sizeof(ULONG); + + RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE, + registryPath.Buffer, ¶mTable[0], + NULL, NULL ); + + if( startType != SERVICE_DEMAND_START ) { + + // + // Crash here during the boot process + // + KeInitializeDpc( &TimerDpc, + TimerDpcRoutine, + NULL ); + + KeInitializeTimer( &CrashTimer ); + + // + // Give SMSS 5 seconds to start + // + crashTime.QuadPart = 5 * -10000000; + KeSetTimer( &CrashTimer, + crashTime, + &TimerDpc ); + } + return status; +} + + + diff --git a/NotMyFault/sys/myfault.rc b/NotMyFault/sys/myfault.rc new file mode 100644 index 0000000..1f2d00d --- /dev/null +++ b/NotMyFault/sys/myfault.rc @@ -0,0 +1,27 @@ +#include + +#define VER_DEBUG 0 +#define VER_PRERELEASE 0 +#define VER_FILEFLAGSMASK VS_FFI_FILEFLAGSMASK +#define VER_FILEOS VOS_NT_WINDOWS32 +#define VER_FILEFLAGS (VER_PRERELEASE|VER_DEBUG) + +#define VER_FILETYPE VFT_DRV +#define VER_FILESUBTYPE VFT2_DRV_SYSTEM + +#define VER_COMPANYNAME_STR "Sysinternals" +#define VER_PRODUCTNAME_STR "Sysinternals Myfault" +#define VER_LEGALCOPYRIGHT_YEARS "2002-2004" +#define VER_LEGALCOPYRIGHT_STR "Copyright (C) M. Russinovich " VER_LEGALCOPYRIGHT_YEARS +#define VER_LEGALTRADEMARKS_STR "Copyright (C) 2002-2004 Mark Russinovich" + +#define VER_PRODUCTVERSION 2,0,00,00 +#define VER_PRODUCTVERSION_STR "2.0" +#define VER_PRODUCTVERSION_W (0x0200) +#define VER_PRODUCTVERSION_DW (0x0200) +#define VER_FILEDESCRIPTION_STR "Crash Test Driver" +#define VER_INTERNALNAME_STR "myfault.sys" +#define VER_ORIGINALFILENAME_STR "myfault.sys" + +#include "common.ver" +