UserModeHardwarePortIO


//  vim:set ts=4 sw=4:

//

//  This program demonstrates how to write directly to hardware ports

//  from user mode.  To do this, the account that this program is

//  running under must have SeTcbPrivilege available, but not

//  necessarily active.  The SYSTEM account has this privilege enabled

//  and active.  Administrators do not normally have this privilege

//  available.  To enable SeTcbPrivilege, use the "Local Computer

//  Policy" in the MMC and grant the "Act as part of the operating

//  system" to your user via:

//

//      Local Computer Policy

//          Computer Configuration

//              Windows Settings

//                  Security Settings

//                      Local Policies

//                          User Rights Management

//

//  You will need to log out and back in again so your login token has

//  this privilege granted (but disabled).  You could also assign

//  this privilege programatically to the account.  A relogin is still

//  required.  This program will then enable SeTcbPrivilege then attempt

//  to change the IOPL of this process to allow direct port access and

//  "effective" kernel mode abilities.

//

//  As a demo, we will write directly to the reset port of the keyboard

//  controller.  The keyboard controller has a direct line to the RESET

//  pin of the CPU and the machine will hard reboot with no questions

//  asked and without OS intervention.

//

//  This is something that is not normally allowed from user mode! ;-)

//

//  To perform the reset, write to port 0x64 with command 0xFE. From

//  kernel mode, we already have access to hardware ports and accomplish

//  the same result via: WRITE_PORT_UCHAR(0x64, 0xFE).

//

//  For a kernel mode driver version of this program, refer to

//  "Reboot.c".

//

//  Michael Wookey / August 2006

//


#define STRICT

#define WIN32_LEAN_AND_MEAN


#include <windows.h>

#include <tchar.h>



BOOL

EnablePrivilege(

    PTCHAR Privilege

    )

{

    BOOL rc = FALSE;

    HANDLE hToken;

    LUID luid;

    TOKEN_PRIVILEGES tokenPrivilege;


    //

    //  Open the current process' token.

    //

    rc = OpenProcessToken(

            GetCurrentProcess(),

            TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,

            &hToken);


    if (rc)

    {

        rc = LookupPrivilegeValue(NULL, Privilege, &luid);


        if (rc)

        {

            tokenPrivilege.PrivilegeCount = 1;

            tokenPrivilege.Privileges[0].Luid = luid;

            tokenPrivilege.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;


            //

            //  Assign the given privilege.

            //

            rc = AdjustTokenPrivileges(

                    hToken, 

                    FALSE, 

                    &tokenPrivilege, 

                    sizeof(tokenPrivilege), 

                    NULL, 

                    NULL);

        }

    }


    if (hToken)

    {

        CloseHandle(hToken);

    }


    return rc;

}



BOOL

EnableUserModeHardwareIO()

{

    typedef ULONG (__stdcall* pfn_ZwSetInformationProcess)(

                    HANDLE, 

                    ULONG, 

                    PVOID, 

                    ULONG);


    BOOL rc = FALSE;

    HMODULE hNtDll = NULL;

    ULONG IOPL = 3;

    INT ProcessUserModeIOPL = 16;

    pfn_ZwSetInformationProcess ZwSetInformationProcess;



    hNtDll = GetModuleHandle("ntdll.dll");


    if (hNtDll)

    {

        ZwSetInformationProcess = (pfn_ZwSetInformationProcess) 

            GetProcAddress(hNtDll, "ZwSetInformationProcess");


        if (ZwSetInformationProcess)

        {

            //

            //  Enable SeTcbPrivilege

            //

            rc = EnablePrivilege(SE_TCB_NAME);


            if (rc)

            {

                //

                //  Grant user mode hardware IO access.

                //

                rc = ZwSetInformationProcess(

                        GetCurrentProcess(), 

                        ProcessUserModeIOPL, 

                        &IOPL, 

                        sizeof(IOPL));


                //

                //  An NTSTATUS is returned, so zero is success.

                //


                if (!rc)

                {

                    rc = TRUE;

                }

            }

        }

    }


    return rc;

}



int 

__cdecl 

main(

    int argc, 

    char* argv[]

    )

{

    UNREFERENCED_PARAMETER(argc);   //  To compile cleanly at /W4

    UNREFERENCED_PARAMETER(argv);   //  To compile cleanly at /W4


    if (EnableUserModeHardwareIO())

    {

        //

        //  Hard boot the machine via writing directly to the keyboard

        //  controller...

        //

        __asm mov dx, 0x64

        __asm mov al, 0xFE

        __asm out dx, al

    }


    return 0;

}


/* EOF */