国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

第一篇 windows驅(qū)動之WinRing0.sys的開發(fā)及使用(電腦溫度監(jiān)控軟件開發(fā))

這篇具有很好參考價值的文章主要介紹了第一篇 windows驅(qū)動之WinRing0.sys的開發(fā)及使用(電腦溫度監(jiān)控軟件開發(fā))。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

簡介

??從魯大師的溫度監(jiān)控談起,現(xiàn)代的CPU、GPU等芯片一般都具有溫度監(jiān)控的功能,比如我們可能會遇到的電腦散熱不好導(dǎo)致系統(tǒng)直接關(guān)機(jī)黑屏,就是cpu檢測到當(dāng)前溫度高于額定溫度執(zhí)行的操作。

??魯大師的溫度監(jiān)控模塊就相當(dāng)于把這些信息從底層硬件讀取,然后通過上層UI顯示給用戶。其核心就是與硬件的通信驅(qū)動?,F(xiàn)在win10的驅(qū)動都可以通過系統(tǒng)更新直接完成,不再需要安裝流氓軟件“驅(qū)動精靈”、“驅(qū)動人生”等。我一般只用到溫度檢測模塊,其他功能于我都是雞肋,為了一個很小的功能,我需要安裝一個龐大的魯大師程序,甚是不劃算。故自己動手實(shí)現(xiàn)。本文的主題就是如何實(shí)現(xiàn)魯大師的溫度檢測模塊。

??封閉必將導(dǎo)致落后,開放才能共同進(jìn)步。WinRing0.sys作為一款windows平臺下與設(shè)備通信的驅(qū)動被廣泛使用。卻由開源成了閉源,由支持讀寫成了僅支持讀。本文花費(fèi)數(shù)個工作日將08年之前開源的文件進(jìn)行學(xué)習(xí)整理。便于后期大家的學(xué)習(xí)和升級優(yōu)化。

windows驅(qū)動預(yù)備知識

1.虛擬設(shè)備驅(qū)動程序

.vxd程序:虛擬設(shè)備驅(qū)動程序,主要是為了給dos程序提供一個虛擬硬件

dos程序:早于windows的程序,window 3.x時代為了發(fā)展就需要兼容這些程序。類似當(dāng)前鴻蒙兼容安卓,都是為了錢,不磕磣。

.vxd程序:可以把.vxd程序理解為運(yùn)行在第0級別的dll。

ring0:最高等級權(quán)限,可以為所欲為,直接操作硬件。

ring3:用戶等級權(quán)限,可以調(diào)用user32.dll、NTDLL.dll等庫間接控制硬件。

WinRing0.vxd:其目的并非要虛擬硬件,只是需要第0級別的權(quán)限。

總結(jié)一:.vxd程序最新也得win9的系統(tǒng)才能用到,以上當(dāng)個科普,了解下就行。對應(yīng)WingRing0驅(qū)動的學(xué)習(xí)聚焦到.sys文件。

2.設(shè)備驅(qū)動文件

.sys文件:設(shè)備驅(qū)動文件,常說的聲卡、顯卡、鍵盤驅(qū)動等,都需要開發(fā)這種文件。

.inf文件:驅(qū)動安裝的配置文件,主要是寫注冊表,注冊接口。必有參數(shù)是ClassGUID。

總結(jié)二:.sys文件也當(dāng)做權(quán)限等級為0級的.dll文件就行了。.dll文件的使用不熟悉的可以網(wǎng)上了解下。

3.sys驅(qū)動使用

.簽名:內(nèi)核級別的驅(qū)動都需要微軟公司認(rèn)證過的秘鑰進(jìn)行簽名才能直接安裝到windows系統(tǒng)中。簽名的秘鑰文件后綴是.cer。winring0,Windows驅(qū)動之WinRing0,windows,windows驅(qū)動,DDK,CPU溫度
注冊:注冊僅僅是完成在注冊表里寫一個項(xiàng)。下圖中的小工具是專門用于內(nèi)核驅(qū)動安裝運(yùn)行的。鏈接: 下載地址
winring0,Windows驅(qū)動之WinRing0,windows,windows驅(qū)動,DDK,CPU溫度
winring0,Windows驅(qū)動之WinRing0,windows,windows驅(qū)動,DDK,CPU溫度

啟動:對應(yīng)缺微軟簽名或微軟認(rèn)證過的秘鑰進(jìn)行簽名的內(nèi)核級驅(qū)動是無法直接啟動起來的。這是由于系統(tǒng)對于涉及內(nèi)核層級的驅(qū)動有簽名校驗(yàn)導(dǎo)致,簡單說就是沒有健康碼綠碼的不能在小區(qū)活動。
winring0,Windows驅(qū)動之WinRing0,windows,windows驅(qū)動,DDK,CPU溫度

禁用強(qiáng)制簽名校驗(yàn):通過修改bcdedit來取消掉這個限制。有點(diǎn)類似安卓手機(jī)安裝APP的時候經(jīng)常需要“允許安裝未知來源的程序”。逐條執(zhí)行以下命令即可(管理員權(quán)限):

"Win7系統(tǒng)"

bcdedit.exe -set loadoptions DDISABLE_INTEGRITY_CHECKS

bcdedit /set TESTSIGNING ON

bcdedit /set nointegritychecks yes

如果有失敗項(xiàng),一般需要在BIOS里面關(guān)閉安全啟動

啟動按DEL鍵 進(jìn)入BIOS 然后把 Secure Boot Policy 選項(xiàng)設(shè)置為關(guān)閉

重啟電腦
"Win10系統(tǒng)"
bcdedit.exe -set loadoptions DDISABLE_INTEGRITY_CHECKS

bcdedit /set TESTSIGNING ON

bcdedit /set nointegritychecks yes

如果有失敗,一般需要在BIOS里面關(guān)閉安全啟動

啟動按DEL鍵 進(jìn)入BIOS 然后把 Secure Boot Policy 選項(xiàng)設(shè)置為關(guān)閉

重啟電腦

代碼分析

??通過以上的知識大致了解了windows驅(qū)動程序是啥,怎么用。接下來就進(jìn)入較難的實(shí)戰(zhàn)部分,寫代碼調(diào)用驅(qū)動獲取有效信息。.sys驅(qū)動是用c語言寫的,具體代碼如下三部分。

1、驅(qū)動入口函數(shù)


NTSTATUS DriverEntry(	IN PDRIVER_OBJECT  DriverObject,	IN PUNICODE_STRING RegistryPath	)
{
	NTSTATUS		status;
	UNICODE_STRING  ntDeviceName;
	UNICODE_STRING  win32DeviceName;
	PDEVICE_OBJECT  deviceObject = NULL;

	RtlInitUnicodeString(&ntDeviceName, NT_DEVICE_NAME);

	status = IoCreateDevice(
		DriverObject,					// Our Driver Object
		0,								// We don't use a device extension
		&ntDeviceName,					// Device name 
		OLS_TYPE,						// Device type  自定義的值
		FILE_DEVICE_SECURE_OPEN,		// Device characteristics
		FALSE,							// Not an exclusive device 非排他性設(shè)備
		&deviceObject );				// Returned ptr to Device Object

	if(!NT_SUCCESS(status))
	{
		refCount = (ULONG)-1;
		return status;
	}
	else
	{
		refCount = 0;
	}

	// Initialize the driver object with this driver's entry points.
	// 構(gòu)造DriverObject這個結(jié)構(gòu)體變量
	DriverObject->MajorFunction[IRP_MJ_CREATE] = OlsDispatch;// 1.注冊函數(shù),就是把函數(shù)指針告訴操作系統(tǒng)。當(dāng)操作系統(tǒng)發(fā)送 IRP_MJ_CREATE 請求時,會調(diào)用這個函數(shù)
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = OlsDispatch;// 2.
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = OlsDispatch;// 3.
	DriverObject->DriverUnload = Unload;//驅(qū)動卸載函數(shù)

	// Initialize a Unicode String containing the Win32 name for our device.
	RtlInitUnicodeString(&win32DeviceName, DOS_DEVICE_NAME);

	// Create a symbolic link between our device name  and the Win32 name
	status = IoCreateSymbolicLink(&win32DeviceName, &ntDeviceName);

	if (!NT_SUCCESS(status))
	{
		// Delete everything that this routine has allocated.
		IoDeleteDevice( deviceObject );
	}

	return status;
}

2、調(diào)度函數(shù)

??實(shí)際讀取CPU信息的實(shí)現(xiàn)代碼在此處,主要涉及兩個參數(shù),其一是:DEVICE_OBJECT ,其二是:I/O Request Packet (IRP) 。OlsDispatch()這個函數(shù)根據(jù)傳進(jìn)來的請求信息調(diào)用具體的執(zhí)行函數(shù)。

/*++

Routine Description:
	This routine is the dispatch handler for the driver.  It is responsible
	for processing the IRPs.

Arguments:
	
	pDO - Pointer to device object.

	pIrp - Pointer to the current IRP.

Return Value:

	STATUS_SUCCESS if the IRP was processed successfully, otherwise an erroror
	indicating the reason for failure.

--*/
NTSTATUS OlsDispatch( 	IN	PDEVICE_OBJECT pDO,	IN	PIRP pIrp	)
{
	PIO_STACK_LOCATION pIrpStack;
	NTSTATUS status;
	int index;

	//  Initialize the irp info field.
	//	  This is used to return the number of bytes transfered.
	pIrp->IoStatus.Information = 0;
	pIrpStack = IoGetCurrentIrpStackLocation(pIrp);

	//  Set default return status
	status = STATUS_NOT_IMPLEMENTED;

	// Dispatch based on major fcn code.
	switch(pIrpStack->MajorFunction)
	{
		case IRP_MJ_CREATE:
			if(refCount != (ULONG)-1){refCount++;}
			status = STATUS_SUCCESS;
			break;
		case IRP_MJ_CLOSE:
			if(refCount != (ULONG)-1){refCount--;}
			status = STATUS_SUCCESS;
			break;

		case IRP_MJ_DEVICE_CONTROL:
			//  Dispatch on IOCTL
			switch(pIrpStack->Parameters.DeviceIoControl.IoControlCode)
			{
			case IOCTL_OLS_GET_DRIVER_VERSION:
				*(PULONG)pIrp->AssociatedIrp.SystemBuffer = OLS_DRIVER_VERSION;
				pIrp->IoStatus.Information = 4;
				status = STATUS_SUCCESS;
				break;

			case IOCTL_OLS_GET_REFCOUNT:
				*(PULONG)pIrp->AssociatedIrp.SystemBuffer = refCount;
				pIrp->IoStatus.Information = sizeof(refCount);
				status = STATUS_SUCCESS;
				break;

			case IOCTL_OLS_READ_MSR:
				status = ReadMsr(
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;
			case IOCTL_OLS_WRITE_MSR:
				status = WriteMsr(
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;
			case IOCTL_OLS_READ_PMC:
				status = ReadPmc(
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;
			case IOCTL_OLS_HALT:
				__halt();
				status = STATUS_SUCCESS;
				break;

			case IOCTL_OLS_READ_IO_PORT:
			case IOCTL_OLS_READ_IO_PORT_BYTE:
			case IOCTL_OLS_READ_IO_PORT_WORD:
			case IOCTL_OLS_READ_IO_PORT_DWORD:
				status = ReadIoPort(
					pIrpStack->Parameters.DeviceIoControl.IoControlCode,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;
			case IOCTL_OLS_WRITE_IO_PORT:
			case IOCTL_OLS_WRITE_IO_PORT_BYTE:
			case IOCTL_OLS_WRITE_IO_PORT_WORD:
			case IOCTL_OLS_WRITE_IO_PORT_DWORD:
				status = WriteIoPort(
					pIrpStack->Parameters.DeviceIoControl.IoControlCode,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;

			case IOCTL_OLS_READ_PCI_CONFIG:
				status = ReadPciConfig(
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;
			case IOCTL_OLS_WRITE_PCI_CONFIG:
				status = WritePciConfig(
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;

			case IOCTL_OLS_READ_MEMORY:
				status = ReadMemory(
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;
			case IOCTL_OLS_WRITE_MEMORY:
				status = WriteMemory(
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.InputBufferLength,
					pIrp->AssociatedIrp.SystemBuffer,
					pIrpStack->Parameters.DeviceIoControl.OutputBufferLength,
					(ULONG*)&pIrp->IoStatus.Information
					);
				break;


			}
			break;
	}

	// We're done with I/O request.  Record the status of the I/O action.
	pIrp->IoStatus.Status = status;

	// Don't boost priority when returning since this took little time.
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);

	return status;
}

??下面的代碼是具體每個case的實(shí)現(xiàn)部分,直接在注釋里面做介紹:

//-----------------------------------------------------------------------------
//
// CPU
//
//-----------------------------------------------------------------------------

NTSTATUS
ReadMsr(	void	*lpInBuffer, 
			ULONG	nInBufferSize, 
			void	*lpOutBuffer, 
			ULONG	nOutBufferSize, 
			ULONG	*lpBytesReturned)
{
	__try
	{
		//MSR是CPU的一組64位寄存器,可以分別通過RDMSR和WRMSR 兩條指令進(jìn)行讀和寫的操作。
		//__readmsr就是生成指令并執(zhí)行。此函數(shù)僅在內(nèi)核模式下可用,且對應(yīng)程序僅可用作內(nèi)部函數(shù),
		//這也就是為啥需要Ring0權(quán)限的原因。
		ULONGLONG data = __readmsr(*(ULONG*)lpInBuffer);
		memcpy((PULONG)lpOutBuffer, &data, 8);
		*lpBytesReturned = 8;
		return STATUS_SUCCESS;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		*lpBytesReturned = 0;
		return STATUS_UNSUCCESSFUL;
	}
}

NTSTATUS
WriteMsr(	void	*lpInBuffer, 
			ULONG	nInBufferSize, 
			void	*lpOutBuffer, 
			ULONG	nOutBufferSize, 
			ULONG	*lpBytesReturned)
{
	__try
	{
		//與上面的__readmsr類似
		OLS_WRITE_MSR_INPUT* param;
		param = (OLS_WRITE_MSR_INPUT*)lpInBuffer;

		__writemsr(param->Register, param->Value.QuadPart);
		*lpBytesReturned = 0;
		return STATUS_SUCCESS;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		*lpBytesReturned = 0;
		return STATUS_UNSUCCESSFUL;
	}
}

NTSTATUS
ReadPmc(	void	*lpInBuffer, 
			ULONG	nInBufferSize, 
			void	*lpOutBuffer, 
			ULONG	nOutBufferSize, 
			ULONG	*lpBytesReturned)
{
	__try
	{   //pmc 性能計數(shù)器
		ULONGLONG data = __readpmc(*(ULONG*)lpInBuffer);
		memcpy((PULONG)lpOutBuffer, &data, 8);
		*lpBytesReturned = 8;
		return STATUS_SUCCESS;
	}
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		*lpBytesReturned = 0;
		return STATUS_UNSUCCESSFUL;
	}
}
//-----------------------------------------------------------------------------
//
// IO Port IO口
//
//-----------------------------------------------------------------------------

NTSTATUS
ReadIoPort( ULONG	ioControlCode,
			void	*lpInBuffer, 
			ULONG	nInBufferSize, 
			void	*lpOutBuffer, 
			ULONG	nOutBufferSize, 
			ULONG	*lpBytesReturned)
{
	ULONG nPort = *(ULONG*)lpInBuffer;
	
	switch(ioControlCode)
	{
		case IOCTL_OLS_READ_IO_PORT_BYTE://從指定的端口地址讀取單個字節(jié)
			*(PUCHAR)lpOutBuffer = READ_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort);
			break;
		case IOCTL_OLS_READ_IO_PORT_WORD://從指定的端口地址讀取單個字
			*(PUSHORT)lpOutBuffer = READ_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort);
			break;
		case IOCTL_OLS_READ_IO_PORT_DWORD://從指定的端口地址讀取雙字節(jié)
			*(PULONG)lpOutBuffer = READ_PORT_ULONG((PULONG)(ULONG_PTR)nPort);
			break;
		default:
			*lpBytesReturned = 0;
			return STATUS_INVALID_PARAMETER;
			break;
	}
	
	*lpBytesReturned = nInBufferSize;
	return STATUS_SUCCESS;
}

NTSTATUS
WriteIoPort(ULONG	ioControlCode,
			void	*lpInBuffer, 
			ULONG	nInBufferSize, 
			void	*lpOutBuffer, 
			ULONG	nOutBufferSize, 
			ULONG	*lpBytesReturned)
{
	ULONG nPort;
	OLS_WRITE_IO_PORT_INPUT* param;
	
	param = (OLS_WRITE_IO_PORT_INPUT*)lpInBuffer;
	nPort = param->PortNumber;

	switch(ioControlCode)
	{

		case IOCTL_OLS_WRITE_IO_PORT_BYTE:
			WRITE_PORT_UCHAR((PUCHAR)(ULONG_PTR)nPort, param->CharData);
			break;
		case IOCTL_OLS_WRITE_IO_PORT_WORD:
			WRITE_PORT_USHORT((PUSHORT)(ULONG_PTR)nPort, param->ShortData);
			break;
		case IOCTL_OLS_WRITE_IO_PORT_DWORD:
			WRITE_PORT_ULONG((PULONG)(ULONG_PTR)nPort, param->LongData);
			break;
		default:
			return STATUS_INVALID_PARAMETER;
			break;
	}

	return STATUS_SUCCESS;
}
//-----------------------------------------------------------------------------
//
// PCI
//
//-----------------------------------------------------------------------------

NTSTATUS
ReadPciConfig(	void	*lpInBuffer, 
				ULONG	nInBufferSize, 
				void	*lpOutBuffer, 
				ULONG	nOutBufferSize, 
				ULONG	*lpBytesReturned)
{
	OLS_READ_PCI_CONFIG_INPUT *param;
	NTSTATUS status;

	if(nInBufferSize != sizeof(OLS_READ_PCI_CONFIG_INPUT))
	{
		return STATUS_INVALID_PARAMETER;
	}
	param = (OLS_READ_PCI_CONFIG_INPUT *)lpInBuffer;

	status = pciConfigRead(param->PciAddress, param->PciOffset,
						lpOutBuffer, nOutBufferSize);//最終調(diào)用的是HalGetBusDataByOffset,這是硬件抽象層函數(shù),獲取總線數(shù)據(jù)

	if(status == STATUS_SUCCESS)
	{
		*lpBytesReturned = nOutBufferSize;
	}
	else
	{
		*lpBytesReturned = 0;
	}

	return status;
}

NTSTATUS
WritePciConfig(	void *lpInBuffer, 
				ULONG nInBufferSize, 
				void *lpOutBuffer, 
				ULONG nOutBufferSize, 
				ULONG *lpBytesReturned)

{
	OLS_WRITE_PCI_CONFIG_INPUT *param;
	ULONG writeSize;
	NTSTATUS status;

	if(nInBufferSize < offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data))
	{
		return STATUS_INVALID_PARAMETER;
	}

	param = (OLS_WRITE_PCI_CONFIG_INPUT *)lpInBuffer;
	writeSize = nInBufferSize - offsetof(OLS_WRITE_PCI_CONFIG_INPUT, Data);
	
	*lpBytesReturned = 0;

	return pciConfigWrite(param->PciAddress, param->PciOffset,
							&param->Data, writeSize);

}

//-----------------------------------------------------------------------------
//
// Support Function
//
//-----------------------------------------------------------------------------

NTSTATUS pciConfigRead(ULONG pciAddress, ULONG offset, void *data, int length)
{
	PCI_SLOT_NUMBER slot;
	int error;
	ULONG busNumber;

	busNumber = PciGetBus(pciAddress);
	slot.u.AsULONG = 0;
	slot.u.bits.DeviceNumber = PciGetDev(pciAddress);
	slot.u.bits.FunctionNumber = PciGetFunc(pciAddress);
	error =	HalGetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG,
									data, offset, length);

	if(error == 0)
	{
		return OLS_ERROR_PCI_BUS_NOT_EXIST;
	}
	else if(length != 2 && error == 2)
	{
		return OLS_ERROR_PCI_NO_DEVICE;
	}
	else if(length != error)
	{
		return OLS_ERROR_PCI_READ_CONFIG;
	}

	return STATUS_SUCCESS;
}

NTSTATUS pciConfigWrite(ULONG pciAddress, ULONG offset, void *data, int length)
{
	PCI_SLOT_NUMBER slot;
	int error;
	ULONG busNumber;

	busNumber = PciGetBus(pciAddress);

	slot.u.AsULONG = 0;
	slot.u.bits.DeviceNumber = PciGetDev(pciAddress);
	slot.u.bits.FunctionNumber = PciGetFunc(pciAddress);
	error = HalSetBusDataByOffset(PCIConfiguration, busNumber, slot.u.AsULONG,
									data, offset, length);

	if(error != length)
	{
		return OLS_ERROR_PCI_WRITE_CONFIG;
	}

	return STATUS_SUCCESS;
}

//-----------------------------------------------------------------------------
//
// Physical Memory
//
//-----------------------------------------------------------------------------

NTSTATUS
ReadMemory(	void	*lpInBuffer, 
			ULONG	nInBufferSize, 
			void	*lpOutBuffer, 
			ULONG	nOutBufferSize, 
			ULONG	*lpBytesReturned)
{
	OLS_READ_MEMORY_INPUT *param;
	ULONG	size;
	PHYSICAL_ADDRESS address;
	PVOID	maped;
	BOOLEAN	error;

	if(nInBufferSize != sizeof(OLS_READ_MEMORY_INPUT))
	{
		return STATUS_INVALID_PARAMETER;
	}

	param = (OLS_READ_MEMORY_INPUT *)lpInBuffer;
	size = param->UnitSize * param->Count;

	if(nOutBufferSize < size)
	{
		return STATUS_INVALID_PARAMETER;
	}

	address.QuadPart = param->Address.QuadPart;

#ifndef _PHYSICAL_MEMORY_SUPPORT

	if(0x000C0000 > address.QuadPart 
	|| (address.QuadPart + size - 1) > 0x000FFFFF)
	{
		return STATUS_INVALID_PARAMETER;
	}

#endif

	maped = MmMapIoSpace(address, size, FALSE);//把物理地址 轉(zhuǎn)為虛擬地址,比如我們要讀取物理地址為100的一個字節(jié)數(shù)據(jù),
	//其通過系統(tǒng)被映射到虛擬內(nèi)存的地址是200,那我們就通過讀虛擬內(nèi)存的200位置來實(shí)現(xiàn)

	error = FALSE;
	switch(param->UnitSize){
		case 1:
			READ_REGISTER_BUFFER_UCHAR(maped, lpOutBuffer, param->Count);//從虛擬地址里間接讀物理地址的信息
			break;
		case 2:
			READ_REGISTER_BUFFER_USHORT(maped, lpOutBuffer, param->Count);
			break;
		case 4:
			READ_REGISTER_BUFFER_ULONG(maped, lpOutBuffer, param->Count);
			break;
		default:
			error = TRUE;
			break;
	}

	MmUnmapIoSpace(maped, size);

	if(error)
	{
		return STATUS_INVALID_PARAMETER;
	}

	*lpBytesReturned = nOutBufferSize;

	return STATUS_SUCCESS;
}

NTSTATUS
WriteMemory(void	*lpInBuffer, 
			ULONG	nInBufferSize, 
			void	*lpOutBuffer, 
			ULONG	nOutBufferSize, 
			ULONG	*lpBytesReturned)
{
#ifdef _PHYSICAL_MEMORY_SUPPORT

	OLS_WRITE_MEMORY_INPUT *param;
	ULONG size;
	PHYSICAL_ADDRESS address;
	PVOID	maped;
	BOOLEAN	error;

	if(nInBufferSize < offsetof(OLS_WRITE_MEMORY_INPUT, Data))
	{
		return STATUS_INVALID_PARAMETER;
	}

	param = (OLS_WRITE_MEMORY_INPUT *)lpInBuffer;

	size = param->UnitSize * param->Count;
	if (nInBufferSize < size + offsetof(OLS_WRITE_MEMORY_INPUT, Data))
	{
		return STATUS_INVALID_PARAMETER;
	}

	address.QuadPart = param->Address.QuadPart;

	maped = MmMapIoSpace(address, size, FALSE);

	error = FALSE;
	switch(param->UnitSize){
		case 1:
			WRITE_REGISTER_BUFFER_UCHAR(maped, 
										(UCHAR*)&param->Data, param->Count);
			break;
		case 2:
			WRITE_REGISTER_BUFFER_USHORT(maped,
										(USHORT*)&param->Data, param->Count);
			break;
		case 4:
			WRITE_REGISTER_BUFFER_ULONG(maped,
										(ULONG*)&param->Data, param->Count);
			break;
		default:
			error = TRUE;
			break;
	}

	MmUnmapIoSpace(maped, size);

	if(error)
	{
		return STATUS_INVALID_PARAMETER;
	}

	*lpBytesReturned = 0;

	return STATUS_SUCCESS;

#else

	*lpBytesReturned = 0;
	
	return STATUS_INVALID_PARAMETER;

#endif
}

3、驅(qū)動卸載函數(shù)

??實(shí)際的卸載工作被IRP_MN_REMOVE_DEVICE對應(yīng)的派發(fā)函數(shù)處理了,不需要自己實(shí)現(xiàn)。這里的DriverUnload主要處理在DriverEntry中申請的內(nèi)存,也就是“new”出的“win32NameString”。文章來源地址http://www.zghlxwxcb.cn/news/detail-627952.html

/*++

Routine Description:

	This routine is called by the I/O system to unload the driver.

	Any resources previously allocated must be freed.

Arguments:

	DriverObject - a pointer to the object that represents our driver.

Return Value:

	None
--*/
VOID Unload(	PDRIVER_OBJECT DriverObject	)
{
	PDEVICE_OBJECT deviceObject = DriverObject->DeviceObject;
	UNICODE_STRING win32NameString;

	PAGED_CODE();

	// Create counted string version of our Win32 device name.
	RtlInitUnicodeString(&win32NameString, DOS_DEVICE_NAME);

	// Delete the link from our device name to a name in the Win32 namespace.
	IoDeleteSymbolicLink(&win32NameString);

	if(deviceObject != NULL)
	{
		IoDeleteDevice(deviceObject);
	}
}

革命尚未成功,以上只是.sys驅(qū)動的代碼實(shí)現(xiàn),主要目的是獲取Ring0權(quán)限,為了給開發(fā)者使用,需要做一個DLL提供對外的接口。請參閱第二篇。。。

到了這里,關(guān)于第一篇 windows驅(qū)動之WinRing0.sys的開發(fā)及使用(電腦溫度監(jiān)控軟件開發(fā))的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 【Spring進(jìn)階系列丨第一篇】初識Spring開發(fā)

    【Spring進(jìn)階系列丨第一篇】初識Spring開發(fā)

    小伙伴們大家好,我是陳橘又青,今天起 《Spring進(jìn)階系列》 開始更新。本專欄將涵蓋Spring框架的核心概念、配置管理、Web開發(fā)、AOP、Boot、Security、Data、Integration和Batch等多個主題。通過理論講解和實(shí)際案例的剖析,幫助讀者深入理解Spring框架的原理和應(yīng)用技巧,提升開發(fā)人員

    2024年02月05日
    瀏覽(16)
  • 記錄第一篇被”華為開發(fā)者聯(lián)盟鴻蒙專區(qū) “收錄的文章

    記錄第一篇被”華為開發(fā)者聯(lián)盟鴻蒙專區(qū) “收錄的文章

    記錄第一篇被”華為開發(fā)者聯(lián)盟鴻蒙專區(qū)?“社區(qū)收錄的文章。 堅持寫作的動力是什么? 是記錄、分享,以及更好的思考?。 ?

    2024年02月14日
    瀏覽(22)
  • 第一篇【傳奇開心果系列】beeware開發(fā)移動應(yīng)用:輪盤抽獎移動應(yīng)用

    第一篇【傳奇開心果系列】beeware開發(fā)移動應(yīng)用:輪盤抽獎移動應(yīng)用

    一、項(xiàng)目目標(biāo) 使用beeware的toga寫傳奇開心果輪盤抽獎安卓手機(jī)應(yīng)用和蘋果手機(jī)應(yīng)用 二、開發(fā)傳奇開心果輪盤抽獎安卓應(yīng)用編程思路 要使用Beeware的Toga庫來編寫一個傳奇開心果輪盤抽獎安卓應(yīng)用,你需要按照以下步驟進(jìn)行操作: 安裝Beeware:首先,你需要安裝Beeware的開發(fā)工具包

    2024年01月20日
    瀏覽(95)
  • 【SpringBoot】第一篇:redis使用

    【SpringBoot】第一篇:redis使用

    背景: 本文是教初學(xué)者如何正確使用和接入redis。 ? ? 好了,到此處就已經(jīng)介紹完畢了! 如果有什么問題可以問博主的,可以在底下進(jìn)行留言,看到一定回復(fù)你們。

    2024年02月11日
    瀏覽(22)
  • 第一篇 香橙派刷機(jī)和開發(fā)環(huán)境準(zhǔn)備(ubuntu20.04版)

    第一篇 香橙派刷機(jī)和開發(fā)環(huán)境準(zhǔn)備(ubuntu20.04版)

    目錄 一、香橙派刷ubuntu系統(tǒng)和SSH登錄 1.Ubuntu有趣的Codename 2.刷機(jī)步驟(ubuntu20.04) ??格式化TF卡 ??燒寫系統(tǒng)到TF卡 ??調(diào)試串口登陸系統(tǒng) ??SSH登陸系統(tǒng) ?二、開發(fā)環(huán)境準(zhǔn)備 1.香橙派ubuntu20.04換源 2.VNC遠(yuǎn)程連接香橙派 (1)安裝VNC服務(wù) (2)VNC連接香橙派 3.安裝wiringPi (1)安裝

    2023年04月21日
    瀏覽(81)
  • 手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第一篇

    手把手教你區(qū)塊鏈java開發(fā)智能合約nft-第一篇

    剛接觸區(qū)塊鏈開發(fā),使用java開發(fā),真的是太難了,自己一步步摸索,從新手小白一路碰壁,動不動就報錯,去網(wǎng)上搜索對應(yīng)錯誤,還真什么都搜索不到,摸索了三四個月,今天終于有了一些進(jìn)展,今天開始分享出來,希望能幫助到需要的朋友 我作為一個java后端的程序員,不

    2024年01月23日
    瀏覽(27)
  • 【第一篇:簡介關(guān)于OpenAI的使用】

    其實(shí)以上都不是我寫的,都是chat-GPT自己寫的,真的很神奇!

    2024年02月04日
    瀏覽(20)
  • AI大模型時代下運(yùn)維開發(fā)探索第一篇:ReAct工程初探

    AI大模型時代下運(yùn)維開發(fā)探索第一篇:ReAct工程初探

    人工智能大模型的出現(xiàn),已漸漸地影響了我們的日常生活和工作方式。生活中無處不在的AI,使我們的生活變得更加智能和便捷。工作中,AI大模型的高效和精準(zhǔn),極大地提升了我們解決問題的效率。 是的,我們不能忽視AI大模型對運(yùn)維開發(fā)的巨大影響和潛力。本系列文章旨在

    2024年02月16日
    瀏覽(16)
  • 【標(biāo)準(zhǔn)解讀】Autosar 復(fù)雜驅(qū)動(CDD)開發(fā)--看這一篇就夠了

    【標(biāo)準(zhǔn)解讀】Autosar 復(fù)雜驅(qū)動(CDD)開發(fā)--看這一篇就夠了

    最近看到有朋友提問,“復(fù)雜驅(qū)動和Linux驅(qū)動有啥區(qū)別?” 看到幾個回答挺好的,“Linux驅(qū)動是真正的驅(qū)動,復(fù)雜驅(qū)動只是在autosar范疇的說法,內(nèi)容不一定是驅(qū)動,可能同時包含底層、算法、應(yīng)用層等其他東西” 簡而言之,沒辦法統(tǒng)一標(biāo)準(zhǔn)的東西,都放在復(fù)雜驅(qū)動了;例如功

    2024年02月03日
    瀏覽(25)
  • Hadoop生態(tài)圈實(shí)戰(zhàn)系列:第一篇 Hadoop 集群安裝及使用詳解

    作者:禪與計算機(jī)程序設(shè)計藝術(shù) Apache Hadoop 是一款開源的、分布式文件系統(tǒng)和計算平臺。它由 Apache 基金會開發(fā),并于 2011 年成為 Apache 頂級項(xiàng)目之一。Hadoop 的主要特性包括: 分布式存儲: Hadoop 允許將數(shù)據(jù)存儲在多個服務(wù)器上,在同一個集群中,并提供高容錯性和可靠性。

    2024年02月08日
    瀏覽(22)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包