// _UNICODE_STRING結構copy, 並檢測其值是否有效
// 注意:
// 1: 是結構copy,所以源指針與目標指針指向同一位置
// 2: 目標MaximumLength直接修改爲Length +2, 不管源MaximumLength是多少
NTSTATUS PspCaptureAndValidateUnicodeString(_UNICODE_STRING* s, _UNICODE_STRING*d);
// _UNICODE_STRING內容copy,
// 注意:
// 1: copy 源buffer, 到目標*dBuffer, 並設目標buffer爲*dBuffer
// 2: MaximumLength - Length之間的值清0
// 3: 返回*dBuffer 爲 +MaximumLength之後的位置
NTSTATUS PspCopyUnicodeString(_UNICODE_STRING *s, _UNICODE_STRING *d, IN OUT PWSTR *dBuffer);
// 僞代碼
NTSTATUS NTSUD::PspCaptureAndValidateUnicodeString( _UNICODE_STRING* s, _UNICODE_STRING*d )
{
// copy
*d = *s;
// 檢測
if (d->Length&1)
return STATUS_INVALID_PARAMETER;
if (!d->Buffer)
{
if (d->Length)
return STATUS_INVALID_PARAMETER;
d->MaximumLength =0;
}
else
{
d->MaximumLength = d->Length +2;
if (d->Length +2 < d->Length) // 即超出範圍
return STATUS_INVALID_PARAMETER;
}
// 測試是否可讀
if (!d->Length) return STATUS_SUCCESS;
__try
{
PWCH last = d->Buffer + d->Length;
if ((ULONG_PTR)last > MmUserProbeAddress ||
last < d->Buffer
)
ProbeForWriteChar((char*)MmUserProbeAddress);
}__except(EXCEPTION_EXECUTE_HANDLER)
{
return (NTSTATUS)GetExceptionCode();
}
return STATUS_SUCCESS;
}
NTSTATUS NTSUD::PspCopyUnicodeString( _UNICODE_STRING *s, _UNICODE_STRING *d, IN OUT PWSTR *dBuffer )
{
//PWSTR *dBuffer; // rdi
//_UNICODE_STRING *s; // rbx
PWSTR v5; // rcx
//dBuffer = dBuffer;
//s = s;
_mm_storeu_si128((__m128i *)d, _mm_loadu_si128((const __m128i *)s));
if ( s->Buffer )
{
v5 = *dBuffer;
d->Buffer = *dBuffer;
__try
{
memmove(v5, s->Buffer, s->Length);
memset((char *)*dBuffer + s->Length, 0, s->MaximumLength - s->Length);
if ( *dBuffer )
*dBuffer = (PWSTR)((char *)*dBuffer + s->MaximumLength);
}__except(EXCEPTION_EXECUTE_HANDLER)
{
return NTSTATUS(GetExceptionCode());
}
}
return 0;
}