|
发表于 2018-1-19 23:33:36
|
显示全部楼层
//发个r0的
PWSTR _GetSymbolicTarget(PCWSTR pwSymbolic)
{
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uSymbolic;
NTSTATUS status;
HANDLE hSymbolic;
UNICODE_STRING uTarget;
ULONG len = 0;
WCHAR buf[4];
PWSTR pwTarget;
RtlInitUnicodeString(&uSymbolic, pwSymbolic);
InitializeObjectAttributes(&oa, &uSymbolic, OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE, NULL,NULL);
status = ZwOpenSymbolicLinkObject(&hSymbolic, GENERIC_READ, &oa);
if (!NT_SUCCESS(status))
{
DbgPrint(("hpsafe:%-4d [ERRO] ZwOpenSymbolicLinkObject failed with 0x%08X.\n", __LINE__, status));
return NULL;
}
RtlInitEmptyUnicodeString(&uTarget, buf, 0);
status = ZwQuerySymbolicLinkObject(hSymbolic, &uTarget, &len);
if (status != STATUS_BUFFER_TOO_SMALL)
{
DbgPrint(("hpsafe:%-4d [ERRO] ZwQuerySymbolicLinkObject failed with 0x%08X.\n", __LINE__, status));
return NULL;
}
pwTarget = ExAllocatePoolWithTag(NonPagedPool, len + sizeof(WCHAR), '_EL_');
if (!pwTarget)
{
DbgPrint(("hpsafe:%-4d [ERRO] ExAllocatePoolWithTag failed.\n", __LINE__));
ZwClose(hSymbolic);
return NULL;
}
RtlInitEmptyUnicodeString(&uTarget, pwTarget, (USHORT)len + sizeof(WCHAR));
status = ZwQuerySymbolicLinkObject(hSymbolic, &uTarget, &len);
ZwClose(hSymbolic);
if (!NT_SUCCESS(status))
{
DbgPrint(("hpsafe:%-4d [ERRO] ZwQuerySymbolicLinkObject failed with 0x%08X.\n", __LINE__, status));
ExFreePoolWithTag(pwTarget, '_EL_');
return NULL;
}
return pwTarget;
}
PWSTR _DosPathToNtPath(PCWSTR pwDosPath)
{
PWSTR pwTarget, pNtPath;
SIZE_T l1, l2;
WCHAR pwDosDrive[] = L"\\DosDevices\\X:";
if ((*pwDosPath >= L'a' && *pwDosPath <= L'z' ||
*pwDosPath >= L'A' && *pwDosPath <= L'Z') &&
pwDosPath[1] == L':' && pwDosPath[2] == L'\\')
{
/* get nt drive path */
pwDosDrive[12] = pwDosPath[0];
pwTarget = _GetSymbolicTarget(pwDosDrive);
if (!pwTarget)
return NULL;
/* concat two part */
RtlStringCbLengthW(pwTarget, NTSTRSAFE_MAX_CCH * sizeof(WCHAR), &l1);
RtlStringCbLengthW(pwDosPath + 2, NTSTRSAFE_MAX_CCH * sizeof(WCHAR), &l2);
pNtPath = ExAllocatePoolWithTag(NonPagedPool, l1 + l2 + sizeof(WCHAR), '_EL_');
if (pNtPath)
{
RtlStringCbCopyW(pNtPath, l1 + sizeof(WCHAR), pwTarget);
RtlStringCbCopyW(pNtPath + l1 / sizeof(WCHAR), l2 + sizeof(WCHAR), pwDosPath + 2);
}
else
{
DbgPrint(("hpsafe:%-4d [ERRO] ExAllocatePoolWithTag failed.\n", __LINE__));
}
ExFreePoolWithTag(pwTarget, '_EL_');
return pNtPath;
}
else
{
DbgPrint(("hpsafe:%-4d [ERRO] unsupported path: %ws.\n", __LINE__, pwDosPath));
return NULL;
}
}
PWSTR _NtPathToDosPath(PCWSTR pwNtPath)
{
PWSTR pwDosPath;
WCHAR pwDosDrive[] = L"\\DosDevices\\X:";
PWSTR pwTarget;
WCHAR c;
USHORT len;
UNICODE_STRING usTarget;
UNICODE_STRING usNtPath;
UNICODE_STRING usDosPath;
RtlInitUnicodeString(&usNtPath, pwNtPath);
for (c = L'A'; c <= L'Z'; ++ c)
{
pwDosDrive[12] = c;
pwTarget = _GetSymbolicTarget(pwDosDrive);
if (!pwTarget)
continue;
/*
DbgPrint(("hpsafe:%-4d [INFO] %c:\\ -> %ws.\n", __LINE__,
(CHAR)c, pwTarget));
*/
RtlInitUnicodeString(&usTarget, pwTarget);
if (RtlPrefixUnicodeString(&usTarget, &usNtPath, TRUE))
{
len = (wcslen(pwNtPath) - wcslen(pwTarget) + 4) * sizeof(WCHAR);
pwDosPath = ExAllocatePoolWithTag(NonPagedPool, len, '_EL_');
if (!pwDosPath)
{
DbgPrint(("hpsafe:%-4d [ERRO] ExAllocatePoolWithTag failed.\n", __LINE__));
return NULL;
}
memset(pwDosPath, 0, len);
RtlInitEmptyUnicodeString(&usDosPath, pwDosPath, len);
RtlUnicodeStringCopyString(&usDosPath, L"x:");
*pwDosPath = c;
RtlUnicodeStringCatString(&usDosPath, pwNtPath + wcslen(pwTarget) );
return pwDosPath;
}
}
return NULL;
}
|
|