UNICODE_STRING 동적할당 하기 / 드라이버개발
드라이버 개발을 할때 주로 문자열은 UNICODE_STRING이라는 자료구조를 사용하게 된다. 하지만 익숙치 않은 구조때문인지 드라이버 개발 입문시 어려움을 겪는 부분이기도하다.
우선 UNICODE_STRING
구조체를 보겠다.
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
유저 모드 프로그램 개발시 char
, wchar
와 같이 단순 배열 형태가 아닌 것을 볼 수 있다.
첫번째 필드 Length
는 문자열 버퍼의 길이를 바이트 단위로 나타낸다. 조심해야 한다. 문자의 갯수가 아니라 버퍼 바이트 길이이다. 이때, NULL문자를 제외한 크기이다. 또 주의 해야 할 점은 Length
가 0이라도 버퍼에 NULL가 들어있을 수 있다.
두번째, MaxiumLength
는 Buffer
에 할당된 총 메모리의 바이트 크기를 나타낸다.
마지막으로 Buffer
는 실제 문자 데이터가 들어간 버퍼이다. Wide-Charactor를 가리킨다.
UNICODE_STRING은 문자열을 나타내는게 아니라 문자열의 버퍼와 길이등의 정보를 저장하고 있는 구조체라는 것을 알 수 있다.
UNICODE_STRING 동적할당/해제
다음은 UNICODE_STRING의 동적할당, 해제를 구현한 코드이다.
동적할당 시 MaxiumLength
기준으로 버퍼크기를 할당받아 구조체를 체워주면된다.
NTSTATUS AllocUnicode(
PUNICODE_STRING dst,
USHORT maxiumBufferLen
)
{
dst->Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, maxiumBufferLen, POOL_TAG);
if (dst->Buffer == NULL)
{
return STATUS_UNSUCCESSFUL;
}
RtlZeroMemory(dst->Buffer, maxiumBufferLen);
dst->Length = 0;
dst->MaximumLength = maxiumBufferLen;
return STATUS_SUCCESS;
}
할당해제는 Buffer
필드가 가리키고 있는 Wide Character 버퍼를 할당해제 한다.
VOID FreeUnicode(
PUNICODE_STRING dst
)
{
if (!dst->Buffer)
{
return;
}
ExFreePool(dst->Buffer);
dst->Buffer = 0;
dst->Length = 0;
dst->MaximumLength = 0;
}
예제 코드
다음은 UNICODE_STRING
을 동적할당하여 문자열을 복사하고 출력하는 예제 코드이다.
출력은 KdPrint
함수를 이용하고 UNICODE_STRING
의 Format String 식별자는 %wZ
이다.
#include <ntddk.h>
#define POOL_TAG 'cw32'
NTSTATUS DriverEntry(
PDRIVER_OBJECT pDriverObject,
PUNICODE_STRING pRegistryPath
);
VOID DriverUnload(
PDRIVER_OBJECT pDriverObject
);
NTSTATUS AllocUnicode(
PUNICODE_STRING dst,
USHORT maxiumBufferLen
);
VOID FreeUnicode(
PUNICODE_STRING dst
);
const WCHAR gHello[] = L"hello~Driver!";
VOID FreeUnicode(
PUNICODE_STRING dst
)
{
if (!dst->Buffer)
{
return;
}
ExFreePool(dst->Buffer);
dst->Buffer = 0;
dst->Length = 0;
dst->MaximumLength = 0;
}
NTSTATUS AllocUnicode(
PUNICODE_STRING dst,
USHORT maxiumBufferLen
)
{
dst->Buffer = (PWCH)ExAllocatePoolWithTag(NonPagedPool, maxiumBufferLen, POOL_TAG);
if (dst->Buffer == NULL)
{
return STATUS_UNSUCCESSFUL;
}
RtlZeroMemory(dst->Buffer, maxiumBufferLen);
dst->Length = 0;
dst->MaximumLength = maxiumBufferLen;
return STATUS_SUCCESS;
}
NTSTATUS DriverEntry(
PDRIVER_OBJECT pDriverObject,
PUNICODE_STRING pRegistryPath
)
{
UNREFERENCED_PARAMETER(pDriverObject);
UNREFERENCED_PARAMETER(pRegistryPath);
pDriverObject->DriverUnload = DriverUnload;
NTSTATUS status = STATUS_UNSUCCESSFUL;
UNICODE_STRING helloUnicode;
UNICODE_STRING helloUnicodeAlloc;
RtlInitUnicodeString(&helloUnicode, gHello); //Unicode String 초기화
KdPrint(("helloUnicode=%wZ Length=%d MaxiumLength=%d\n", &helloUnicode, helloUnicode.Length, helloUnicode.MaximumLength));
AllocUnicode(&helloUnicodeAlloc, 100);
RtlCopyUnicodeString(&helloUnicodeAlloc, &helloUnicode);
KdPrint(("helloUnicodeAlloc=%wZ Length=%d MaxiumLength=%d\n", &helloUnicodeAlloc, helloUnicodeAlloc.Length, helloUnicodeAlloc.MaximumLength));
FreeUnicode(&helloUnicodeAlloc);
return status;
}
VOID DriverUnload(
PDRIVER_OBJECT pDriverObject
)
{
UNREFERENCED_PARAMETER(pDriverObject);
KdPrint(("DriverUnload\n"));
}
참고
'개발 > Windows' 카테고리의 다른 글
드라이버에서 파일 읽기 예제/ ZwOpenFile ,ZwReadFile (0) | 2020.11.12 |
---|---|
Windbg 커널디버깅 설정하기 (Network 디버깅) (0) | 2020.07.27 |
Windows 드라이버 커널모드에서 파일 해시 구하기 (0) | 2020.07.23 |
윈도우 네트워킹 아키텍처 (Windows Networking Architecture) (0) | 2020.06.24 |
Python2.x 에서 error: Microsoft Visual C++ 9.0 is required. (0) | 2020.06.05 |
댓글