Solved

Generate a Blue Screen

Posted on 2000-04-20
3
277 Views
Last Modified: 2013-11-20
i have a cool application,and like any application i want it to have an easter-agg so it will create a self suicide - blu screen,

can i create a blue screen using user level application by an undocumented function,or i must be at kernel level in order to do it?
0
Comment
Question by:yanissim
  • 2
3 Comments
 
LVL 1

Author Comment

by:yanissim
ID: 2734048
forgot to mention..
i'm using Nt4 or win2k
0
 
LVL 86

Accepted Solution

by:
jkr earned 200 total points
ID: 2734388
You'll have to create a kmode driver in order to be a vle to do this - the BSOD is generated by 'KeBugCheckEx()', and as this function is exported by ntoskrnl.exe, it can't be loaded dynamically (and I also doubt that it'll work).

Surprisingly, creating a driver that generates a blue screen isn't a too difficult task ;-)

#include <ntddk.h>

#define FILE_DEVICE_BSOD     0x00009000
#define IOCTL_BSOD           ( ULONG) CTL_CODE( FILE_DEVICE_BSOD, 0x00, METHOD_NEITHER, FILE_ANY_ACCESS )

PDEVICE_OBJECT  pbsodDevice   =   NULL;

NTSTATUS    bsodDispatchIoctl (   IN  PDEVICE_OBJECT  pDeviceObject,
                                  IN  PIRP            pIrp
                              );
VOID        bsodUnload        (   IN  PDRIVER_OBJECT  DriverObject);

/*
    Intended to be called like this:

    DeviceIoControl     (   hDriver,
                            ( DWORD) IOCTL_BSOD,
                            NULL,
                            sizeof  (   PVOID),
                            NULL,
                            sizeof  (   PVOID),
                            &cbReturned,
                            lpOverlapped
                        );
*/


NTSTATUS    bsodDispatchIoctl (   IN  PDEVICE_OBJECT  pDeviceObject,
                                  IN  PIRP            pIrp
                              )
{

    PIO_STACK_LOCATION  pIos;
    NTSTATUS            ntStatus;

    // Get a pointer to current I/O Stack Location
    pIos    =   IoGetCurrentIrpStackLocation    (   pIrp);

    switch  (   pIos->MajorFunction)
            {
                case    IRP_MJ_CREATE:

                        DbgPrint (  "bsod.SYS: IRP_MJ_CREATE\n");

                        ntStatus    =   STATUS_SUCCESS;

                        break;

                case    IRP_MJ_CLOSE:

                        DbgPrint (  "bsod.SYS: IRP_MJ_CLOSE\n");

                        ntStatus    =   STATUS_SUCCESS;

                        break;

                case    IRP_MJ_DEVICE_CONTROL:

                        DbgPrint (  "bsod.SYS: IRP_MJ_DEVICE_CONTROL\n");

                        // Make sure this is a valid IOCTL for us...
                        if  (       IOCTL_BSOD
                                !=  pIos->Parameters.DeviceIoControl.IoControlCode
                            )
                            {
                                ntStatus    =   STATUS_INVALID_PARAMETER;
                            }
                         else
                            {
                                PLONG    pl = NULL;

                                *pl = 0; // BSOD!!!

                                ntStatus    =   STATUS_SUCCESS; // will never reach this point ;-)
                            }

                        break;

                default:
                        ntStatus    =   STATUS_INVALID_PARAMETER;
                        break;

            }

    pIrp->IoStatus.Status       =   ntStatus;
    pIrp->IoStatus.Information  =   0;

    IoCompleteRequest   (   pIrp,   IO_NO_INCREMENT);

    return  (   ntStatus);

}

NTSTATUS DriverEntry    (   IN  PDRIVER_OBJECT  pDriverObject,
                            IN  PUNICODE_STRING pRegistryPath
                        )
{
    NTSTATUS                ntStatus;
    WCHAR                   deviceNameBuffer[]      = L"\\Device\\bsod";
    UNICODE_STRING          deviceNameUnicodeString;
    WCHAR                   deviceLinkBuffer[]      = L"\\DosDevices\\bsod";
    UNICODE_STRING          deviceLinkUnicodeString;

    DbgPrint (  "bsod.SYS: entering DriverEntry\n");

    // Setup the device name
    RtlInitUnicodeString    (   &deviceNameUnicodeString,
                                deviceNameBuffer
                            );

    // Create the device used for bsod communications
    ntStatus    =   IoCreateDevice  (   pDriverObject,
                                        0,
                                        &deviceNameUnicodeString,
                                        FILE_DEVICE_BSOD,
                                        0,
                                        TRUE,
                                        &pbsodDevice
                                    );

    // If successful, make a symbolic link that allows for the device
    // object's access from Win32 programs
    if  (   NT_SUCCESS  (   ntStatus))
        {
            // Create a symbolic link that the application can specify to gain access
            // to this driver/device
            RtlInitUnicodeString    (   &deviceLinkUnicodeString,
                                        deviceLinkBuffer
                                    );

            ntStatus    =    IoCreateSymbolicLink   (   &deviceLinkUnicodeString,
                                                        &deviceNameUnicodeString
                                                    );
            if  (   !NT_SUCCESS (   ntStatus))
                {

                    DbgPrint (("bsod.SYS: IoCreateSymbolicLink failed\n"));
       
                }

            // Create dispatch points for all routines that must be handled.
            pDriverObject->MajorFunction    [ IRP_MJ_CREATE]            =
            pDriverObject->MajorFunction    [ IRP_MJ_CLOSE]             =
            pDriverObject->MajorFunction    [ IRP_MJ_DEVICE_CONTROL]    =   bsodDispatchIoctl;
            pDriverObject->DriverUnload                                 =   bsodUnload;

        }

    //
    // If something went wrong, cleanup the device object and don't load
    //
    if  (   !NT_SUCCESS (   ntStatus))
        {

            DbgPrint    (   "bsod: Failed to create our device!\n");

            if  (   pbsodDevice)
                {

                    IoDeleteDevice  (   pbsodDevice);
                }

            return  (   ntStatus);
        }

    return  (   ntStatus);
}


VOID bsodUnload   (   IN  PDRIVER_OBJECT  DriverObject)
{
    WCHAR                  deviceLinkBuffer []      =   L"\\DosDevices\\bsod";
    UNICODE_STRING         deviceLinkUnicodeString;

    // Delete the symbolic link for our bsod device
    RtlInitUnicodeString    (   &deviceLinkUnicodeString,   deviceLinkBuffer);
    IoDeleteSymbolicLink    (   &deviceLinkUnicodeString);

    DbgPrint    ("bsod.SYS: unloading\n");

    // Delete the device object, making sure that the bsod device
    // object is always deleted.
    if  (   pbsodDevice   ==  DriverObject->DeviceObject)  
        {

            IoDeleteDevice  (   DriverObject->DeviceObject);

        }
     else
        {
            IoDeleteDevice  (   DriverObject->DeviceObject);
            IoDeleteDevice  (   pbsodDevice);
        }

    DbgPrint    (   "bsod.SYS: deleted devices\n");

    DbgPrint    (   "bsod.SYS: freed memory\n");
}

To build the above example, go to 'http://www.microsoft.com/hwdev/ddk/' and download the DDK.
0
 
LVL 86

Expert Comment

by:jkr
ID: 2734394
Oh, yes, and that's how to actually call the driver:

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

#include <devioctl.h>

#define FILE_DEVICE_BSOD     0x00009000
#define IOCTL_BSOD           ( ULONG) CTL_CODE( FILE_DEVICE_BSOD, 0x00, METHOD_NEITHER, FILE_ANY_ACCESS )


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) )
        {
            printf  (   "ERROR opening '%s', reason == %d\n", completeDeviceName,   GetLastError());
            return FALSE;
        }

    // If user wants handle, give it to them.  Otherwise, just close it.
    if ( lphDevice )
        *lphDevice = hDevice;
    else
        CloseHandle( hDevice );

    return TRUE;
}

int main    (   int     argc,
                char**  argv
            )
{
    HANDLE  hDriver;
    DWORD   cbReturned;

    if  (   !OpenDevice (   "bsod",   &hDriver))
        {
            printf  (   "FAILED to open device!\n");
            return  (   -1);
        }

    // generate BSOD
    DeviceIoControl     (   hDriver,
                            ( DWORD) IOCTL_BSOD,
                            ( LPVOID) NULL,
                            sizeof  (   PVOID),
                            NULL,
                            sizeof  (   PVOID),
                            &cbReturned,
                            NULL
                        );


    return  (   0);
}
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In this article, I'll describe -- and show pictures of -- some of the significant additions that have been made available to programmers in the MFC Feature Pack for Visual C++ 2008.  These same feature are in the MFC libraries that come with Visual …
Introduction: Dialogs (2) modeless dialog and a worker thread.  Handling data shared between threads.  Recursive functions. Continuing from the tenth article about sudoku.   Last article we worked with a modal dialog to help maintain informat…
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
With Secure Portal Encryption, the recipient is sent a link to their email address directing them to the email laundry delivery page. From there, the recipient will be required to enter a user name and password to enter the page. Once the recipient …

821 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question