⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sector_io.c

📁 一个基于Windows系统( NT5.0
💻 C
字号:
/*=============================================================================
	FILE			 : sector_io.c 
	ABSTRACT		 : User application sending data to kernel driver which reads/writes
					directly on disk sectors
	AUTHOR		 : Deepak Gupta
     
	Thanks to Chew Keong TAN because some of the driver laoding and unloading functions
	are taken frome there
   				
=============================================================================*/
// sector_io.c : Defines the entry point for the console application.
//

#include "sector_io.h"

#define	DRV_NAME	"sectorio"
#define DRV_FILENAME	"sectorio.sys"

#define SECTOR_IO_DEVICE       0x8000

#define IOCTL_SECTOR_READ		CTL_CODE(SECTOR_IO_DEVICE, 0x800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_SECTOR_WRITE		CTL_CODE(SECTOR_IO_DEVICE, 0x801, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)
#define IOCTL_GET_SECTOR_SIZE	CTL_CODE(SECTOR_IO_DEVICE, 0x802, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

BOOL getLoadDriverPriv()
{
	HANDLE hToken;
	LUID huid;
	LUID_AND_ATTRIBUTES priv;
	TOKEN_PRIVILEGES tp;

	if(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY | TOKEN_ADJUST_PRIVILEGES, &hToken))
	{

		if(LookupPrivilegeValueA(NULL, "SeLoadDriverPrivilege", &huid))
		{
			priv.Attributes = SE_PRIVILEGE_ENABLED;
			priv.Luid = huid;
			
			tp.PrivilegeCount = 1;
			tp.Privileges[0] = priv;

			if(AdjustTokenPrivileges(hToken, FALSE, &tp, 0, NULL, NULL))
			{
				return TRUE;
			}
		}
	}
	return FALSE;
}

BOOL setupRegistry()
{
	HKEY hkey;
	DWORD val;
	char *imgName = "System32\\DRIVERS\\"DRV_FILENAME;

	if(RegCreateKeyA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"DRV_NAME, &hkey) != ERROR_SUCCESS)
		return FALSE;

	
	val = 1;
	if(RegSetValueExA(hkey, "Type", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
		return FALSE;

	if(RegSetValueExA(hkey, "ErrorControl", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
		return FALSE;
	
	val = 3;
	if(RegSetValueExA(hkey, "Start", 0, REG_DWORD, (PBYTE)&val, sizeof(val)) != ERROR_SUCCESS)
		return FALSE;

	
	if(RegSetValueExA(hkey, "ImagePath", 0, REG_EXPAND_SZ, (PBYTE)imgName, strlen(imgName)) != ERROR_SUCCESS)
		return FALSE;

	return TRUE;
}

BOOL loadDriver()
{
	// call ntdll APIs
	HMODULE hntdll;
	ANSI_STRING aStr;
	UNICODE_STRING uStr;

	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 = GetModuleHandleA("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)
	{
		_RtlInitAnsiString(&aStr, 
		"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"DRV_NAME);
						
		if(_RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS)
			return FALSE;
		else
		{
			if(_ZwLoadDriver(&uStr) == STATUS_SUCCESS)
			{
				_RtlFreeUnicodeString(&uStr);
				return TRUE;
			}
			_RtlFreeUnicodeString(&uStr);
		}
	}

	return FALSE;
}

void cleanupDriver(void)
{
	char sysDir[MAX_PATH + 1];
	GetSystemDirectoryA(sysDir, MAX_PATH);
	strncat(sysDir, "\\drivers\\"DRV_FILENAME, MAX_PATH);
	DeleteFileA(sysDir);

	RegDeleteKeyA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"DRV_NAME"\\Enum");
	RegDeleteKeyA(HKEY_LOCAL_MACHINE, "System\\CurrentControlSet\\Services\\"DRV_NAME);
}

BOOL unloadDriver()
{
	// call ntdll APIs
	HMODULE hntdll;
	ANSI_STRING aStr;
	UNICODE_STRING uStr;

	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 = GetModuleHandleA("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)
	{

		_RtlInitAnsiString(&aStr, 
		"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"DRV_NAME);
						
		if(_RtlAnsiStringToUnicodeString(&uStr, &aStr, TRUE) != STATUS_SUCCESS)
			return FALSE;
		else
		{
			if(_ZwUnloadDriver(&uStr) == STATUS_SUCCESS)
			{
				_RtlFreeUnicodeString(&uStr);
				return TRUE;
			}
			_RtlFreeUnicodeString(&uStr);
		}
	}

	return FALSE;
}


void uninstallDriver(void)
{
	char drvFullPath[MAX_PATH+1];
	char *filePart;
	HANDLE hFile;
	char sysDir[MAX_PATH + 1];

	ZeroMemory(drvFullPath, MAX_PATH);		
	GetFullPathNameA(DRV_FILENAME, MAX_PATH, drvFullPath, &filePart);

	hFile= CreateFileA(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\n", drvFullPath);
		return;
	}
	else
	{
		CloseHandle(hFile);

		GetSystemDirectoryA(sysDir, MAX_PATH);
		strncat(sysDir, "\\drivers\\"DRV_FILENAME, MAX_PATH);
		CopyFileA(drvFullPath, sysDir, TRUE);

		if(!getLoadDriverPriv())
		{
			printf("Error getting load driver privilege!\n");
		}
		else
		{
			if(!setupRegistry())
			{
				printf("Error setting driver registry keys!\nMake sure you are running this as Administrator.\n");
			}
			else
			{
				if(unloadDriver())
					printf("Support driver successfully unloaded.\n");
				else
					printf("Unload support driver failed.  It is probably not loaded.\n");
			}
		}
		cleanupDriver();
	}
}

HANDLE openDriver(void)
{
	HANDLE hDevice;
	HANDLE hFile;
	char drvFullPath[MAX_PATH+1];
	char *filePart;
	char sysDir[MAX_PATH + 1];

	hDevice = CreateFileA("\\\\.\\"DRV_NAME, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE,
		   				 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);

	if(hDevice == INVALID_HANDLE_VALUE)
	{		


		ZeroMemory(drvFullPath, MAX_PATH);		
		GetFullPathNameA(DRV_FILENAME, MAX_PATH, drvFullPath, &filePart);
		
		hFile= CreateFileA(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\n", drvFullPath);
			return INVALID_HANDLE_VALUE;
		}
		else
		{
			CloseHandle(hFile);

			GetSystemDirectoryA(sysDir, MAX_PATH);
			strncat(sysDir, "\\drivers\\"DRV_FILENAME, MAX_PATH);
			CopyFileA(drvFullPath, sysDir, TRUE);

			if(!getLoadDriverPriv())
			{
				printf("Error getting load driver privilege!\n");
			}
			else
			{
				if(!setupRegistry())
				{
					printf("Error setting driver registry keys!\nMake sure you are running this as Administrator.\n");
				}
				else
				{
					loadDriver();
					hDevice = CreateFileA("\\\\.\\"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!\nMake sure you are running this as Administrator.\n");
					}
				}
			}
			cleanupDriver();
		}
	}
	
	return hDevice;
}

DWORD DoDeviceIoCtl(DWORD dwIoCtl, DWORD dwDiskObjOrdinal, 
					BOOLEAN bIsRawDisk, ULONGLONG ullSectorNumber, PVOID *pBuf)
{
	CHAR	szDriverPath[MAX_PATH];
	HANDLE	hDevice;
	DWORD	dwStatus, Size = 512, Bytes;
	DISK_LOCATION	dlInfo;
	PVOID	pMem = NULL;
	PBYTE	pByte;
	OFSTRUCT	ofReOpenBuff;
	DWORD		i;
	char	c;

	hDevice = openDriver();

	if (hDevice == INVALID_HANDLE_VALUE) {
		printf("Can't Open Driver\n");
	}

	dlInfo.bIsRawDiskObj = bIsRawDisk;
	dlInfo.dwDiskOrdinal = dwDiskObjOrdinal;
	dlInfo.ullSectorNum  = ullSectorNumber;
	

	do
	{
		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			Size += sizeof(DISK_LOCATION);
		}

		pMem = malloc(Size);

		// A very ugly hack to transfer disk location data and input buffer both for write operations
		// Came to know about bug of write operations very late, So instead of handling mapping user address into kernel
		// address space, I did this hack, Will fix it in future
	
		if (!pMem)
			return ERROR_NOT_ENOUGH_MEMORY;

		memset(pMem, 0x00, Size);
		
		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			pByte = (PBYTE) ((ULONG)pMem + sizeof(DISK_LOCATION));
			i = 0;
			printf("Please type the data you want to write to the sector (input redirection is a better option)\nInput Data: \n");

			do{
				c = getc(stdin);
				pByte[i] = c;
				i++;
			}while ((i < Size) && (c != EOF));
		}
		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			memcpy(pMem, &dlInfo, sizeof(dlInfo));
			if(DeviceIoControl(hDevice, dwIoCtl, pMem, Size, NULL, 0, &Bytes, NULL))
				break;
		} else {
			if(DeviceIoControl(hDevice, dwIoCtl, &dlInfo, sizeof(dlInfo), pMem, Size, &Bytes, NULL))
				break;
		}
		
		dwStatus = GetLastError();
		printf ("DeviceIoControl Failed and error code is %d\n", dwStatus);

		if (dwIoCtl == IOCTL_SECTOR_WRITE) {
			Size -= sizeof(DISK_LOCATION);
		}
		free(pMem);
		pMem = NULL;
		Size = Size * 2;
	}while(dwStatus == ERROR_INSUFFICIENT_BUFFER);

	if (dwIoCtl == IOCTL_SECTOR_READ && pMem) {
		pByte = (PBYTE) pMem;
		i = 0;
		c = 0;
		printf("Displaying the data read from the sector (in hexadecimal, output redirection can also work)\nOutput Data: \n");
		do{
			c = pByte[i];
			//putc(c, stdout);
			printf("0x%-02X ", c & 0x00FFUL);

			if (!(i+1)%0x10) {
				printf ("\n");
			}
			i++;
		}while (i < Size);
	}

	*pBuf = pMem;
	return Size;
}
VOID PrintUsage()
{
	printf("Usage is:\n"
		"DiskSector {/disk | /partition} <rawdisk number | partition number> " 
		"{/read | /write} <sectornumber> {/unload}\n"
		"\n{/disk | /partition} <rawdisk number | partition number>\n"
		"Disk and Parition options are mutually exclusive\n"
		"Disk numbering starts from 0 while partition starts from 1\n"
		"\n{/read | /write} <sectornumber>\n"
		"Read and Write options are mutually exclusive\n"
		"Sector numbering starts from 0\n"
		"\n{/unload} \nThis option simply unloads the support driver\n"
		"\ne.g \"DiskSector /disk 0 /read 0\" will read raw sector 0 of harddisk 0\n");
	return;
}

int __cdecl main(int argc, char* argv[])
{
	int			argIndex;
	BOOLEAN		bIsRawDisk, bReadWrite, bLoadDriver = TRUE;
	DWORD		dwDiskObjOrdinal = -1;
	ULONGLONG	ullSectorNumber = -1;
	DWORD		dwSize = 512;
	PVOID		pBuf = NULL;

	
	if( argc < 2 || strcmp(argv[1], "/?") == 0 ) {
        PrintUsage();
        return (0);
    }

	argIndex = 1;

	for (argIndex = 1; argIndex < argc; argIndex++)
	{
		if (!strcmp(argv[argIndex], "/disk") || !strcmp(argv[argIndex], "/partition")) {
			if (dwDiskObjOrdinal == -1) {
				bIsRawDisk = strcmp(argv[argIndex], "/disk") ? FALSE : TRUE;
				argIndex++;
				if (argIndex < argc) {
					char *endptr;
					dwDiskObjOrdinal = strtoul(argv[argIndex], &endptr, 10);
				} else {
					PrintUsage();
					return -1;
				}
			} else {
				PrintUsage();
				return -1;
			}
		} else if (!strcmp(argv[argIndex], "/read") || !strcmp(argv[argIndex], "/write")) {
			if (ullSectorNumber == -1) {
				bReadWrite = strcmp(argv[argIndex], "/read") ? FALSE : TRUE;
				argIndex++;
				if (argIndex < argc) {
					char *endptr;
					ullSectorNumber = _strtoui64(argv[argIndex], &endptr, 10);
				}
			} else {
				PrintUsage();
				return -1;
			}

		} else if (!strcmp(argv[argIndex], "/unload")) {
			bLoadDriver = FALSE;
		} else {
			PrintUsage();
			return -1;
		}
	}

	if (!bLoadDriver) {
		uninstallDriver();
		return 0;
	} else if (dwDiskObjOrdinal == -1 || ullSectorNumber == -1){
		PrintUsage();
		return -1;

	}

	DoDeviceIoCtl(bReadWrite?IOCTL_SECTOR_READ:IOCTL_SECTOR_WRITE, 
				dwDiskObjOrdinal, bIsRawDisk, ullSectorNumber, &pBuf);
	if (!pBuf)
		free(pBuf);

	return 0;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -