ZwCreateFile() 이 실패하는 이유..
오늘 참... 어이없는 삽질을 했습니다. (사실 요즘 삽질의 연속이긴합니다만 ㅠ.ㅠ )
아주 간단한 드라이버를 두개를 작성하고, 하나의 드라이버에서 다른 드라이버를 오픈하는 코드를 작성했지요.

오픈의 대상이 되는 드라이버의 코드는 아래와 같고요.. 빌드해서 로드하면 \Device\Callee 오브젝트를 만듭니다.
참고로.. 아래 코드에서 "중간생략" 된 코드는 없고, 컴파일 되는 코드 그대로입니다. :-)

extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
KdPrint( (CALLEE_CALLEE_DRIVER_NAME" %s \n", __FUNCTION__) );

// device 생성
//
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING DeviceName;
RtlInitUnicodeString(&DeviceName, L"\\Device\\Callee");
NTSTATUS status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&DeviceObject
);
if (FALSE == NT_SUCCESS(status))
{
KdPrint( (CALLEE_CALLEE_DRIVER_NAME" IoCreateDevice(), status=0x%08x \n", status) );
return status;
}

// initialize MajorFunctions
//
DriverObject->DriverUnload = Unload;

return STATUS_SUCCESS;
}


Callee 드라이버를 오픈하는 드라이버의 코드는 아래와 같습니다.


extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
KdPrint( (CALLER_CALLEE_DRIVER_NAME" %s \n", __FUNCTION__) );

NTSTATUS status=STATUS_UNSUCCESSFUL;

DriverObject->DriverUnload = Unload;

// Open Callee device
//
HANDLE hCallee = NULL;
IO_STATUS_BLOCK iostatus;
OBJECT_ATTRIBUTES oa;
UNICODE_STRING uCalleeDeviceName;
RtlInitUnicodeString(&uCalleeDeviceName, L"\\Device\\Callee");
InitializeObjectAttributes(
&oa,
&uCalleeDeviceName,
OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE,
NULL,
NULL);
status = ZwCreateFile(
&hCallee,
GENERIC_ALL,
&oa,
&iostatus,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ | FILE_SHARE_WRITE/*| FILE_SHARE_DELETE*/,
FILE_OPEN_IF,
FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
if(!NT_SUCCESS(status))
{
KdPrint((
"%s, ZwCreateFile(%wZ) failed, status=0x%08x \n",
__FUNCTION__, &uCalleeDeviceName, status
));
return status;
}

// Close Callee device
//
ZwClose(hCallee);

return STATUS_SUCCESS;
}
당연히 잘 되겠지 했는데 계속 ZwCreateFile() 함수가 오류를 뱉어내더군요.ㅜㅜ
WinObj 로 봐도 분명히 \Device\Callee 가 만들어져 있는데도요..
별의 별짓을 다 하다.. 갑자기 아차차~!!! 싶더군요.

대체 왜 ZwCreateFile() 이 에러를 뱉어냈을까요?? 퀴즈입니다!!~!

답은 아래에 있습니다.




































정답 나갑니다. :-)
ZwCreateFile()  이 실패했던 이유는 Create 핸들러가 없어서 그렇습니다. -_-;;
이러니 Open 이 안되는것이겠죠. ㅎㅎ 간단하죠?
코드를 작성할때 대부분 기존 사용하던 템플릿 코드를 그대로 재사용하기 때문에 이런 어처구니 없는 실수를 하게 만드는것 같습니다. 




NTSTATUS __stdcall DispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);

/** ---------------------------------------------------------------------------
\brief

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
extern "C"
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegistryPath)
{
KdPrint( (CALLEE_CALLEE_DRIVER_NAME" %s \n", __FUNCTION__) );

// device 생성
//
PDEVICE_OBJECT DeviceObject = NULL;
UNICODE_STRING DeviceName;
RtlInitUnicodeString(&DeviceName, L"\\Device\\Callee");
NTSTATUS status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&DeviceName,
FILE_DEVICE_UNKNOWN,
FILE_DEVICE_SECURE_OPEN,
TRUE,
&DeviceObject
);
if (FALSE == NT_SUCCESS(status))
{
KdPrint( (CALLEE_CALLEE_DRIVER_NAME" IoCreateDevice(), status=0x%08x \n", status) );
return status;
}

// initialize MajorFunctions
//
DriverObject->MajorFunction[IRP_MJ_CREATE] = DispatchCreateClose;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DispatchCreateClose;
DriverObject->DriverUnload = Unload;

return STATUS_SUCCESS;
}

/** ---------------------------------------------------------------------------
\brief 제가 범인이랍니다. ^^

\param
\return
\code
\endcode
-----------------------------------------------------------------------------*/
NTSTATUS __stdcall DispatchCreateClose(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
UNREFERENCED_PARAMETER(DeviceObject);
KdPrint( (CALLEE_CALLEE_DRIVER_NAME" %s \n", __FUNCTION__) );


// complete this irp !
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}



이 글과 관련있는 글을 자동검색한 결과입니다 [?]

by somma | 2009/08/13 22:16 | 시스템 프로그래밍 | 트랙백 | 덧글(9)
트랙백 주소 : http://somma.egloos.com/tb/4210598
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 이재홍 at 2009/08/13 23:12
IoCreateDevice의 6번째 매개변수 Exclusive가 TRUE이기 때문.
Commented by 멍멍이 at 2009/08/19 19:24
음..ㅋㅋ 드라이버가 만든 DACL에 부합하는 접근권한이
app에는 없던걸까요? 위에분이 말씀하신건 뭐죠? 'ㅁ')?!
Commented by somma at 2009/08/20 07:53
권한문제는 아니고요.. ^^
이재홍님께서 말씀하신 것은 exclusive 로 만들어진 device 의 경우 하나의 app 에서 핸들을 획득하면 다른 녀석이 오픈하지 못하게합니다.
의도된 답은 아닙니다. :-)
Commented by 멍멍이 at 2009/08/20 13:05
아하 그것에 대해서 말한 것이군요,
예전 부터 궁금했던 것중에 하나인데,
exclusive flag와 Inherit flag를 같이 가지고 있는 securable object에
handle을 child process 가 DuplicateHandle()을 하면 쓸 수 있을까요?
기본적으로는, DulplicateHandle()을 하면, 특정 Object를 자신의 handle table로
포인터 떙겨주고 레퍼런스 카운터를 올리는 것일텐데요,
exclusive 속성 상 다른 한 프로세스에서 핸들을 획득하면,
다른 녀석이 오픈하지 못한다 라는 말은 어쩌면 레퍼런스를 못하게 한다 일수도 있으니,
DuplicateHandle()이 안된다면, 그냥 그 inherit 된 handle 그 자체는 쓸 수 있을테니
되려나요? ㅎㅎ
Commented by somma at 2009/08/20 23:28
으흠.. 해보시고 알려주세요. ^^; 헤헤~
Commented by 양군 at 2009/09/22 01:04
지만이네나 여기나 역시나 여려분 얘기들뿐..^^;;
술은 언제 마시는거래요?
Commented by somma at 2009/09/25 11:59
그러게 술한잔 해야 하는데...당췌 시간이 안나는 구만.. -_-;;
추석 지나고 봅시다.~ ^^
Commented by 김종호 at 2009/09/22 17:58
안녕하세요 잘 지내시죠? ㅋㅋ

한글을 보고 무슨말인지 모를때도 종종있는데 보안하시는 분들 코드가 딱 그런거 같아요

분명 C 코드인데 이해가 안간다눈..;;;;
Commented by somma at 2009/09/25 11:58
쫑호~ 잘 지내고 있는감?
난 그냥 정신없이 바쁘게 지내고 있어..
뭐 나도 저 코드 보고 이해 잘 못하고 있으니..피장 파장이지..ㅋㅋㅋ

:         :

:

비공개 덧글



< 이전페이지 다음페이지 >