RW-Everything的RwDrv.sys驱动调用

RW-Everything的RwDrv.sys驱动调用


一、RwDrv.sys

RW-Everything是一个硬件底层的工具,可用于物理内存、BIOS、PCI和IO端口的查看和修改,其基于驱动RwDrv.sys来实现,利用这个驱动可以实现系统的侵入。


二、示例代码

  • 使用服务来加载RwDrv驱动
  • 打开Win Object对象,通过调用DeviceIoControl通信调用
cpp 复制代码
#include <Windows.h>
#include <stdio.h>

#define RW_DRIVER_ID							"RwDrv"

// type of access: U8 = 0; U16 = 1, U32 =2, ref to READ_REGISTER_BUFFER_UCHAR / USHORT / ULONG
typedef struct {
	DWORD64 physicalAddress;
	DWORD size;
	DWORD access;
	DWORD64 buffer;
} PhysRw_t;

typedef struct {
	DWORD low;
	DWORD pad;
	DWORD reg;
	DWORD high;
} MSRRw_t;

HANDLE hDrv;

DWORD LoadDriver()
{
	TCHAR sDrv[MAX_PATH] = {0};
	GetFullPathName("RwDrv.sys", MAX_PATH, sDrv, NULL);
	
	//check driver exist
	WIN32_FIND_DATA	findData;
	HANDLE hFile = FindFirstFile(sDrv, &findData);
	if(hFile == INVALID_HANDLE_VALUE)
	{
		printf("Driver File Doesn't Exist, errno = %d.\n", GetLastError());
		return -1;
	}

	//establishes a connection to the service control manager
	SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if(hSCM == NULL)
	{
		printf("Open SCM Failed, errno = %d.\n", GetLastError());
		return -1;
	}
	
	//create a service object and add to SCM
	SC_HANDLE hSrv = CreateService(hSCM, RW_DRIVER_ID, RW_DRIVER_ID, SC_MANAGER_ALL_ACCESS, 
		SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START, SERVICE_ERROR_NORMAL, 
		sDrv, NULL, NULL, NULL, NULL, NULL);
	if(hSrv == NULL)
	{
		if(GetLastError() != ERROR_SERVICE_EXISTS)
		{
			CloseHandle(hSCM);
			printf("Create Service Failed, errno = %d.\n", GetLastError());
			return -1;
		}
	}

	//open service
	hSrv = OpenService(hSCM, RW_DRIVER_ID, SERVICE_ALL_ACCESS);
	if(hSrv == NULL)
	{
		CloseHandle(hSCM);
		printf("Open Service Failed, errno = %d.\n", GetLastError());
		return -1;
	}
	
	//start service
	if(!StartService(hSrv, 0, NULL))
	{
		if(GetLastError() != ERROR_SERVICE_ALREADY_RUNNING)
		{
			CloseHandle(hSCM);
			CloseServiceHandle(hSrv);
			printf("Start Service Failed, errno = %d.\n", GetLastError());
			return -1;
		}
	}

	//create or open device object, see "Win32 Device Namespaces" section 
	//of https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file
	//and https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createfilea
	hDrv = CreateFile("\\\\.\\"RW_DRIVER_ID, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
	if(hDrv == INVALID_HANDLE_VALUE)
	{
		CloseHandle(hSCM);
		CloseServiceHandle(hSrv);
		printf("Create File Failed, errno = %d.\n", GetLastError());
		return -1;
	}

	return 0;
}

DWORD UnloadDriver()
{
	SC_HANDLE hSCM = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
	if(hSCM == NULL)
	{
		printf("Open SCM Failed, errno = %d.\n", GetLastError());
		return -1;
	}

	SC_HANDLE hSrv = OpenService(hSCM, RW_DRIVER_ID, SERVICE_ALL_ACCESS);
	if(hSrv == NULL)
	{
		CloseHandle(hSCM);
		printf("Open Service Failed, errno = %d.\n", GetLastError());
		return -1;
	}

	SERVICE_STATUS status;
	if (!ControlService(hSrv, SERVICE_CONTROL_STOP, &status)) 
	{
		CloseHandle(hSCM);
		CloseHandle(hDrv);
		printf("Stop Service Failed, errno = %d.\n", GetLastError());
		return -1;
	}

	CloseHandle(hSCM);
	CloseHandle(hDrv);

	return 0;
}

BOOL isElevated() {
	HANDLE hToken = NULL;
	if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
		TOKEN_ELEVATION Elevation;
		DWORD cbSize = sizeof(TOKEN_ELEVATION);
		if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) {
			return Elevation.TokenIsElevated;
		}
	}
	if (hToken) {
		CloseHandle(hToken);
	}
	return FALSE;
}

void readMem(DWORD64 address, const DWORD64* buffer, DWORD size, DWORD access = 0) 
{
	PhysRw_t tPhyMem;
	tPhyMem.physicalAddress = address;
	tPhyMem.size = size;
	tPhyMem.access = access;
	tPhyMem.buffer = (DWORD64)buffer;
	DeviceIoControl(hDrv, 0x222808, &tPhyMem, sizeof(tPhyMem), &tPhyMem, sizeof(tPhyMem), NULL, NULL);
}
void writeMem(DWORD64 address, const DWORD64* buffer, DWORD size, DWORD access = 0) 
{
	PhysRw_t tPhyMem;
	tPhyMem.physicalAddress = address;
	tPhyMem.size = size;
	tPhyMem.access = access;
	tPhyMem.buffer = (DWORD64)buffer;
	DeviceIoControl(hDrv, 0x22280C, &tPhyMem, sizeof(tPhyMem), NULL, 0, NULL, NULL);
}

void readMSR(int reg, LARGE_INTEGER& value) 
{
    MSRRw_t tMSR;
	tMSR.low = 0;
	tMSR.pad = 0;
	tMSR.reg = reg;	
	tMSR.high = 0;

    DeviceIoControl(hDrv, 0x222848, &tMSR, sizeof(tMSR), &tMSR, sizeof(tMSR), NULL, NULL);

	value.LowPart = tMSR.low;
	value.HighPart = tMSR.high;
}
void writeMSR(int reg, LARGE_INTEGER& value) {
    MSRRw_t tMSR;
	ZeroMemory(&tMSR, sizeof(tMSR));
    tMSR.reg = reg;
    tMSR.low = value.LowPart;
    tMSR.high= value.HighPart;
	
    DeviceIoControl(hDrv, 0x22284C, &tMSR, sizeof(tMSR), &tMSR, sizeof(tMSR), NULL, NULL);
}

int main()
{
	//Check UAC
	if(isElevated() == FALSE)
	{
		printf("This program requires run as administrator.\n");
		return 0;
	}

	LoadDriver();

	//Read Mem
	DWORD64 buf[1] = {0};
	readMem(0x0000CCCC, buf, 1);
	/*
	DWORD64 buf[16] = {0};
	readMem(0x0000CCCC, buf, 2, 1);
	*/
	printf("read mem = %x\n", buf[0]);
	
	//Read Msr
	LARGE_INTEGER value;
	readMSR(0x20, value);
	printf("read msr high part = %08x, low part = %08x\n", value.HighPart, value.LowPart);

	UnloadDriver();

	return 0;
}

三、总结

合法的签名驱动可以调用内核的很多方法来实现系统或硬件的控制,但对于一些情况我们无法申请签名,可以借用第三方驱动来实现,其次,这种方式是一种高风险的漏洞。

相关推荐
ShineWinsu4 小时前
对于Qt:QTreeWidget常见属性以及QTreeWidgetItem类的解析
开发语言·c++·qt·gui·客户端·多叉树·qtreewidget
落羽的落羽5 小时前
【C++】C++17的主要特性
linux·服务器·开发语言·c++·算法·机器学习
Funlang6 小时前
在 Windows 95 上跑 Fun
windows
汉克老师10 小时前
《从C++小白到算法高手:GESP 1—8级成长地图》第一讲:认识GESP——从编程新手到算法探索者
c++·gesp·信息学竞赛·小学生学c++
晴天的雨.99211 小时前
【C++】继承篇
java·开发语言·c++
ö Constancy11 小时前
一台电脑的硬件组成与作用:按功能分类详解(Windows 与 Linux 视角)
linux·windows·电脑
青少儿编程课堂11 小时前
蓝桥杯青少组图形化 + 全国青少年信息素养大赛 + 电子学会图形化考级:校园大富翁经营闯关解析
c++·python·算法·bfs·信息学竞赛
another heaven11 小时前
【C/C++ 第一次跨越(上):用 C++11/14 停止制造新的旧代码】
c语言·c++·制造
qq_4069810311 小时前
c++ lamda(三)Lambda表达式
java·前端·c++
I_belong_to_jesus1 天前
C++关于分支预测的优化1
开发语言·c++·算法