实现UNC转本地路径

以为学长写的:

其中有两个功能挺好用的

//实现 strchr功能 返回chr出现的位置
WCHAR * RtlUnicodeStringChr(PUNICODE_STRING IN pStr, WCHAR chr);
//实现strstr功能  返回pStrDst首次初夏你的位置
WCHAR * RtlUnicodeStringStr(PUNICODE_STRING IN pStr, PUNICODE_STRING pStrDst);

WCHAR * RtlUnicodeStringChr(PUNICODE_STRING IN pStr, WCHAR chr)
{
	ULONG i = 0;
	ULONG uSize = pStr->Length >> 1;

	for (i=0; i<uSize; i++)
	{
		if (pStr->Buffer[i] == chr)
		{
			return pStr->Buffer + i;
		}
	}

	return NULL;
}

WCHAR * RtlUnicodeStringStr(PUNICODE_STRING IN pSource, PUNICODE_STRING IN pStrDst)
{
	ULONG i = 0;
	ULONG uLengthSetp = 0;
	ULONG uLengthSrc = 0;
	ULONG uLengthDst = 0;
	UNICODE_STRING str1 = {0};
	UNICODE_STRING str2 = {0};

	uLengthSrc = pSource->Length;
	uLengthDst = pStrDst->Length;
	
	if (uLengthSrc < uLengthDst)
	{
		return NULL;
	}
	
	uLengthSetp = ((uLengthSrc - uLengthDst) >> 1) + 1;
	for (i=0; i<uLengthSetp; i++)
	{
		str1.Length = str1.MaximumLength = (USHORT)uLengthDst;
		str2.Length = str2.MaximumLength = (USHORT)uLengthDst;
		str1.Buffer = pSource->Buffer+i;
		str2.Buffer = pStrDst->Buffer;

		if ( 0 == RtlCompareUnicodeString(&str1, &str2, TRUE))
		{
			return pSource->Buffer + i;
		}
	}
	return NULL;
}


/*

实现Unc路径 转换成本地路径。
UNC (Universal Naming Convention)  通用命名规则
\\servername\sharename\directory\filename
SharedDocs\\hi.txt  ->  D:\\Docs\\hi.txt
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares

by kyle
*/

//#define MyPrint
#define MyPrint DbgPrint

#include <ntifs.h>
#include <ntimage.h>
#include <string.h>
#include <ntstrsafe.h>

#include <wdm.h>

#include <ntddk.h>

#ifndef MAX_PATH
#define MAX_PATH 260
#endif

#define SAFE_MAX_PATH  (MAX_PATH+64)

#define MEM_TAG		('kyle')

VOID UnloadDriver(PDRIVER_OBJECT pDriverObject)
{

}
//实现 strchr功能
WCHAR * RtlUnicodeStringChr(PUNICODE_STRING IN pStr, WCHAR chr);
//实现strstr功能
WCHAR * RtlUnicodeStringStr(PUNICODE_STRING IN pStr, PUNICODE_STRING pStrDst);


//SharedDocs\\111.txt -> c:\\document and settings\\ Documents\\111.txt
//这里木有校验文件是否存在 只是根据注册表转换路径
NTSTATUS Unc2Local(PUNICODE_STRING IN pstrUnc, PUNICODE_STRING OUT pstrLocal);

NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pReg)
{
	NTSTATUS					status = STATUS_UNSUCCESSFUL;
	DECLARE_UNICODE_STRING_SIZE(strUnc, SAFE_MAX_PATH);
	DECLARE_UNICODE_STRING_SIZE(strLocal, SAFE_MAX_PATH);
	RtlInitUnicodeString(&strUnc, L"SharedDocs\\111.txt");
	if (STATUS_SUCCESS == Unc2Local(&strUnc, &strLocal))
	{
		MyPrint("本地路径:%wZ \n", &strLocal);
	}
	else
	{
		MyPrint("出错鸟。\n");
	}

	pDriverObject->DriverUnload = UnloadDriver;
	return STATUS_SUCCESS;
}

WCHAR * RtlUnicodeStringChr(PUNICODE_STRING IN pStr, WCHAR chr)
{
	ULONG i = 0;
	ULONG uSize = pStr->Length >> 1;

	for (i=0; i<uSize; i++)
	{
		if (pStr->Buffer[i] == chr)
		{
			return pStr->Buffer + i;
		}
	}

	return NULL;
}

WCHAR * RtlUnicodeStringStr(PUNICODE_STRING IN pSource, PUNICODE_STRING IN pStrDst)
{
	ULONG i = 0;
	ULONG uLengthSetp = 0;
	ULONG uLengthSrc = 0;
	ULONG uLengthDst = 0;
	UNICODE_STRING str1 = {0};
	UNICODE_STRING str2 = {0};

	uLengthSrc = pSource->Length;
	uLengthDst = pStrDst->Length;
	
	if (uLengthSrc < uLengthDst)
	{
		return NULL;
	}
	
	uLengthSetp = ((uLengthSrc - uLengthDst) >> 1) + 1;
	for (i=0; i<uLengthSetp; i++)
	{
		str1.Length = str1.MaximumLength = (USHORT)uLengthDst;
		str2.Length = str2.MaximumLength = (USHORT)uLengthDst;
		str1.Buffer = pSource->Buffer+i;
		str2.Buffer = pStrDst->Buffer;

		if ( 0 == RtlCompareUnicodeString(&str1, &str2, TRUE))
		{
			return pSource->Buffer + i;
		}
	}
	return NULL;
}


//SharedDocs\\111.txt -> C:\\Documents and Settings\\All Users\\Documents\\111.txt
NTSTATUS Unc2Local(PUNICODE_STRING IN pstrUnc, PUNICODE_STRING OUT pstrLocal)
{
	NTSTATUS						status = STATUS_UNSUCCESSFUL;
	OBJECT_ATTRIBUTES		objectAttr = {0};
	HANDLE							hRegister = NULL;
	UNICODE_STRING			ustrReg = {0};
	ULONG							uResult = 0;
	WCHAR							*pTmp = NULL;
	DECLARE_UNICODE_STRING_SIZE(strShare, SAFE_MAX_PATH);
	DECLARE_UNICODE_STRING_SIZE(strName, SAFE_MAX_PATH);
	PKEY_VALUE_PARTIAL_INFORMATION pkpi = NULL;
	
	pTmp = RtlUnicodeStringChr(pstrUnc, L'\\');
	if (NULL == pTmp)
	{
		status = STATUS_INVALID_PARAMETER;
		return status;
	}
	
	//取 SharedDocs
	strShare.Length = (USHORT)((ULONG)pTmp - (ULONG)pstrUnc->Buffer);
	RtlCopyMemory(strShare.Buffer, pstrUnc->Buffer, strShare.Length);

	//取 \\111.txt
	strName.Length = pstrUnc->Length - strShare.Length;
	RtlCopyMemory(strName.Buffer, pTmp, strName.Length);

	//查看 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\LanmanServer\Shares   
	//有木有 SharedDocs 字段

	RtlInitUnicodeString(&ustrReg, L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\LanmanServer\\Shares");
	InitializeObjectAttributes(&objectAttr,
		&ustrReg,
		OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
		NULL,
		NULL);

	status = ZwCreateKey( 
		&hRegister,
		KEY_ALL_ACCESS,
		&objectAttr,
		0,
		NULL,
		REG_OPTION_NON_VOLATILE,
		&uResult);

	if (!NT_SUCCESS(status))
	{
		goto __error;
	}

	status = ZwQueryValueKey(hRegister,
		&strShare,
		KeyValuePartialInformation,
		NULL,
		0,
		&uResult);

	//非法UNC路径
	if (status != STATUS_BUFFER_OVERFLOW &&
		status != STATUS_BUFFER_TOO_SMALL)
	{
		goto __error;
	}

	pkpi = 	(PKEY_VALUE_PARTIAL_INFORMATION)
		ExAllocatePoolWithTag(PagedPool, uResult, MEM_TAG);
	if (pkpi == NULL)
	{
		status = STATUS_MEMORY_NOT_ALLOCATED;
		goto __error;
	}

	status = ZwQueryValueKey(hRegister,
		&strShare,
		KeyValuePartialInformation,
		pkpi,
		uResult,
		&uResult);
	if (!NT_SUCCESS(status))
	{
		goto __error;
	}
	
	//类型必须是这个
	if (pkpi->Type != REG_MULTI_SZ)
	{
		goto __error;
	}
	//解析出Path=来
	ustrReg.Length = (USHORT)pkpi->DataLength;
	ustrReg.MaximumLength = (USHORT)pkpi->DataLength;
	ustrReg.Buffer = (WCHAR*)(pkpi->Data);

	RtlInitUnicodeString(&strShare, L"path=");
	pTmp = RtlUnicodeStringStr(&ustrReg, &strShare);
	if (NULL == pTmp)
	{
		status = STATUS_UNSUCCESSFUL;
		goto __error;
	}
	else
	{
		RtlInitUnicodeString(&strShare, pTmp + wcslen(L"path="));
		RtlCopyUnicodeString(pstrLocal, &strShare);
		RtlAppendUnicodeStringToString(pstrLocal, &strName);
		status = STATUS_SUCCESS;
	}

__error:
	if (pkpi)
	{
		ExFreePool(pkpi);
	}
	if (hRegister)
	{
		ZwClose(hRegister);
	}

	return status;
}


我自己实现的:

#include <ntddk.h>
#include <ntstrsafe.h>

#define REG_PATH "\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanServer\\Shares"

#define MAX_PATH 260

NTSTATUS RegQueryValue(LPWSTR KeyName, LPWSTR ValueName, PKEY_VALUE_PARTIAL_INFORMATION *pkvpi)
{
	ULONG ulSize;
	NTSTATUS ntStatus;
	PKEY_VALUE_PARTIAL_INFORMATION pvpi;
	OBJECT_ATTRIBUTES objectAttributes;
	HANDLE hRegister;
	UNICODE_STRING usKeyName;
	UNICODE_STRING usValueName;
	RtlInitUnicodeString(&usKeyName, KeyName);
	RtlInitUnicodeString(&usValueName, ValueName);

	InitializeObjectAttributes(&objectAttributes,
	                           &usKeyName,
	                           OBJ_CASE_INSENSITIVE,//对大小写敏感
	                           NULL,
	                           NULL );

	ntStatus = ZwOpenKey( &hRegister, KEY_ALL_ACCESS, &objectAttributes);

	if(!NT_SUCCESS(ntStatus))
	{
		DbgPrint("[RegQueryValueKey]ZwOpenKey failed!\n");
		return ntStatus;
	}

	ntStatus = ZwQueryValueKey(hRegister,
	                           &usValueName,
	                           KeyValuePartialInformation ,
	                           NULL,
	                           0,
	                           &ulSize);

	if (ntStatus== STATUS_OBJECT_NAME_NOT_FOUND)
	{
		DbgPrint("Name_Not_Found\n");
		return STATUS_OBJECT_NAME_NOT_FOUND;
	}

	if(ulSize==0)
	{
		DbgPrint("ZwQueryValueKey failed!\n");
		return STATUS_UNSUCCESSFUL;
	}

	pvpi = (PKEY_VALUE_PARTIAL_INFORMATION)ExAllocatePool(PagedPool,ulSize);

	ntStatus = ZwQueryValueKey(hRegister,
	                           &usValueName,
	                           KeyValuePartialInformation ,
	                           pvpi,
	                           ulSize,
	                           &ulSize);

	if (!NT_SUCCESS(ntStatus))
	{
		DbgPrint("ZwQueryValueKey 2 failed!\n");
		return STATUS_UNSUCCESSFUL;
	}
	//这里的pvpi是没有释放的用完要释放。ExFreePool(pvpi);
	*pkvpi=pvpi;
	DbgPrint("ZwQueryValueKey success!\n");
	return STATUS_SUCCESS;
}


/*
\\servername\sharename\directory\filename
*/
WCHAR* GetDirAndFileName(WCHAR* strUnc)
{
#define MAX_PATH 260
	int count = 0;
	WCHAR *pEnd = 0;
	int index = 0;
	WCHAR* temp = (WCHAR*)ExAllocatePool(PagedPool,MAX_PATH * sizeof(WCHAR));
	memset(temp,'\0',MAX_PATH * sizeof(WCHAR));

	pEnd = strUnc;

	while (*pEnd != '\0')
	{
		count++;
		if(*pEnd == '\\')
		{
			index ++;
			if(index == 4)
			{
				wcscpy(temp,pEnd);
				return temp;
			}
		}	
		pEnd++;
	}
	return temp;
}

WCHAR* AppendWchar(WCHAR* str1, WCHAR *str2)
{
	WCHAR* resule = (WCHAR*)ExAllocatePool(PagedPool,260*2);
	memset(resule,'\0',260*2);

	wcsncpy(resule,str1,wcslen(str1));
	wcsncpy(resule+wcslen(str1),str2,wcslen(str2));
	return resule;

}

WCHAR* GetShareName(WCHAR* strUnc)
{
#define MAX_PATH 260
	WCHAR* pEntry = 0;
	WCHAR* pEnd = 0;
	int count = 0;
	WCHAR* temp = (WCHAR*)ExAllocatePool(PagedPool,MAX_PATH * sizeof(WCHAR));
	memset(temp,'\0',MAX_PATH * sizeof(WCHAR));

	pEntry = pEnd = strUnc;

	while (*pEnd != '\0')
	{
		if(*pEnd == '\\')
		{
			count++;
			if(count == 3)
			{
				pEntry = pEnd;
			}

			if(count == 4)
			{
				wcsncpy(temp,pEntry+1,pEnd - pEntry -1);
				return temp;//没有释放
			}
		}
		pEnd ++;
	}

	return temp;
}

//未完成
NTSTATUS EnumSubGValueReg(PUNICODE_STRING pRegUnicodeString)
{
	HANDLE hRegiste = NULL;
	OBJECT_ATTRIBUTES objectAttributes;
	NTSTATUS Status = STATUS_SUCCESS;
	ULONG ulSize = 0;
	PKEY_FULL_INFORMATION pfi = 0;
	ULONG index = 0;
	


	InitializeObjectAttributes(&objectAttributes,
							pRegUnicodeString,
							OBJ_CASE_INSENSITIVE,
							NULL,
							NULL);

	Status = ZwOpenKey( &hRegiste,
							KEY_ALL_ACCESS,
							&objectAttributes);

	if(!NT_SUCCESS(Status))
		DbgPrint("ZwOpenKey is faild !\n");

	ZwQueryKey(hRegiste,
			KeyFullInformation,
			NULL,
			0,
			&ulSize);

	pfi = (PKEY_FULL_INFORMATION)ExAllocatePoolWithTag(PagedPool,ulSize,'jdaa');

	if(pfi)
	{
		DbgPrint("ExallocatePool Faild!\n");
		return STATUS_UNSUCCESSFUL;
	}

	ZwQueryKey(hRegiste,
			KeyFullInformation,
			pfi,ulSize,
			&ulSize);

	for (index = 0; index < pfi->Values; index++)
	{

	}

	return STATUS_SUCCESS;

}


void DriverUnlaod(PDRIVER_OBJECT pDriverObject)
{
	DbgPrint("[Djwow]DriverUnload\n");
}


NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject ,PUNICODE_STRING pRegPath)
{
	#define MAX_PATH 260
	PKEY_VALUE_PARTIAL_INFORMATION pVpi = 0;
	NTSTATUS Status = STATUS_SUCCESS;
	UNICODE_STRING str = {0};
	WCHAR *p = 0;
	WCHAR *pSharName = 0;
	WCHAR *pDirName = 0;
	WCHAR *pQueryedName = 0;
	WCHAR *pEntry = 0;
	int count = 0;
	
	// “\\\\192.168.0.1\\mydocs\\hi.txt” ”D:\\Docs\\hi.txt”
	/*  \\\\192.168.0.1\\Mydocs\\directory\\filename E:\\Docs\\directory\\filename */
	DbgPrint("\\\\192.168.0.1\\Mydocs\\directory\\filename.txt\n");
	pSharName = GetShareName(L"\\\\192.168.0.1\\Mydocs\\directory\\filename.txt");
	DbgPrint("%S\n",pSharName);
	//注意 这个没有释放
	//ExFreePool(pSharName);
	pDirName = GetDirAndFileName(L"\\\\192.168.0.1\\Mydocs\\directory\\filename.txt");
	//注意 这个没有释放
	DbgPrint("%S\n",pDirName);


	Status = RegQueryValue(L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\LanmanServer\\Shares",pSharName,&pVpi);

	if(!NT_SUCCESS(Status))
	{
		if(Status == STATUS_OBJECT_NAME_NOT_FOUND)
		{
			//DbgPrint("NAME_NOT_FOUND!\n");
			goto EX;
		}

		DbgPrint("RegQueryValue faild! code :0x%x", Status);
		goto EX;
	}

	pQueryedName = ExAllocatePool(PagedPool,MAX_PATH * sizeof(WCHAR));
	memset(pQueryedName,'\0',MAX_PATH * sizeof(WCHAR));

	for(p = pVpi->Data;*p!=L'\0'; p=p+wcslen(p)+1)
	{
		count ++;
		if(count == 3)
		{
			wcscpy(pQueryedName,p);
			break;
		}

	}

	DbgPrint("%S\n",pQueryedName);

	/*str.Buffer = ExAllocatePool(PagedPool,MAX_PATH * sizeof(WCHAR));
	str.Length = MAX_PATH * sizeof(WCHAR);
	str.MaximumLength = MAX_PATH * sizeof(WCHAR);
	
	if(str.Buffer == NULL)
	{
		DbgPrint("str.buff is null;\n");
		return STATUS_UNSUCCESSFUL;
	}
		
	memset(str.Buffer,'\0',MAX_PATH * sizeof(WCHAR));

	for(p = pVpi->Data;*p!=L'\0'; p=p+wcslen(p)+1)
	{
		count ++;
		if(count == 3)
		{
			wcscpy(str.Buffer,p);
			break;
		}

	}

	DbgPrint("%wZ\n",&str);
	
	ExFreePool(str.Buffer);*/

	pEntry = AppendWchar(pQueryedName,pDirName);
	DbgPrint("%S\n",pEntry);

	ExFreePool(pEntry);
	ExFreePool(pQueryedName);
	ExFreePool(pVpi);
	str.Buffer = 0;
	pVpi = 0;

EX:
	ExFreePool(pSharName);
	ExFreePool(pDirName);
	pDriverObject->DriverUnload = DriverUnlaod;
	DbgPrint("[Djwow]DriverEntry!\n");
	return STATUS_SUCCESS;
}

学长思路很明确啊

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值