Egloos | Log-in






Windbg를 이용한 IoCallDriver 분석

IoCallDriver는 파라미터를 받을 때 fastcall방식을 사용합니다.
즉, ecx는 첫번째 파라미터(DeviceObject), edx는 두번째 파라미터(Irp)가 입력됩니다.

lkd> u nt!IopfCallDriver
804e33a2 dec    byte ptr [edx+23h]                     

; Irp->CurrentLocation 을 1 감소합니다.
; 즉 현재 스택에서 하위 스택으로 이동하는 것이지요

                  
804e33a5 mov    al,byte ptr [edx+23h]
804e33a8 test    al,al                                            
804e33aa jle     nt!IopfCallDriver+0xa (805222e1)

; 현재 스택의 위치가 0보다 작다면 
; nt!IopfCallDriver+0xa  로 점프합니다.
; u 명령어로 역어셈 해보니 블루스크린을 발생하는 곳이군요.
; 즉 현재 스택위치가 0보다 작다는 의미는
; 더이상 하위 스택이 없단 의미로 이렇게 되면 무엇인가
; 코드가 문제가 있는 것이니 더이상 진행할 수 없어 블루스크린을
; 띄우는 것입니다.


804e33b0 mov     eax,dword ptr [edx+60h]            
804e33b3 sub     eax,24h

; 이번엔 Irp->OverLay.CurrentStackLocation을 가져옵니다. 
; CurrentStackLocation에서 -24를 하네요... 왜 -24를 뺄까요?
; 그것은 하위 스택의 주소를 가져오기 위함입니다.
; 스택의 자료구조는 _IO_STACK_LOCATION이고 이 구조체의
; 크기는 24입니다. 헤헤.. 네~ 포인터 연산을 하는 것입니다.


804e33b6 push    esi
804e33b7 mov     dword ptr [edx+60h],eax

; 포인터 연산을 마무리하네요..
; 다음 스택을 Irp->Overlay.CurrentStackLocation에 설정합니다.


804e33ba mov     dword ptr [eax+14h],ecx

; nextStack->DeviceObject에 파라미터로 받은
; DeviceObject를 설정합니다.


804e33bd movzx   eax,byte ptr [eax]

; eax는 currentStack이었죠 첫번째 필드는 MajorFunction입니다.


804e33c0 mov     esi,dword ptr [ecx+8]                

; ecx는 DeviceObject이고 +8의 위치는 DriverObject를 뜻합니다.


804e33c3 push    edx                
804e33c4 push    ecx
804e33c5 call    dword ptr [esi+eax*4+38h]

; DriverObject+ 38h + MajorFunction*4  라는 뜻이 되겠네요.
; DriverObject+ 38h는 MajorFunction Table을 뜻합니다.
; 즉 DriverObject에 MajorFunction에 해당하는 함수를 호출하는 것이 되겠네요.


804e33c9 pop     esi
804e33ca ret

lkd> u 805222e1
nt!IopfCallDriver+0xa:                            
805222e1 push    0
805222e3 push    0
805222e5 push    0
805222e7 push    edx
805222e8 push    35h
805222ea call    nt!KeBugCheckEx (80539657)    ; 블루스크린을 발생시킵니다.!
805222ef  mov     esi,dword ptr [eax+4]

위의 코드를 보면 IoCallDriver의 역할은 Irp를 하위 스택으로 설정하고
하위 스택의 DriverObject의 MajorFunction에 대한 함수를 호출하는 것으로
정리할 수 있습니다.


p.s. 밑의 자료구조와 매칭해서 보시면 더욱 이해가 쉬울 것입니다.

lkd> dt _IRP
nt!_IRP
   +0x000 Type             : Int2B
   +0x002 Size             : Uint2B
   +0x004 MdlAddress       : Ptr32 _MDL
   +0x008 Flags            : Uint4B
   +0x00c AssociatedIrp    : __unnamed
   +0x010 ThreadListEntry  : _LIST_ENTRY
   +0x018 IoStatus         : _IO_STATUS_BLOCK
   +0x020 RequestorMode    : Char
   +0x021 PendingReturned  : UChar
   +0x022 StackCount       : Char
  
+0x023 CurrentLocation  : Char
   +0x024 Cancel           : UChar
   +0x025 CancelIrql       : UChar
   +0x026 ApcEnvironment   : Char
   +0x027 AllocationFlags  : UChar
   +0x028 UserIosb         : Ptr32 _IO_STATUS_BLOCK
   +0x02c UserEvent        : Ptr32 _KEVENT
   +0x030 Overlay          : __unnamed
   +0x038 CancelRoutine    : Ptr32     void
   +0x03c UserBuffer       : Ptr32 Void
   +0x040 Tail             : __unnamed
      +0x000 Overlay          : __unnamed
         +0x000 DeviceQueueEntry : _KDEVICE_QUEUE_ENTRY
         +0x000 DriverContext    : [4] Ptr32 Void
         +0x010 Thread           : Ptr32 _ETHREAD
         +0x014 AuxiliaryBuffer  : Ptr32 Char
         +0x018 ListEntry        : _LIST_ENTRY
         +0x020 CurrentStackLocation : Ptr32 _IO_STACK_LOCATION
         +0x020 PacketType       : Uint4B
         +0x024 OriginalFileObject : Ptr32 _FILE_OBJECT

lkd> dt _IO_STACK_LOCATION
nt!_IO_STACK_LOCATION
   +0x000 MajorFunction    : UChar
   +0x001 MinorFunction    : UChar
   +0x002 Flags            : UChar
   +0x003 Control          : UChar
   +0x004 Parameters       : __unnamed
  
+0x014 DeviceObject     : Ptr32 _DEVICE_OBJECT
   +0x018 FileObject       : Ptr32 _FILE_OBJECT
   +0x01c CompletionRoutine : Ptr32     long
   +0x020 Context          : Ptr32 Void

lkd> dt _DEVICE_OBJECT
nt!_DEVICE_OBJECT
   +0x000 Type             : Int2B
   +0x002 Size             : Uint2B
   +0x004 ReferenceCount   : Int4B
  
+0x008 DriverObject     : Ptr32 _DRIVER_OBJECT
   +0x00c NextDevice       : Ptr32 _DEVICE_OBJECT
   +0x010 AttachedDevice   : Ptr32 _DEVICE_OBJECT
   +0x014 CurrentIrp       : Ptr32 _IRP
   +0x018 Timer            : Ptr32 _IO_TIMER
   +0x01c Flags            : Uint4B
   +0x020 Characteristics  : Uint4B
   +0x024 Vpb              : Ptr32 _VPB
   +0x028 DeviceExtension  : Ptr32 Void
   +0x02c DeviceType       : Uint4B
   +0x030 StackSize        : Char
   +0x034 Queue            : __unnamed
   +0x05c AlignmentRequirement : Uint4B
   +0x060 DeviceQueue      : _KDEVICE_QUEUE
   +0x074 Dpc              : _KDPC
   +0x094 ActiveThreadCount : Uint4B
   +0x098 SecurityDescriptor : Ptr32 Void
   +0x09c DeviceLock       : _KEVENT
   +0x0ac SectorSize       : Uint2B
   +0x0ae Spare1           : Uint2B
   +0x0b0 DeviceObjectExtension : Ptr32 _DEVOBJ_EXTENSION
   +0x0b4 Reserved         : Ptr32 Void

lkd> dt _DRIVER_OBJECT
nt!_DRIVER_OBJECT
   +0x000 Type             : Int2B
   +0x002 Size             : Int2B
   +0x004 DeviceObject     : Ptr32 _DEVICE_OBJECT
   +0x008 Flags            : Uint4B
   +0x00c DriverStart      : Ptr32 Void
   +0x010 DriverSize       : Uint4B
   +0x014 DriverSection    : Ptr32 Void
   +0x018 DriverExtension  : Ptr32 _DRIVER_EXTENSION
   +0x01c DriverName       : _UNICODE_STRING
   +0x024 HardwareDatabase : Ptr32 _UNICODE_STRING
   +0x028 FastIoDispatch   : Ptr32 _FAST_IO_DISPATCH
   +0x02c DriverInit       : Ptr32     long
   +0x030 DriverStartIo    : Ptr32     void
   +0x034 DriverUnload     : Ptr32     void
   +0x038 MajorFunction    : [28] Ptr32     long

by 견우 | 2008/08/29 09:58 | 트랙백 | 덧글(1)

트랙백 주소 : http://cjhnim.egloos.com/tb/3883019
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]
Commented by 늅늅 at 2009/11/24 14:19
안녕하세요. 친절하게 IoCallDrive 에 대하여 설명해 주신거 잘 보고 갑니다 ^^

:         :

:

비공개 덧글

◀ 이전 페이지          다음 페이지 ▶