HyperDbg/hyperdbg/hprdbgctrl/Source Files/Debugger/Driver Loader/install.cpp
2021-09-25 15:46:05 +03:30

505 lines
11 KiB
C++

/**
* @file Install.cpp
* @author Sina Karvandi (sina@rayanfam.com)
* @brief Install functions
* @details
* @version 0.1
* @date 2020-04-11
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "..\hprdbgctrl\pch.h"
BOOLEAN
InstallDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName, LPCTSTR ServiceExe);
BOOLEAN
RemoveDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName);
BOOLEAN
StartDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName);
BOOLEAN
StopDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName);
/**
* @brief Install driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
InstallDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName, LPCTSTR ServiceExe)
{
SC_HANDLE schService;
DWORD err;
//
// NOTE: This creates an entry for a standalone driver. If this
// is modified for use with a driver that requires a Tag,
// Group, and/or Dependencies, it may be necessary to
// query the registry for existing driver information
// (in order to determine a unique Tag, etc.).
//
//
// Create a new a service object.
//
schService =
CreateService(SchSCManager, // handle of service control manager database
DriverName, // address of name of service to start
DriverName, // address of display name
SERVICE_ALL_ACCESS, // type of access to service
SERVICE_KERNEL_DRIVER, // type of service
SERVICE_DEMAND_START, // when to start service
SERVICE_ERROR_NORMAL, // severity if service fails to start
ServiceExe, // address of name of binary file
NULL, // service does not belong to a group
NULL, // no tag requested
NULL, // no dependency names
NULL, // use LocalSystem account
NULL // no password for service account
);
if (schService == NULL)
{
err = GetLastError();
if (err == ERROR_SERVICE_EXISTS)
{
//
// Ignore this error.
//
return TRUE;
}
else if (err == ERROR_SERVICE_MARKED_FOR_DELETE)
{
//
// Previous instance of the service is not fully deleted so sleep
// and try again.
//
ShowMessages("previous instance of the service is not fully deleted. Try "
"again...\n");
return FALSE;
}
else
{
ShowMessages("err, CreateService failed! Error = %d \n", err);
//
// Indicate an error.
//
return FALSE;
}
}
//
// Close the service object.
//
if (schService)
{
CloseServiceHandle(schService);
}
//
// Indicate success.
//
return TRUE;
}
/**
* @brief Manage Driver
*
* @param LPCTSTR
* @param LPCTSTR
* @param USHORT
* @return BOOLEAN
*/
BOOLEAN
ManageDriver(LPCTSTR DriverName, LPCTSTR ServiceName, USHORT Function)
{
SC_HANDLE schSCManager;
BOOLEAN rCode = TRUE;
//
// Insure (somewhat) that the driver and service names are valid.
//
if (!DriverName || !ServiceName)
{
ShowMessages("invalid Driver or Service provided to ManageDriver() \n");
return FALSE;
}
//
// Connect to the Service Control Manager and open the Services database.
//
schSCManager = OpenSCManager(NULL, // local machine
NULL, // local database
SC_MANAGER_ALL_ACCESS // access required
);
if (!schSCManager)
{
ShowMessages("err, OpenSCManager failed (%d)\n", GetLastError());
return FALSE;
}
//
// Do the requested function.
//
switch (Function)
{
case DRIVER_FUNC_INSTALL:
//
// Install the driver service.
//
if (InstallDriver(schSCManager, DriverName, ServiceName))
{
//
// Start the driver service (i.e. start the driver).
//
rCode = StartDriver(schSCManager, DriverName);
}
else
{
//
// Indicate an error.
//
rCode = FALSE;
}
break;
case DRIVER_FUNC_STOP:
//
// Stop the driver.
//
StopDriver(schSCManager, DriverName);
//
// Ignore all errors.
//
rCode = TRUE;
break;
case DRIVER_FUNC_REMOVE:
//
// Remove the driver service.
//
RemoveDriver(schSCManager, DriverName);
//
// Ignore all errors.
//
rCode = TRUE;
break;
default:
ShowMessages("unknown ManageDriver() function. \n");
rCode = FALSE;
break;
}
//
// Close handle to service control manager.
//
if (schSCManager)
{
CloseServiceHandle(schSCManager);
}
return rCode;
}
/**
* @brief Remove Driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
RemoveDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName)
{
SC_HANDLE schService;
BOOLEAN rCode;
//
// Open the handle to the existing service
//
schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
if (schService == NULL)
{
ShowMessages("err, OpenService failed (%d)\n", GetLastError());
//
// Indicate error
//
return FALSE;
}
//
// Mark the service for deletion from the service control manager database
//
if (DeleteService(schService))
{
//
// Indicate success
//
rCode = TRUE;
}
else
{
ShowMessages("err, DeleteService failed (%d)\n", GetLastError());
//
// Indicate failure. Fall through to properly close the service handle
//
rCode = FALSE;
}
//
// Close the service object
//
if (schService)
{
CloseServiceHandle(schService);
}
return rCode;
}
/**
* @brief Start Driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
StartDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName)
{
SC_HANDLE schService;
DWORD err;
SERVICE_STATUS serviceStatus;
UINT64 Status = TRUE;
//
// Open the handle to the existing service.
//
schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
if (schService == NULL)
{
ShowMessages("err, OpenService failed (%d)\n", GetLastError());
//
// Indicate failure
//
return FALSE;
}
//
// Start the execution of the service (i.e. start the driver).
//
if (!StartService(schService, // service identifier
0, // number of arguments
NULL // pointer to arguments
))
{
err = GetLastError();
if (err == ERROR_SERVICE_ALREADY_RUNNING)
{
//
// Ignore this error
//
}
else if (err == 577)
{
ShowMessages(
"err (577), it's because you driver signature enforcement is enabled\n"
"you should disable driver signature enforcement by attaching Windbg "
"or from the boot menu\n");
//
// Indicate failure. Fall through to properly close the service handle
//
Status = FALSE;
}
else
{
ShowMessages("err, StartService failure (%d)\n", err);
//
// Indicate failure. Fall through to properly close the service handle
//
Status = FALSE;
}
}
//
// Close the service object
//
if (schService)
{
CloseServiceHandle(schService);
}
return Status;
}
/**
* @brief Stop driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
StopDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName)
{
BOOLEAN rCode = TRUE;
SC_HANDLE schService;
SERVICE_STATUS serviceStatus;
//
// Open the handle to the existing service.
//
schService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
if (schService == NULL)
{
ShowMessages("err, OpenService failed (%d)\n", GetLastError());
return FALSE;
}
//
// Request that the service stop.
//
if (ControlService(schService, SERVICE_CONTROL_STOP, &serviceStatus))
{
//
// Indicate success.
//
rCode = TRUE;
}
else
{
ShowMessages("err, ControlService failed! Error = %d \n", GetLastError());
//
// Indicate failure. Fall through to properly close the service handle.
//
rCode = FALSE;
}
//
// Close the service object.
//
if (schService)
{
CloseServiceHandle(schService);
}
return rCode;
}
/**
* @brief Setup driver name
*
* @param ULONG
* @return BOOLEAN
*/
BOOLEAN
SetupDriverName(_Inout_updates_bytes_all_(BufferLength) PCHAR DriverLocation,
ULONG BufferLength)
{
HANDLE fileHandle;
DWORD driverLocLen = 0;
HMODULE ProcHandle = GetModuleHandle(NULL);
char * Pos;
//
// Get the current directory.
//
/*
//
// We use the location of running exe instead of
// finding driver based on current directory
//
driverLocLen = GetCurrentDirectory(BufferLength, DriverLocation);
if (driverLocLen == 0) {
ShowMessages("err, GetCurrentDirectory failed (%d)\n", GetLastError());
return FALSE;
}
*/
GetModuleFileName(ProcHandle, DriverLocation, BufferLength);
Pos = strrchr(DriverLocation, '\\');
if (Pos != NULL)
{
//
// this will put the null terminator here. you can also copy to
// another string if you want, we can also use PathCchRemoveFileSpec
//
*Pos = '\0';
}
//
// Setup path name to driver file.
//
if (FAILED(
StringCbCat(DriverLocation, BufferLength, "\\" DRIVER_NAME ".sys")))
{
return FALSE;
}
//
// Insure driver file is in the specified directory.
//
if ((fileHandle = CreateFile(DriverLocation, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) ==
INVALID_HANDLE_VALUE)
{
ShowMessages("%s.sys is not loaded.\n", DRIVER_NAME);
//
// Indicate failure.
//
return FALSE;
}
//
// Close open file handle.
//
if (fileHandle)
{
CloseHandle(fileHandle);
}
//
// Indicate success.
//
return TRUE;
}