看流星社区

 找回密码
 注册账号
查看: 1755|回复: 0

实现UNC转本地路径

[复制链接]

该用户从未签到

发表于 2017-6-1 13:33:44 | 显示全部楼层 |阅读模式
以为学长写的:
其中有两个功能挺好用的
//实现 strchr功能 返回chr出现的位置
WCHAR * RtlUnicodeStringChr(PUNICODE_STRING IN pStr, WCHAR chr);
//实现strstr功能  返回pStrDst首次初夏你的位置
WCHAR * RtlUnicodeStringStr(PUNICODE_STRING IN pStr, PUNICODE_STRING pStrDst);[/code]
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 == 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;
}[/code]


/*

实现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 == 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;
}[/code]


我自己实现的:
#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;
}
[/code]
学长思路很明确啊
点击按钮快速添加回复内容: 支持 高兴 激动 给力 加油 苦寻 生气 回帖 路过 感恩
您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

小黑屋|手机版|Archiver|看流星社区 |网站地图

GMT+8, 2024-4-20 03:18

Powered by Kanliuxing X3.4

© 2010-2019 kanliuxing.com

快速回复 返回顶部 返回列表