HyperDbg/hyperdbg/libhyperdbg/code/debugger/driver-loader/install.cpp

556 lines
14 KiB
C++
Raw Permalink Normal View History

2020-05-27 12:09:57 -07:00
/**
* @file Install.cpp
2022-01-18 22:38:56 +03:30
* @author Sina Karvandi (sina@hyperdbg.org)
2020-05-27 12:09:57 -07:00
* @brief Install functions
* @details
* @version 0.1
* @date 2020-04-11
*
* @copyright This project is released under the GNU Public License v3.
*
*/
#include "pch.h"
2020-05-27 12:09:57 -07:00
/**
* @brief Install driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
2021-03-22 18:19:39 +04:30
InstallDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName, LPCTSTR ServiceExe)
{
SC_HANDLE SchService;
2023-03-22 17:45:52 +09:00
DWORD LastError;
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
//
// 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
2023-02-02 19:41:32 +09:00
// (in order to determine a unique Tag, etc.)
//
//
// Create a new a service object
//
2023-03-22 17:45:52 +09:00
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
2023-02-02 19:41:32 +09:00
);
2023-03-22 17:45:52 +09:00
if (SchService == NULL)
{
LastError = GetLastError();
2021-03-22 18:19:39 +04:30
2023-03-22 17:45:52 +09:00
if (LastError == ERROR_SERVICE_EXISTS)
{
2021-03-22 18:19:39 +04:30
//
// The service is already been created
// means that, the driver is previously installed
//
ShowMessages("the service (driver) already exists\n");
//
// We need to remove the old instance of the driver first
// Because the version of the driver might be different from the
// user-mode application
//
ShowMessages("trying to remove the old instance of the driver first\n");
//
// Stop the driver
//
ManageDriver(DriverName, NULL, DRIVER_FUNC_STOP);
//
// Remove the driver
//
if (ManageDriver(DriverName, NULL, DRIVER_FUNC_REMOVE))
{
ShowMessages("the old instance of the driver is removed successfully\n");
}
else
{
ShowMessages("err, failed to remove the old instance of the driver\n");
return FALSE;
}
//
// Try to install the driver again
2021-03-22 18:19:39 +04:30
//
ShowMessages("installing the driver again\n");
if (InstallDriver(SchSCManager, DriverName, ServiceExe))
{
return TRUE;
}
else
{
ShowMessages("err, failed to install the driver after removing the old instance\n");
return FALSE;
}
2023-03-22 17:45:52 +09:00
}
else if (LastError == ERROR_SERVICE_MARKED_FOR_DELETE)
{
2021-03-22 18:19:39 +04:30
//
// Previous instance of the service is not fully deleted so sleep
2023-02-02 19:41:32 +09:00
// and try again
2021-03-22 18:19:39 +04:30
//
ShowMessages("err, previous instance of the service is not fully deleted. Try "
2021-03-22 18:19:39 +04:30
"again...\n");
return FALSE;
2023-03-22 17:45:52 +09:00
}
else
{
ShowMessages("err, CreateService failed (%x)\n", LastError);
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Indicate an error
2021-03-22 18:19:39 +04:30
//
return FALSE;
}
2020-05-27 12:09:57 -07:00
}
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Close the service object
2021-03-22 18:19:39 +04:30
//
2023-03-22 17:45:52 +09:00
if (SchService)
{
CloseServiceHandle(SchService);
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Indicate success
2021-03-22 18:19:39 +04:30
//
return TRUE;
2020-05-27 12:09:57 -07:00
}
/**
* @brief Manage Driver
*
* @param DriverName
* @param ServiceName
* @param Function
2020-05-27 12:09:57 -07:00
* @return BOOLEAN
*/
BOOLEAN
ManageDriver(LPCTSTR DriverName, LPCTSTR ServiceName, UINT16 Function)
2021-03-22 18:19:39 +04:30
{
SC_HANDLE SchSCManager;
2023-03-22 17:45:52 +09:00
BOOLEAN Res = TRUE;
2020-05-27 12:09:57 -07:00
//
2023-02-02 19:41:32 +09:00
// Insure (somewhat) that the driver and service names are valid
2020-05-27 12:09:57 -07:00
//
if (!DriverName || (Function == DRIVER_FUNC_INSTALL && !ServiceName))
2023-03-22 17:45:52 +09:00
{
ShowMessages("invalid Driver or Service provided to ManageDriver() \n");
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
return FALSE;
2020-05-27 12:09:57 -07:00
}
//
2023-02-02 19:41:32 +09:00
// Connect to the Service Control Manager and open the Services database
2020-05-27 12:09:57 -07:00
//
SchSCManager = OpenSCManager(NULL, // local machine
2023-03-22 17:45:52 +09:00
NULL, // local database
SC_MANAGER_ALL_ACCESS // access required
2021-03-22 18:19:39 +04:30
);
if (!SchSCManager)
2023-03-22 17:45:52 +09:00
{
2021-09-30 12:31:51 +03:30
ShowMessages("err, OpenSCManager failed (%x)\n", GetLastError());
2021-03-22 18:19:39 +04:30
return FALSE;
}
2020-05-27 12:09:57 -07:00
//
2023-02-02 19:41:32 +09:00
// Do the requested function
2020-05-27 12:09:57 -07:00
//
2023-03-22 17:45:52 +09:00
switch (Function)
{
2021-03-22 18:19:39 +04:30
case DRIVER_FUNC_INSTALL:
//
2023-02-02 19:41:32 +09:00
// Install the driver service
2021-03-22 18:19:39 +04:30
//
if (InstallDriver(SchSCManager, DriverName, ServiceName))
2023-03-22 17:45:52 +09:00
{
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Start the driver service (i.e. start the driver)
2021-03-22 18:19:39 +04:30
//
Res = StartDriver(SchSCManager, DriverName);
2023-03-22 17:45:52 +09:00
}
else
{
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Indicate an error
2021-03-22 18:19:39 +04:30
//
Res = FALSE;
2021-03-22 18:19:39 +04:30
}
break;
case DRIVER_FUNC_STOP:
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Stop the driver
2021-03-22 18:19:39 +04:30
//
Res = StopDriver(SchSCManager, DriverName);
break;
case DRIVER_FUNC_REMOVE:
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Remove the driver service
2021-03-22 18:19:39 +04:30
//
Res = RemoveDriver(SchSCManager, DriverName);
2021-03-22 18:19:39 +04:30
break;
default:
2023-02-02 19:41:32 +09:00
ShowMessages("unknown ManageDriver() function \n");
2021-03-22 18:19:39 +04:30
Res = FALSE;
2021-03-22 18:19:39 +04:30
break;
}
2020-05-27 12:09:57 -07:00
//
2023-02-02 19:41:32 +09:00
// Close handle to service control manager
2020-05-27 12:09:57 -07:00
//
if (SchSCManager)
2023-03-22 17:45:52 +09:00
{
CloseServiceHandle(SchSCManager);
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
return Res;
2020-05-27 12:09:57 -07:00
}
/**
* @brief Remove Driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
2021-03-22 18:19:39 +04:30
RemoveDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName)
{
SC_HANDLE SchService;
2023-03-22 17:45:52 +09:00
BOOLEAN Res;
2020-05-27 12:09:57 -07:00
//
// Open the handle to the existing service
2020-05-27 12:09:57 -07:00
//
SchService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
2020-05-27 12:09:57 -07:00
2023-03-22 17:45:52 +09:00
if (SchService == NULL)
{
2021-09-30 12:31:51 +03:30
ShowMessages("err, OpenService failed (%x)\n", GetLastError());
2021-03-22 18:19:39 +04:30
//
// Indicate error
2021-03-22 18:19:39 +04:30
//
return FALSE;
}
2020-05-27 12:09:57 -07:00
//
// Mark the service for deletion from the service control manager database
2020-05-27 12:09:57 -07:00
//
2023-03-22 17:45:52 +09:00
if (DeleteService(SchService))
{
2021-03-22 18:19:39 +04:30
//
// Indicate success
2021-03-22 18:19:39 +04:30
//
Res = TRUE;
2023-03-22 17:45:52 +09:00
}
else
{
2021-09-30 12:31:51 +03:30
ShowMessages("err, DeleteService failed (%x)\n", GetLastError());
2021-03-22 18:19:39 +04:30
//
// Indicate failure. Fall through to properly close the service handle
2021-03-22 18:19:39 +04:30
//
Res = FALSE;
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
//
// Close the service object
2020-05-27 12:09:57 -07:00
//
2023-03-22 17:45:52 +09:00
if (SchService)
{
CloseServiceHandle(SchService);
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
return Res;
2020-05-27 12:09:57 -07:00
}
/**
* @brief Start Driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
2021-03-22 18:19:39 +04:30
StartDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName)
{
2024-03-15 13:49:02 +09:00
SC_HANDLE SchService;
DWORD LastError;
BOOLEAN Status = TRUE;
2020-05-27 12:09:57 -07:00
//
2023-02-02 19:41:32 +09:00
// Open the handle to the existing service
2020-05-27 12:09:57 -07:00
//
SchService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
2020-05-27 12:09:57 -07:00
2023-03-22 17:45:52 +09:00
if (SchService == NULL)
{
2021-09-30 12:31:51 +03:30
ShowMessages("err, OpenService failed (%x)\n", GetLastError());
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
//
// Indicate failure
2021-03-22 18:19:39 +04:30
//
return FALSE;
2020-05-27 12:09:57 -07:00
}
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Start the execution of the service (i.e. start the driver)
2021-03-22 18:19:39 +04:30
//
if (!StartService(SchService, // service identifier
2023-03-22 17:45:52 +09:00
0, // number of arguments
NULL // pointer to arguments
))
{
LastError = GetLastError();
2021-03-22 18:19:39 +04:30
2023-03-22 17:45:52 +09:00
if (LastError == ERROR_SERVICE_ALREADY_RUNNING)
{
2021-03-22 18:19:39 +04:30
//
// Ignore this error
2021-03-22 18:19:39 +04:30
//
2023-03-22 17:45:52 +09:00
}
else if (LastError == ERROR_PATH_NOT_FOUND)
{
//
// Driver not found, or anti-virus limits the access to it
//
ShowMessages("err, path to the driver not found, or the access to the driver file is limited\n");
ShowMessages("most of the time, it's because anti-virus software is not finished scanning the drivers, "
"so, if you try to load the driver again (re-enter the previous command), the problem will be solved\n");
//
// Indicate failure
//
Status = FALSE;
2023-03-22 17:45:52 +09:00
}
else if (LastError == ERROR_INVALID_IMAGE_HASH)
{
2021-03-22 18:19:39 +04:30
ShowMessages(
"err, failed loading driver\n"
"it's because either the driver signature enforcement is enabled or HVCI prevents the driver from loading\n"
"you should disable the driver signature enforcement by attaching WinDbg or from the boot menu\n"
"if the driver signature enforcement is disabled, HVCI might prevent the driver from loading\n"
"HyperDbg is not compatible with Virtualization Based Security (VBS)\n"
"please follow the instructions from: https://docs.hyperdbg.org/getting-started/build-and-install \n");
2021-03-22 18:19:39 +04:30
//
// Indicate failure. Fall through to properly close the service handle
2021-03-22 18:19:39 +04:30
//
Status = FALSE;
2023-03-22 17:45:52 +09:00
}
else
{
ShowMessages("err, StartService failure (%x)\n", LastError);
2021-03-22 18:19:39 +04:30
//
// Indicate failure. Fall through to properly close the service handle
2021-03-22 18:19:39 +04:30
//
Status = FALSE;
2021-03-22 18:19:39 +04:30
}
}
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
//
// Close the service object
2021-03-22 18:19:39 +04:30
//
2023-03-22 17:45:52 +09:00
if (SchService)
{
CloseServiceHandle(SchService);
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
return Status;
2020-05-27 12:09:57 -07:00
}
/**
* @brief Stop driver
*
* @param SC_HANDLE
* @param LPCTSTR
* @return BOOLEAN
*/
BOOLEAN
2021-03-22 18:19:39 +04:30
StopDriver(SC_HANDLE SchSCManager, LPCTSTR DriverName)
{
2023-03-22 17:45:52 +09:00
BOOLEAN Res = TRUE;
SC_HANDLE SchService;
2021-03-22 18:19:39 +04:30
SERVICE_STATUS serviceStatus;
2020-05-27 12:09:57 -07:00
//
2023-02-02 19:41:32 +09:00
// Open the handle to the existing service
2020-05-27 12:09:57 -07:00
//
SchService = OpenService(SchSCManager, DriverName, SERVICE_ALL_ACCESS);
2020-05-27 12:09:57 -07:00
2023-03-22 17:45:52 +09:00
if (SchService == NULL)
{
2021-09-30 12:31:51 +03:30
ShowMessages("err, OpenService failed (%x)\n", GetLastError());
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
return FALSE;
}
2020-05-27 12:09:57 -07:00
//
2023-02-02 19:41:32 +09:00
// Request that the service stop
2020-05-27 12:09:57 -07:00
//
2023-03-22 17:45:52 +09:00
if (ControlService(SchService, SERVICE_CONTROL_STOP, &serviceStatus))
{
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Indicate success
2021-03-22 18:19:39 +04:30
//
Res = TRUE;
2023-03-22 17:45:52 +09:00
}
else
{
2025-02-24 15:05:18 +01:00
ShowMessages("warning, failed to stop the driver. Possible reasons include the driver not currently running or an unsuccessful unload from a previous run. "
"This is not an error, HyperDbg tries to remove the previous driver and load it again (%x)\n",
GetLastError());
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Indicate failure. Fall through to properly close the service handle
2021-03-22 18:19:39 +04:30
//
Res = FALSE;
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Close the service object
2021-03-22 18:19:39 +04:30
//
2023-03-22 17:45:52 +09:00
if (SchService)
{
CloseServiceHandle(SchService);
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
return Res;
2020-05-27 12:09:57 -07:00
}
/**
* @brief Setup file name
2020-05-27 12:09:57 -07:00
*
* @param FileName
* @param FileLocation
2023-02-02 19:41:32 +09:00
* @param BufferLength
* @param CheckFileExists
2023-02-02 19:41:32 +09:00
*
2020-05-27 12:09:57 -07:00
* @return BOOLEAN
*/
BOOLEAN
SetupPathForFileName(const CHAR * FileName,
_Inout_updates_bytes_all_(BufferLength) PCHAR FileLocation,
ULONG BufferLength,
BOOLEAN CheckFileExists)
2021-03-22 18:19:39 +04:30
{
2023-03-22 17:45:52 +09:00
HANDLE FileHandle;
DWORD FileLocLen = 0;
HMODULE ProcHandle = GetModuleHandle(NULL);
CHAR * Pos;
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
//
// Get the current directory.
//
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
/*
2020-08-28 04:03:12 -07:00
//
// We use the location of running exe instead of
// finding driver based on current directory
//
FileLocLen = GetCurrentDirectory(BufferLength, DriverLocation);
2020-05-27 12:09:57 -07:00
if (FileLocLen == 0) {
2020-05-27 12:09:57 -07:00
2021-09-30 12:31:51 +03:30
ShowMessages("err, GetCurrentDirectory failed (%x)\n", GetLastError());
2020-05-27 12:09:57 -07:00
return FALSE;
}
2020-08-28 04:03:12 -07:00
*/
GetModuleFileName(ProcHandle, FileLocation, BufferLength);
2021-03-22 18:19:39 +04:30
Pos = strrchr(FileLocation, '\\');
2023-03-22 17:45:52 +09:00
if (Pos != NULL)
{
2021-03-22 18:19:39 +04:30
//
// this will put the null terminator here. you can also copy to
// another string if you want, we can also use PathCchRemoveFileSpec
//
*Pos = '\0';
}
2020-08-28 04:03:12 -07:00
//
2023-02-02 19:41:32 +09:00
// Setup path name to driver file
2020-08-28 04:03:12 -07:00
//
2021-03-22 18:19:39 +04:30
if (FAILED(
StringCbCat(FileLocation, BufferLength, "\\")))
2023-03-22 17:45:52 +09:00
{
2023-02-02 19:41:32 +09:00
return FALSE;
}
if (FAILED(
StringCbCat(FileLocation, BufferLength, FileName)))
2023-03-22 17:45:52 +09:00
{
2021-03-22 18:19:39 +04:30
return FALSE;
}
2020-05-27 12:09:57 -07:00
if (CheckFileExists)
2023-03-22 17:45:52 +09:00
{
2021-03-22 18:19:39 +04:30
//
// ensure file is in the specified directory
2021-03-22 18:19:39 +04:30
//
if ((FileHandle = CreateFile(FileLocation, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE)
{
ShowMessages("err, target file is not loaded\n");
2020-05-27 12:09:57 -07:00
//
// Indicate failure
//
return FALSE;
}
//
// Close open file handle
//
if (FileHandle)
{
CloseHandle(FileHandle);
}
2021-03-22 18:19:39 +04:30
}
2020-05-27 12:09:57 -07:00
2021-03-22 18:19:39 +04:30
//
2023-02-02 19:41:32 +09:00
// Indicate success
2021-03-22 18:19:39 +04:30
//
return TRUE;
2020-05-27 12:09:57 -07:00
}