Solved

Generate a Blue Screen

Posted on 2000-04-20
3
249 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

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Suggested Solutions

This is to be the first in a series of articles demonstrating the development of a complete windows based application using the MFC classes.  I’ll try to keep each article focused on one (or a couple) of the tasks that one may meet.   Introductio…
Introduction: Finishing the grid – keyboard support for arrow keys to manoeuvre, entering the numbers.  The PreTranslateMessage function is to be used to intercept and respond to keyboard events. Continuing from the fourth article about sudoku. …
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.
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

708 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

Need Help in Real-Time?

Connect with top rated Experts

11 Experts available now in Live!

Get 1:1 Help Now