심플스 - 프로그램과 책 이야기로 가득한 곳, (Simples.Kr)

  

 

( 주의 : 이 글에서 디스어셈블리되는 커널은 Windows XP SP2 이며 . ZwQueryInformationFile호출시 FileStandardInformation를 사용하였으므로 다른 인자를 사용하였다면 결과가 다르게 나타날 수 있습니다. )

ZwCreateFile을 이용해 파일 핸들을 열 때 비동기적으로 열어야 하는 경우가 생겼습니다.

이러한 경우 ZwReadFile로 파일을 읽을 때 두 번째 인자인 Event객체를 사용하여 WaitForSingleObject로 대기해야 하는 것으로 알고 있습니다.

그 러나 ZwQueryInformationFile에 경우에는 Event객체가 존재하지 않습니다. 그렇다면 윈도우즈 내부에서KeWaitForSingleObject을 호출 할 수도 있고 ( 만약에 비동기 모드로 파일의 핸들을 열었다면.. ),KeWaitForSingleObject 호출하지 않고 STATUS_PENDING을 리턴 할수도 있습니다.

내부적인 부분이라 알 수가 없고 STATUS_PENDING 리턴여부를 확실히 알아야 하기 때문에 WinDbg로 디버깅을 해보았습니다.

우선 파일을 비동기 모드로 연 후 ZwQueryInformationFile을 호출하기 바로 전에 브레이크 포인트를 걸어둡니다.


b0072382_4971b1f3078e5.png 


ZwQueryInformationFile은 내부적으로 NtQueryInformationFile 파일을 호출할 것이므로 다음과 같은 WinDbg명령줄을 이용해 브레이크 포인트를 겁니다.

bp nt!NtQueryInformationFile

그리고 F5를 눌러서 한 번 실행시킵니다.


b0072382_49a7de4994124.png 


위에 그림에서 보는 위치에서 멈추게 됩니다.
중요한건 콜스택을 잘 확인하여 내 드라이버에서 호출한 것이 맞는지 반드시 확인해보아야 합니다. ( 간혹 내 드라이버에서 호출하지 않은 경우가 있을 수 있습니다. )

F11를 눌르거나 계속해서 디버깅을 해보면 결국엔 IRP를 전송하기 위해 nt!IofCallDriver를 호출하게 되므로

bp nt!IofCallDriver

를 이용하여 다시 브레이크 포인트를 겁니다.

그리고 다시 F5를 누릅니다.


b0072382_4971b1f3078e5.png 


위와 마찬가지로 반드시 콜스택을 확인하여 내 드라이버에서 호출했는지 확인을 합니다. 이 상태에서 콜 스택을 보게 되면 이 함수를 호출 후 리턴되는 주소를 확인 할 수 있습니다.


b0072382_4971b1f3078e5.png 



그림에서 하이라이트 된 부분이 리턴되는 주소이며 해당 주소에 디스어셈블리 된 코드를 보면 다음과 같습니다.


b0072382_4971b1f3078e5.png 


위에서 보시면 KeWaitForSingleObject라는 함수를 어떠한 조건의 의해서 호출한다는 것을 알 수 있습니다.

8057bc3c 8b4dd4          mov     ecx,dword ptr [ebp-2Ch]
8057bc3f e87452f7ff      call    nt!IofCallDriver (804f0eb8)
8057bc44 8945d8          mov     dword ptr [ebp-28h],eax
8057bc47 817dd803010000  cmp     dword ptr [ebp-28h],103h
8057bc4e 0f85cc000000    jne     nt!NtQueryInformationFile+0x528 (8057bd20)
8057bc54 807de700        cmp     byte ptr [ebp-19h],0
8057bc58 745e            je      nt!NtQueryInformationFile+0x4c0 (8057bcb8)
8057bc5a 33ff            xor     edi,edi
8057bc5c 57              push    edi
8057bc5d 8b45dc          mov     eax,dword ptr [ebp-24h]
8057bc60 8b482c          mov     ecx,dword ptr [eax+2Ch]
8057bc63 c1e902          shr     ecx,2
8057bc66 81e101ffffff    and     ecx,0FFFFFF01h
8057bc6c 51              push    ecx
8057bc6d ff75cc          push    dword ptr [ebp-34h]
8057bc70 57              push    edi
8057bc71 83c05c          add     eax,5Ch
8057bc74 50              push    eax
8057bc75 e8300ff8ff      call    nt!KeWaitForSingleObject (804fcbaa)

이 부분은 IofCallDriver에 리턴값을 넣는 부분입니다.
리턴값은 NTSTATUS일 것 입니다.
8057bc44 8945d8          mov     dword ptr [ebp-28h],eax

그 후에 다음과 같이 0x103값과 비교하는데 이 값은
8057bc47 817dd803010000  cmp     dword ptr [ebp-28h],103h

다음과 같이 정의되어 있습니다.
#define STATUS_PENDING ((NTSTATUS)0x00000103L)    // winnt

즉, Pending여부를 체크한다는 것을 알 수 있습니다.
Pending이 아니라면 8057bd20주소로 점프하게 됩니다. Pedning이라면 다시 밑에서 무언가를 비교하게 되는데 byte ptr [ebp-19h]에 있는 이 값에 따라서 KeWaitForSingleObject를 호출할지 말지를 결정하게 됩니다. 중요한 것은 제 경우 테스트할 때 이 값은 0이 아니었으며 따라서 KeWaitForSingleObject를 호출하는 코드를 실행하게 됩니다. 또한 IofCallDriver호출 후 리턴한 후 강제적으로 eax레지스터에 STATUS_PENDING를 넣게 되면 KeWaitForSingleObject를 호출하게 됩니다.

참고로 만약 파일핸들을 동기화 모드로 열었다면 위에서 말한 코드 부분이 실행되지 않습니다.

결론은 ZwQueryInformationFile를 비동기 파일핸들로 호출 시에 내부적으로 STATUS_PENDING 여부를 체크하여
KeWaitForSingleObject로 대기합니다.

또한 ReactOS소스코드를 보시면 위와 비슷하게 구현되어 있는 것을 볼 수 있습니다. 물론 실제 윈도우즈 코드와 ReactOS소스코드가 완전히 같지는 않다는 것에 주의해야 할 것입니다.

List of Articles
번호 제목 글쓴이 날짜 조회 수
43 문서자료 SCSI Multi-Media Commands - 5 (MMC-5) file lain 2010-09-03 11070
42 문서자료 Seagate - SCSI Commands Reference Manual file lain 2010-09-03 11277
41 문서자료 Intel® Threading Building Blocks: Documents lain 2010-09-03 10735
40 문서자료 Mozilla - Accessibility/AT-Windows-API lain 2010-09-03 8909
39 문서자료 Win32 Assembly Tutorials [1] lain 2010-09-03 10963
38 문서자료 the Operating System resource center lain 2010-09-03 10533
37 문서자료 Bona Fide OSDev Documents lain 2010-09-03 10280
36 문서자료 Keybaord Scan Codes Demystified lain 2010-09-03 10429
35 문서자료 Intel i80x86 CPU Architecture lain 2010-09-03 10996
34 문서자료 Hexray - Failures and troubleshooting lain 2010-09-03 11503
33 Windows Research 윈도우즈 버전이 Windows XP SP2인지 확인하는 다른 방법 [1] lain 2010-09-03 21368
32 Windows Research 유저 레벨에서 API Hook 1부 file [1] lain 2010-09-03 22466
31 Windows Research 유저 레벨에서 API Hook 2부 file [2] lain 2010-09-03 19702
30 Windows Research IDA에 HexRay를 사용할 때의 주의점 [1] lain 2010-09-03 15614
29 Windows Research IDA에서 Microsoft 바이너리 파일을 리버싱 할 때 디버그 심... file [1] lain 2010-09-03 16626
28 Windows Research 커널 모듈 리스트 가져오기 [3] lain 2010-09-03 17322
27 Windows Research VMWare 탐지 기법 우회 [2] lain 2010-09-03 22788
26 Windows Research 커널 디버거 탐지 기법 우회 lain 2010-09-03 17082
» Windows Research ZwQueryInformationFile을 비동기 파일핸들로 호출 시 STATUS... file lain 2010-09-03 15514
24 Windows Research DosPathNameToNtPathName file lain 2010-09-03 13734

  • 이용약관
  • 개인정보취급방침
  • 사이트맵