이 프로그램은 제가 작성한 블루스크린을 띄우는 프로그램의 소스코드입니다.
실행 후, 아무 키나 누르면 다시 원상태로 되돌아옵니다.
#include <stdio.h>
#include <windows.h>
#include <wingdi.h>
#include <ddraw.h>
#define LINE(x) (int)(14*(float)x)
BOOL IsDisplayed;
DWORD dwDelayTickCount;
char BChkText[64];
PVOID BChkCode;
PVOID BChkArg1;
PVOID BChkArg2;
PVOID BChkArg3;
PVOID BChkArg4;
char Driver[20];
PVOID RefAddress;
PVOID Base;
PVOID Date;
BOOL PrintVideoText(HWND hWnd, int x, int y, COLORREF BkColor, COLORREF TextColor, LPSTR FormatString, ...)
{
LPSTR Text=(LPSTR)malloc(strlen(FormatString)*8);
BOOL bStatus=FALSE;
va_list args;
HDC hDc;
PAINTSTRUCT PaintStruct;
hDc=BeginPaint(hWnd, &PaintStruct);
SetBkColor(hDc, BkColor);
SetTextColor(hDc, TextColor);
va_start(args, FormatString);
vsprintf(Text, FormatString, args);
va_end(args);
bStatus=TextOut(hDc, x, y, Text, strlen(Text));
free((void *)Text);
EndPaint(hWnd, &PaintStruct);
ReleaseDC(hWnd, hDc);
return bStatus;
}
void InitVideo(int x, int y)
{
DEVMODE DevMode;
ZeroMemory(&DevMode, sizeof(DevMode));
DevMode.dmSize=sizeof(DevMode);
DevMode.dmFields=DM_PELSWIDTH | DM_PELSHEIGHT;
DevMode.dmPelsWidth=x;
DevMode.dmPelsHeight=y;
DevMode.dmColor=0;
ChangeDisplaySettings(&DevMode, CDS_VIDEOPARAMETERS);
ShowCursor(FALSE);
}
void UnInitVideo()
{
DEVMODE DevMode;
DevMode.dmSize=sizeof(DevMode);
DevMode.dmFields=DM_PELSWIDTH | DM_PELSHEIGHT;
DevMode.dmPelsWidth=1024;
DevMode.dmPelsHeight=768;
DevMode.dmColor=1;
ChangeDisplaySettings(&DevMode, 1);
ShowCursor(TRUE);
}
BOOL TextOutEx(HDC hDc, int x, int y, LPSTR FormatString, ...)
{
LPSTR Text=(LPSTR)malloc(strlen(FormatString)*8);
BOOL bStatus=FALSE;
va_list args;
va_start(args, FormatString);
vsprintf(Text, FormatString, args);
va_end(args);
bStatus=TextOut(hDc, x, y, Text, strlen(Text));
free((void *)Text);
return bStatus;
}
VOID DisplayBlueScreen(
HWND hWnd,
BOOL bKernelDumpPhysicalMemory,
LPSTR BugCheckMessageText,
PVOID KeBugCheckCode,
PVOID BugCheckArgument1,
PVOID BugCheckArgument2,
PVOID BugCheckArgument3,
PVOID BugCheckArgument4,
LPSTR DriverName,
PVOID ReferencedAddress,
PVOID BaseAddress,
PVOID DateStamp)
{
HDC hDc;
LOGFONT LogFont={NULL, };
PAINTSTRUCT PaintStruct;
HGDIOBJ FontObj, PrevFontObj;
int y=0, DriverNameLength=0;
if(DriverName) DriverNameLength=strlen(DriverName);
hDc=BeginPaint(hWnd, &PaintStruct);
/*RED=RGB(193, 54, 45)*/
/*BLUE=RGB(0, 0, 132)*/
SetBkColor(hDc, RGB(0, 0, 132));
SetTextColor(hDc, RGB(255, 255, 255));
LogFont.lfHeight=13;
strcpy(LogFont.lfFaceName, TEXT("Lucida Console"));
FontObj=(HGDIOBJ)CreateFontIndirect(&LogFont);
PrevFontObj=SelectObject(hDc, FontObj);
TextOutEx(hDc, 0, LINE(1), "A problem has been detected and Windows has been shut down to prevent damage");
TextOutEx(hDc, 0, LINE(2), "to your computer.");
if(DriverNameLength)
{
TextOutEx(hDc, 0, LINE(4), "The problem seems to be caused by the following file: %s", DriverName);
}
TextOutEx(hDc, 0, DriverNameLength ? LINE(6) : LINE(4), BugCheckMessageText);
TextOutEx(hDc, 0, DriverNameLength ? LINE(8) : LINE(6), "If this is the first time you've seen this error screen,");
TextOutEx(hDc, 0, DriverNameLength ? LINE(9) : LINE(7), "restart your computer. If this screen appears again, follow ");
TextOutEx(hDc, 0, DriverNameLength ? LINE(10) : LINE(8), "these steps:");
TextOutEx(hDc, 0, DriverNameLength ? LINE(12) : LINE(10), "Check to make sure any new hardware or software is properly installed.");
TextOutEx(hDc, 0, DriverNameLength ? LINE(13) : LINE(11), "If this is a new installation, ask your hardware or software manufacturer");
TextOutEx(hDc, 0, DriverNameLength ? LINE(14) : LINE(12), "for any windows updates you might need.");
TextOutEx(hDc, 0, DriverNameLength ? LINE(16) : LINE(14), "If problems continue, disable or remove any newly installed hardware");
TextOutEx(hDc, 0, DriverNameLength ? LINE(17) : LINE(15), "or software. Disable BIOS memory options such as caching or shadowing.");
TextOutEx(hDc, 0, DriverNameLength ? LINE(18) : LINE(16), "If you need to use Safe Mode to remove or disable components, restart");
TextOutEx(hDc, 0, DriverNameLength ? LINE(19) : LINE(17), "your computer, press F8 to select Advanced Startup Options, and then");
TextOutEx(hDc, 0, DriverNameLength ? LINE(20) : LINE(18), "select Safe Mode.");
TextOutEx(hDc, 0, DriverNameLength ? LINE(22) : LINE(20), "Technical information:");
TextOutEx(hDc, 0, DriverNameLength ? LINE(24) : LINE(22), "*** STOP: 0x%p (0x%p, 0x%p, 0x%p, 0x%p)", KeBugCheckCode, BugCheckArgument1, BugCheckArgument2, BugCheckArgument3, BugCheckArgument4);
if(DriverNameLength)
{
TextOutEx(hDc, 0, LINE(26), "*** %s - Address %p base at %p, Datestamp %p", DriverName, ReferencedAddress, BaseAddress, DateStamp);
}
if(KeBugCheckCode==(PVOID)0x50 || KeBugCheckCode==(PVOID)0x1E || KeBugCheckCode==(PVOID)0x24 ||
KeBugCheckCode==(PVOID)0x58 || KeBugCheckCode==(PVOID)0x79)
{
//DO NOTHING
}
else
{
TextOutEx(hDc, 0, DriverNameLength ? LINE(28) : LINE(24), "Beginning dump of physical memory");
if(bKernelDumpPhysicalMemory && (strncmp(BugCheckMessageText, "DRIVER_IRQL_NOT_LESS_OR_EQUAL", 29)==0 ||
strncmp(BugCheckMessageText, "IRQL_NOT_LESS_OR_EQUAL", 22)==0))
{
int DumpProgress=1;
TextOutEx(hDc, 0, DriverNameLength ? LINE(29) : LINE(25), "Dumping physical memory to disk: ");
while(DumpProgress<=1000)
{
TextOutEx(hDc, 275, DriverName ? LINE(29) : LINE(25), "%.2d", DumpProgress/10);
Sleep(10);
DumpProgress+=1;
}
}
TextOutEx(hDc, 0, DriverNameLength ? LINE(29) : LINE(25), "Physical memory dump complete. ");
TextOutEx(hDc, 0, DriverNameLength ? LINE(30) : LINE(26), "Contact your system administrator or technical support group for further");
TextOutEx(hDc, 0, DriverNameLength ? LINE(31) : LINE(27), "assistance.");
}
DeleteObject(FontObj);
SelectObject(hDc, PrevFontObj);
EndPaint(hWnd, &PaintStruct);
}
int randEx()
{
srand(GetTickCount() >> 4);
return rand();
}
VOID RandomBugCheckParameter(
OUT PCHAR BugCheckMessageText,
OUT PVOID *KeBugCheckCode,
OUT PVOID *BugCheckArgument1,
OUT PVOID *BugCheckArgument2,
OUT PVOID *BugCheckArgument3,
OUT PVOID *BugCheckArgument4,
OUT LPSTR DriverName,
OUT PVOID *ReferencedAddress,
OUT PVOID *BaseAddress,
OUT PVOID *DateStamp)
{
int BugCheckCodes[18]={0x0A, 0x1E, 0x24, 0x35, 0x3F, 0x50, 0x58, 0x76,
0x79, 0x7F, 0xC5, 0xCE, 0xCF, 0xD0, 0xD1, 0xD4, 0xDE, 0xE2};
char *BugCheckMessages[18]={"IRQL_NOT_LESS_OR_EQUAL", "KMODE_EXCEPTION_NOT_HANDLED",
"NTFS_FILE_SYSTEM", "NO_MORE_IRP_STACK_LOCATIONS", "NO_MORE_SYSTEM_PTES",
"PAGE_FAULT_IN_NONPAGED_AREA", "FTDISK_INTERNAL_ERROR", "PROCESS_HAS_LOCKED_PAGES",
"MISMATCHED_HAL", "UNEXPECTED_KERNEL_MODE_TRAP", "DRIVER_CORRUPTED_EXPOOL",
"DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS",
"TERMINAL_SERVER_DRIVER_MADE_INCORRECT_MEMORY_REFERENCE",
"DRIVER_CORRUPTED_MMPOOL", "DRIVER_IRQL_NOT_LESS_OR_EQUAL",
"SYSTEM_SCAN_AT_RAISED_IRQL_CAUGHT_IMPROPER_DRIVER_UNLOAD",
"POOL_CORRUPTION_IN_FILE_AREA", "MANUALLY_INITIATED_CRASH"};
char *Drivers[25]={"Ndis.sys", "ipsec.sys", "Null.sys", "tcpip.sys",
"wanarp.sys", "RSPSC.sys", "cdrom.sys", "ntoskrnl.exe", "ipfltdrv.sys",
"acpi.sys", "netbios.sys", "atapi.sys", "USBSTOR.SYS", "vga.sys",
"nv4.sys", "cdfs.sys", "isapnp.sys", "i8042prt.sys", "serial.sys",
"modem.sys", "DISK.sys", "wstcodec.sys", "dxapi.sys", "ntoskrnl.exe",
"win32k.sys"};
ULONG BugCheckParameters[18][4]={
{0xEA00ACFDL+randEx(), randEx()%2 ? 0xFF : 0x01, randEx()%2, 0xEA00ACFDL-randEx()},
{randEx()%2 ? 0xC0000005 : 0x00000001, 0x80400000+randEx()*randEx(), 0x7FFFD174+randEx(), randEx()},
{randEx()%1024, 0, 0xEBB0A538+randEx(), 0},
{0xECAFEDFB+randEx(), 0, 0, 0},
{0, 0, 0, 0},
{0x80040000+randEx(), randEx()%2, 0x80000000+randEx()*randEx(), 0},
{0, 0, 0, 0},
{0, randEx()*randEx()*randEx(), randEx(), 0},
{randEx()%3, randEx()%3, randEx()%3, 0},
{0, 0, 0, 0},
{0x80040000+randEx(), randEx()%2 ? 0xFF : 0x01, randEx()%2, 0x80000000+randEx()*randEx()},
{0xEBACDAFE+randEx(), randEx()%2, 0xED000000+randEx()*randEx()*randEx(), 0},
{0xEEADC013+randEx(), randEx()%2, 0xEF2DAA34+randEx()*randEx()-randEx(), 0},
{0xE0000000+randEx()*randEx()+randEx(), randEx()%2 ? 0xFF : 0x01, randEx()%2, 0xEABCDEFA+randEx()},
{0xDECABDDF+randEx()*2, randEx()%2 ? 0xFF : 0x01, randEx()%2, 0xDABCDEFA+randEx()},
{0xDADECAFF+randEx()*randEx()+randEx(), randEx()%2 ? 0xFF : 0x01, randEx()%2, 0xDDDCDEFA+randEx()},
{0, 0, 0, 0},
{0, 0, 0, 0}
};
BOOL HasDriver[18]={1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0};
ULONG ReferencedAddressList[18]={BugCheckParameters[0][3], BugCheckParameters[1][2],
0, 0, 0, BugCheckParameters[5][2], 0, 0, 0, 0, BugCheckParameters[10][3],
BugCheckParameters[11][2], BugCheckParameters[12][2], BugCheckParameters[13][3],
BugCheckParameters[14][3], BugCheckParameters[15][3], 0, 0};
int Index=randEx()%18;
memset(BugCheckMessageText, NULL, sizeof(BugCheckMessageText));
memset(DriverName, NULL, sizeof(DriverName));
strcpy(BugCheckMessageText, BugCheckMessages[Index]);
*KeBugCheckCode=(PVOID)BugCheckCodes[Index];
*BugCheckArgument1=(PVOID)BugCheckParameters[Index][0];
*BugCheckArgument2=(PVOID)BugCheckParameters[Index][1];
*BugCheckArgument3=(PVOID)BugCheckParameters[Index][2];
*BugCheckArgument4=(PVOID)BugCheckParameters[Index][3];
if(HasDriver[Index]) strcpy(DriverName, Drivers[randEx()%25]);
*ReferencedAddress=(PVOID)ReferencedAddressList[Index];
*BaseAddress=(PVOID)(ReferencedAddressList[Index]-(randEx()*2)+(randEx()%2));
*DateStamp=(PVOID)(randEx()*randEx()*abs(randEx()-randEx()));
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT iMessage, WPARAM wParam, LPARAM lParam)
{
if(!IsDisplayed && iMessage==WM_PAINT)
{
RandomBugCheckParameter(BChkText, &BChkCode, &BChkArg1, &BChkArg2, &BChkArg3,
&BChkArg4, Driver, &RefAddress, &Base, &Date);
}
switch(iMessage)
{
case WM_PAINT:
DisplayBlueScreen(
hWnd,
IsDisplayed ? FALSE : TRUE,
BChkText,
BChkCode,
BChkArg1,
BChkArg2,
BChkArg3,
BChkArg4,
Driver,
RefAddress,
Base,
Date);
IsDisplayed=TRUE;
break;
case WM_KEYDOWN:
UnInitVideo();
ShowCursor(TRUE);
ExitProcess(0);
break;
}
return DefWindowProc(hWnd, iMessage, wParam, lParam);
}
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdParam, int nCmdShow)
{
HWND hWnd;
MSG Msg;
WNDCLASS WndClass;
InitVideo(640, 480);
WndClass.cbClsExtra=1;
WndClass.cbWndExtra=0;
WndClass.hbrBackground=(HBRUSH)CreateSolidBrush(RGB(0, 0, 132));//GetStockObject(13);
WndClass.hCursor=(HCURSOR)LoadCursor(NULL, IDC_ARROW);
WndClass.hIcon=LoadIcon(NULL, IDI_APPLICATION);
WndClass.hInstance=hInstance;
WndClass.lpfnWndProc=(WNDPROC)WndProc;
WndClass.lpszClassName="DisplayBlueScreenClass32W";
WndClass.lpszMenuName=NULL;
WndClass.style=CS_HREDRAW | CS_VREDRAW;
RegisterClass(&WndClass);
hWnd=CreateWindow("DisplayBlueScreenClass32W", "DisplayBSOD", WS_POPUP, 0, 0, GetSystemMetrics(SM_CXSCREEN), GetSystemMetrics(SM_CYSCREEN),
NULL, (HMENU)NULL, hInstance, NULL);
SetWindowPos(hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
ShowWindow(hWnd, SW_SHOW);
while(GetMessage(&Msg, 0, 0, 0))
{
TranslateMessage(&Msg);
DispatchMessage(&Msg);
}
UnInitVideo();
return Msg.wParam;
}
아래는 실행 결과입니다.
※ 참고 : 이 블루스크린은 실제의 블루스크린(BSOD)와 차이가 날 수 있습니다.