Programming/Win32 API2008. 12. 3. 11:11

이 프로그램은 제가 작성한 블루스크린을 띄우는 프로그램의 소스코드입니다.

실행 후, 아무 키나 누르면 다시 원상태로 되돌아옵니다.


#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)와 차이가 날 수 있습니다.

Posted by skensita