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;
}

三、总结

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

相关推荐
NiceCloud喜云6 小时前
Opus 4.8 的 Effort Control 怎么选:Low 到 Max 五档策略
android·java·大数据·前端·c++·python·spring
Dfreedom.6 小时前
Windows、虚拟机、开发板组网通信原理及调试通联步骤
人工智能·windows·部署·边缘计算·开发板·模型加速
cjhbachelor6 小时前
c++继承
c++
肩上风骋7 小时前
C++14特性
开发语言·c++·c++14特性
QiLinkOS10 小时前
【从实验室到商业战场:发明专利如何重塑科技与企业的共生生态】
大数据·c语言·数据结构·c++·人工智能·单片机·算法
Irissgwe10 小时前
c++11(lambda表达式与包装器、线程库)
c++·c++11·lambda表达式·线程库·包装器·互斥量库·条件变量库
Peter·Pan爱编程11 小时前
14. Lambda 表达式:随手可写的函数对象
c++·算法·ai编程
不想写代码的星星12 小时前
从分支预测角度看 C++:为什么你的热循环慢得离谱?
c++
三无推导12 小时前
ComfyUI 安装部署教程:Windows 下快速搭建可视化 AI 绘图工作流,零基础也能跑通
人工智能·pytorch·windows·stable diffusion·aigc·ai绘画·持续部署
郝学胜-神的一滴12 小时前
Qt 高级开发 018:复刻经典登录界面布局与窗口美化全解析
开发语言·c++·qt·程序人生·用户界面