参考 https://blog.csdn.net/FX677588/article/details/74615658
1、在C++中,mutable是为了突破const的限制而设置的。被mutable修饰的变量,将永远处于可变的状态,即使在一个const函数中,甚至结构体变量或者类对象为const,其mutable成员也可以被修改,对业务逻辑的约束
2、volatile是一个类型修饰符。volatile修饰的数据,编译器不可对其进行执行期寄存器于寄存器的优化。这种特性,是为了满足多线程同步、中断、硬件编程等特殊需要。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的直接访问,对编译器的优化约束
从KProcCheck的代码里提取出来的,不用安装驱动程序,自己的程序里要用的时候用HANDLE openDriver(void)加载驱动,用完了void uninstallDriver(void)卸载。使用时还需自己修改,代码不难,看下就明白了。
代码如下:
//HANDLE openDriver(void)打开驱动建立的符号链接的句柄
//void uninstallDriver(void)卸载驱动,要把openDriver打开的句柄关闭才可以成功卸载
#include <windows.h>
#define DRV_NAME "DLPORTIO"//驱动名
#define DRV_FILENAME "DLPORTIO.sys"//驱动文件
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
typedef LONG NTSTATUS;
typedef struct _STRING {
USHORT Length;
USHORT MaximumLength;
PCHAR Buffer;
} ANSI_STRING, *PANSI_STRING;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
//*********************************************************************************************
// Assign loaddriver priviledge to our process, so we can load our support driver.
//
//*********************************************************************************************
BOOL getLoadDriverPriv()
{
HANDLE hToken;
if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
{
LUID huid;
if(LookupPrivilegeValue(NULL, "SeLoadDriverPrivilege", &huid))
{
LUID_AND_ATTRIBUTES priv;
priv.Attributes = SE_PRIVILEGE_ENABLED;
priv.Luid = huid;
TOKEN_PRIVILEGES tp;
tp.PrivilegeCount = 1;
tp.Privileges[0] = priv;
if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
{
return TRUE;
}
}
}
return FALSE;
}
//*********************************************************************************************
// Sets up the necessary registry settings to load the support driver
//
//*********************************************************************************************
BOOL setupRegistry()
{
HKEY hkey;
if(RegCreateKey(HKEY_LOCAL_MACHINE, "System\CurrentControlSet\Services\"DRV_NAME, &hkey) != ERROR_SUCCESS)
return FALSE;
DWORD val;
val = 1;
if(RegSetValueEx(hkey, "Type", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
return FALSE;
if(RegSetValueEx(hkey, "ErrorControl", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
return FALSE;
val = 3;
if(RegSetValueEx(hkey, "Start", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
return FALSE;
char *imgName = "System32\DRIVERS\"DRV_FILENAME;
if(RegSetValueEx(hkey, "ImagePath", 0, REG_EXPAND_SZ, (PBYTE)imgName, strlen(imgName)) != ERROR_SUCCESS)
return FALSE;
return TRUE;
}
//*********************************************************************************************
// Actual code to load our driver into memory
//
//*********************************************************************************************
BOOL loadDriver()
{
// call ntdll APIs
HMODULE hntdll;
NTSTATUS (WINAPI *_RtlAnsiStringToUnicodeString)(PUNICODE_STRING DestinationString,IN PANSI_STRING SourceString,IN
BOOLEAN);
VOID (WINAPI *_RtlInitAnsiString)
(IN OUT PANSI_STRING DestinationString,
IN PCHAR SourceString);
NTSTATUS (WINAPI * _ZwLoadDriver)
(IN PUNICODE_STRING DriverServiceName);
NTSTATUS (WINAPI * _ZwUnloadDriver)
(IN PUNICODE_STRING DriverServiceName);
VOID (WINAPI * _RtlFreeUnicodeString)
(IN PUNICODE_STRING UnicodeString);
hntdll = GetModuleHandle("ntdll.dll");
*(FARPROC *)&_ZwLoadDriver = GetProcAddress(hntdll, "NtLoadDriver");
*(FARPROC *)&_ZwUnloadDriver = GetProcAddress(hntdll, "NtUnloadDriver");
*(FARPROC *)&_RtlAnsiStringToUnicodeString =
GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
*(FARPROC *)&_RtlInitAnsiString =
GetProcAddress(hntdll, "RtlInitAnsiString");
*(FARPROC *)&_RtlFreeUnicodeString =
GetProcAddress(hntdll, "RtlFreeUnicodeString");
if(_ZwLoadDriver && _ZwUnloadDriver && _RtlAnsiStringToUnicodeString &&
_RtlInitAnsiString && _RtlFreeUnicodeString)
{
ANSI_STRING aStr;
_RtlInitAnsiString(&aStr,
"\Registry\Machine\System\CurrentControlSet\Services\"DRV_NAME);
UNICODE_STRING uStr;
if(_RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS)
return FALSE;
else
{
if(_ZwLoadDriver(&uStr) == STATUS_SUCCESS)
{
_RtlFreeUnicodeString(&uStr);
return TRUE;
}
_RtlFreeUnicodeString(&uStr);
}
}
return FALSE;
}
//*********************************************************************************************
// Actual code to remove our driver from memory
//
//*********************************************************************************************
BOOL unloadDriver()
{
// call ntdll APIs
HMODULE hntdll;
NTSTATUS (WINAPI * _RtlAnsiStringToUnicodeString)
(PUNICODE_STRING DestinationString,
IN PANSI_STRING SourceString,
IN BOOLEAN);
VOID (WINAPI *_RtlInitAnsiString)
(IN OUT PANSI_STRING DestinationString,
IN PCHAR SourceString);
NTSTATUS (WINAPI * _ZwLoadDriver)
(IN PUNICODE_STRING DriverServiceName);
NTSTATUS (WINAPI * _ZwUnloadDriver)
(IN PUNICODE_STRING DriverServiceName);
VOID (WINAPI * _RtlFreeUnicodeString)
(IN PUNICODE_STRING UnicodeString);
hntdll = GetModuleHandle("ntdll.dll");
*(FARPROC *)&_ZwLoadDriver = GetProcAddress(hntdll, "NtLoadDriver");
*(FARPROC *)&_ZwUnloadDriver = GetProcAddress(hntdll, "NtUnloadDriver");
*(FARPROC *)&_RtlAnsiStringToUnicodeString =
GetProcAddress(hntdll, "RtlAnsiStringToUnicodeString");
*(FARPROC *)&_RtlInitAnsiString =
GetProcAddress(hntdll, "RtlInitAnsiString");
*(FARPROC *)&_RtlFreeUnicodeString =
GetProcAddress(hntdll, "RtlFreeUnicodeString");
if(_ZwLoadDriver && _ZwUnloadDriver && _RtlAnsiStringToUnicodeString &&
_RtlInitAnsiString && _RtlFreeUnicodeString)
{
ANSI_STRING aStr;
_RtlInitAnsiString(&aStr,
"\Registry\Machine\System\CurrentControlSet\Services\"DRV_NAME);
UNICODE_STRING uStr;
if(_RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS)
return FALSE;
else
{
if(_ZwUnloadDriver(&uStr) == STATUS_SUCCESS)
{
_RtlFreeUnicodeString(&uStr);
return TRUE;
}
_RtlFreeUnicodeString(&uStr);
}
}
return FALSE;
}
//*********************************************************************************************
// Removes our driver file and registry settings
//
//*********************************************************************************************
void cleanupDriver(void)
{
char sysDir[MAX_PATH + 1];
GetSystemDirectory(sysDir, MAX_PATH);
strncat(sysDir, "\drivers\"DRV_FILENAME, MAX_PATH);
DeleteFile(sysDir);
RegDeleteKey(HKEY_LOCAL_MACHINE, "System\CurrentControlSet\Services\"DRV_NAME"\Enum");
RegDeleteKey(HKEY_LOCAL_MACHINE, "System\CurrentControlSet\Services\"DRV_NAME);
}
//*********************************************************************************************
// Attempts to get a handle to our kernel driver. If fails, try to install the driver.
//
//*********************************************************************************************
HANDLE openDriver(void)
{
HANDLE hDevice;
//CreateFile打开驱动建立的符号链接,得根据驱动中建立的名字更改
hDevice = CreateFile("\\.\"DRV_NAME, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
char drvFullPath[MAX_PATH+1];
char *filePart;
ZeroMemory(drvFullPath, MAX_PATH);
GetFullPathName(DRV_FILENAME, MAX_PATH, drvFullPath, &filePart);
//printf("%s ", drvFullPath);
HANDLE hFile = CreateFile(drvFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
//printf("Cannot find required driver file %s ", drvFullPath);
AfxMessageBox("Cannot find required driver file");
return INVALID_HANDLE_VALUE;
}
else
{
CloseHandle(hFile);
char sysDir[MAX_PATH + 1];
GetSystemDirectory(sysDir, MAX_PATH);
strncat(sysDir, "\drivers\"DRV_FILENAME, MAX_PATH);
CopyFile(drvFullPath, sysDir, TRUE);
if(!getLoadDriverPriv())
{
//printf("Error getting load driver privilege! ");
AfxMessageBox("Error getting load driver privilege! ");
}
else
{
if(!setupRegistry())
{
//printf("Error setting driver registry keys! Make sure you are running this as
Administrator. ");
AfxMessageBox("Error setting driver registry keys! Make sure you are running this as
Administrator. ");
}
else
{
loadDriver();
hDevice = CreateFile("\\.\"DRV_NAME, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ
| FILE_SHARE_WRITE,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if(hDevice == INVALID_HANDLE_VALUE)
{
//printf("Error loading kernel support driver! Make sure you are running
this as Administrator. ");
AfxMessageBox("Error loading kernel support driver! Make sure you are
running this as Administrator. ");
}
else
{
AfxMessageBox("loading kernel support driver success");
}
}
}
cleanupDriver();
}
}
return hDevice;
}
//*********************************************************************************************
// Remove our kernel driver from memory
//
//*********************************************************************************************
void uninstallDriver(void)
{
char drvFullPath[MAX_PATH+1];
char *filePart;
ZeroMemory(drvFullPath, MAX_PATH);
GetFullPathName(DRV_FILENAME, MAX_PATH, drvFullPath, &filePart);
HANDLE hFile = CreateFile(drvFullPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, 0);
if(hFile == INVALID_HANDLE_VALUE)
{
//printf("Cannot find required driver file %s ", drvFullPath);
AfxMessageBox("Cannot find required driver file ");
return;
}
else
{
CloseHandle(hFile);
char sysDir[MAX_PATH + 1];
GetSystemDirectory(sysDir, MAX_PATH);
strncat(sysDir, "\drivers\"DRV_FILENAME, MAX_PATH);
CopyFile(drvFullPath, sysDir, TRUE);
if(!getLoadDriverPriv())
{
//printf("Error getting load driver privilege! ");
AfxMessageBox("Error getting load driver privilege! ");
}
else
{
if(!setupRegistry())
{
//printf("Error setting driver registry keys! Make sure you are running this as
Administrator. ");
AfxMessageBox("Error setting driver registry keys! Make sure you are running this as
Administrator. ");
}
else
{
if(unloadDriver())
//printf("Support driver successfully unloaded. ");
AfxMessageBox("Support driver successfully unloaded. ");
else
//printf("Unload support driver failed. It is probably not loaded. ");
AfxMessageBox("Unload support driver failed. It is probably not loaded. ");
}
}
cleanupDriver();
}
}