3: kd> !analyze -v
*****************************************
* Bugcheck Analysis
*
*****************************************
UNEXPECTED_KERNEL_MODE_TRAP (7f)
This means a trap occurred in kernel mode, and it’s a trap of a kind
that the kernel isn’t allowed to have/catch (bound trap) or that
is always instant death (double fault). The first number in the
bugcheck params is the number of the trap (8 = double fault, etc)
Consult an Intel x86 family manual to learn more about what these
traps are. Here is a *portion* of those codes:
If kv shows a taskGate
use .tss on the part before the colon, then kv.
Else if kv shows a trapframe
use .trap on that value
Else
.trap on the appropriate frame will show where the trap was taken
(on x86, this will be the ebp that goes with the procedure KiTrap)
Endif
kb will then show the corrected stack.
Arguments:
Arg1: 00000008, EXCEPTION_DOUBLE_FAULT
Arg2: f7727d70
Arg3: 00000000
Arg4: 00000000
Debugging Details:
——————
PEB is paged out (Peb.Ldr = 7ffdc00c). Type “.hh dbgerr001″ for details
PEB is paged out (Peb.Ldr = 7ffdc00c). Type “.hh dbgerr001″ for details
BUGCHECK_STR: 0×7f_8
TSS: 00000028 — (.tss 0×28)
eax=0000bb40 ebx=b3c91454 ecx=00000000 edx=00000001 esi=b3c91400 edi=0000002d
eip=804e90d6 esp=b3c90f98 ebp=b3c91024 iopl=0 nv up di ng nz ac po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010092
nt!KeContextFromKframes+0×10:
804e90d6 53 push ebx
Resetting default scope
DEFAULT_BUCKET_ID: CODE_CORRUPTION
PROCESS_NAME: app.exe
EXCEPTION_RECORD: b3c91400 — (.exr 0xffffffffb3c91400)
ExceptionAddress: 80503a3f (nt!DebugService+0×0000001b)
ExceptionCode: 80000003 (Break instruction exception)
ExceptionFlags: 00000000
NumberParameters: 3
Parameter[0]: 00000001
Parameter[1]: b3c91530
Parameter[2]: 0000002d
TRAP_FRAME: b3c91454 — (.trap 0xffffffffb3c91454)
ErrCode = 00000000
eax=00000001 ebx=ffffffff ecx=b3c91530 edx=0000002d esi=0000002d edi=00000000
eip=80503a40 esp=b3c914c8 ebp=b3c914dc iopl=0 nv up ei pl nz ac pe cy
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00000217
nt!DebugService+0×1c:
80503a40 5b pop ebx
Resetting default scope
LAST_CONTROL_TRANSFER: from 804fbcef to 804e90d6
STACK_TEXT:
b3c91024 804fbcef b3c91454 00000000 b3c910fc nt!KeContextFromKframes+0×10
b3c913e4 804e0403 b3c91400 00000000 b3c91454 nt!KiDispatchException+0×82
b3c9144c 804e0b5c b3c914dc 80503a3f badb0d00 nt!CommonDispatchException+0×4d
b3c9144c 80503a40 b3c914dc 80503a3f badb0d00 nt!KiTrap03+0xae
b3c914dc 80503a6f 00000001 b3c91530 0000002d nt!DebugService+0×1c
b3c914f8 80503e97 b3c91518 ffffffff 00000000 nt!DebugPrint+0×1c
b3c9174c 80503ee3 80503ee6 ffffffff 00000000 nt!vDbgPrintExWithPrefix+0×101
b3c91768 b2e8aac0 b2e93360 b2e93320 8550a3d8 nt!DbgPrint+0×1a
WARNING: Stack unwind information not available. Following frames may be wrong.
b3c91788 b2e8a98e b2e93320 89e0cd00 8643bde0 Driver4+0×14ac0
b3c9179c b2e8b9d6 8643bde0 89e0cd00 87dca810 Driver4+0×1498e
b3c917c8 b2e8d382 89e0cd00 8643bde0 8643bebc Driver4+0×159d6
b3c91a08 b2e7baf8 89e0cd00 8643bde0 b3c91a30 Driver4+0×17382
b3c91a58 b4487c29 89e0cd00 8643bde0 87dbe000 Driver4+0×5af8
b3c91a84 b4486d87 89e0cd00 8643bde0 00000000 Driver3+0×7c29
b3c91aa4 b5765796 00000000 87dca810 8a6ccc50 Driver3+0×6d87
b3c91ac0 b5766176 89df432c 00000000 8a6ccc50 Driver1+0×9796
b3c91b08 b5765c28 89df432c 00000001 87dca801 Driver1+0xa176
b3c91b48 804e38ff 00000000 8643bde0 00000000 Driver1+0×9c28
b3c91b78 b4486dd8 8643bde0 89e65958 c0000001 nt!IopfCompleteRequest+0xa2
b3c91b8c bac601fb 8643bde0 8a3d8cf4 c0000056 Driver3+0×6dd8
b3c91ba0 bac608ac 8643bde0 89df432c 8a3d8cf4 Driver2+0×11fb
b3c91bc4 bac60d70 8643bde0 b3c91be4 00000001 Driver2+0×18ac
b3c91bdc 804e33d9 00000000 8643bde0 87dca810 Driver2+0×1d70
b3c91c00 b5765796 00000000 87dca810 8a6ccc50 nt!IopfCallDriver+0×31
b3c91c1c b5766176 89df432c 00000000 8a6ccc50 Driver1+0×9796
b3c91c64 b5765c28 89df432c 00000001 87dca801 Driver1+0xa176
b3c91ca4 804e38ff 00000000 8643bde0 00000000 Driver1+0×9c28
b3c91cd4 b4486dd8 8643bde0 89e65958 c0000001 nt!IopfCompleteRequest+0xa2
b3c91ce8 bac601fb 8643bde0 8a3d8cf4 c0000056 Driver3+0×6dd8
b3c91cfc bac608ac 8643bde0 89df432c 8a3d8cf4 Driver2+0×11fb
b3c91d20 bac60d70 8643bde0 b3c91d40 00000001 Driver2+0×18ac
b3c91d38 804e33d9 00000000 8643bde0 87dca810 Driver2+0×1d70
b3c91d5c b5765796 00000000 87dca810 8a6ccc50 nt!IopfCallDriver+0×31
b3c91d78 b5766176 89df432c 00000000 8a6ccc50 Driver1+0×9796
b3c91dc0 b5765c28 89df432c 00000001 87dca801 Driver1+0xa176
b3c91e00 804e38ff 00000000 8643bde0 00000000 Driver1+0×9c28
b3c91e30 b4486dd8 8643bde0 89e65958 c0000001 nt!IopfCompleteRequest+0xa2
b3c91e44 bac601fb 8643bde0 8a3d8cf4 c0000056 Driver3+0×6dd8
b3c91e58 bac608ac 8643bde0 89df432c 8a3d8cf4 Driver2+0×11fb
b3c91e7c bac60d70 8643bde0 b3c91e9c 00000001 Driver2+0×18ac
b3c91e94 804e33d9 00000000 8643bde0 87dca810 Driver2+0×1d70
b3c91eb8 b5765796 00000000 87dca810 8a6ccc50 nt!IopfCallDriver+0×31
b3c91ed4 b5766176 89df432c 00000000 8a6ccc50 Driver1+0×9796
b3c91f1c b5765c28 89df432c 00000001 87dca801 Driver1+0xa176
b3c91f5c 804e38ff 00000000 8643bde0 00000000 Driver1+0×9c28
b3c91f8c b4486dd8 8643bde0 89e65958 c0000001 nt!IopfCompleteRequest+0xa2
b3c91fa0 bac601fb 8643bde0 8a3d8cf4 c0000056 Driver3+0×6dd8
b3c91fb4 bac608ac 8643bde0 89df432c 8a3d8cf4 Driver2+0×11fb
b3c91fd8 bac60d70 8643bde0 b3c91ff8 00000001 Driver2+0×18ac
b3c91ff0 804e33d9 00000000 8643bde0 87dca810 Driver2+0×1d70
b3c92014 b5765796 00000000 87dca810 8a6ccc50 nt!IopfCallDriver+0×31
b3c92030 b5766176 89df432c 00000000 8a6ccc50 Driver1+0×9796
b3c92078 b5765c28 89df432c 00000001 87dca801 Driver1+0xa176
b3c920b8 804e38ff 00000000 8643bde0 00000000 Driver1+0×9c28
b3c920e8 b4486dd8 8643bde0 89e65958 c0000001 nt!IopfCompleteRequest+0xa2
b3c920fc bac601fb 8643bde0 8a3d8cf4 c0000056 Driver3+0×6dd8
b3c92110 bac608ac 8643bde0 89df432c 8a3d8cf4 Driver2+0×11fb
b3c92134 bac60d70 8643bde0 b3c92154 00000001 Driver2+0×18ac
b3c9214c 804e33d9 00000000 8643bde0 87dca810 Driver2+0×1d70
b3c92170 b5765796 00000000 87dca810 8a6ccc50 nt!IopfCallDriver+0×31
b3c9218c b5766176 89df432c 00000000 8a6ccc50 Driver1+0×9796
b3c921d4 b5765c28 89df432c 00000001 87dca801 Driver1+0xa176
b3c92214 804e38ff 00000000 8643bde0 00000000 Driver1+0×9c28
b3c92244 b4486dd8 8643bde0 89e65958 c0000001 nt!IopfCompleteRequest+0xa2
b3c92258 bac601fb 8643bde0 8a3d8cf4 c0000056 Driver3+0×6dd8
b3c9226c bac608ac 8643bde0 89df432c 8a3d8cf4 Driver2+0×11fb
b3c92290 bac60d70 8643bde0 b3c922b0 00000001 Driver2+0×18ac
b3c922a8 804e33d9 00000000 8643bde0 87dca810 Driver2+0×1d70
b3c922cc b5765796 00000000 87dca810 8a6ccc50 nt!IopfCallDriver+0×31
b3c922e8 b5766176 89df432c 00000000 8a6ccc50 Driver1+0×9796
b3c92330 b5765c28 89df432c 00000001 87dca801 Driver1+0xa176
b3c92370 804e38ff 00000000 8643bde0 00000000 Driver1+0×9c28
b3c923a0 b4486dd8 8643bde0 89e65958 c0000001 nt!IopfCompleteRequest+0xa2
b3c923b4 bac601fb 8643bde0 8a3d8cf4 c0000056 Driver3+0×6dd8
b3c923c8 bac608ac 8643bde0 89df432c 8a3d8cf4 Driver2+0×11fb
STACK_COMMAND: .tss 0×28 ; kb
CHKIMG_EXTENSION: !chkimg -lo 50 -d !nt
804e33b2-804e33b7 6 bytes - nt!IopfCallDriver
[ fe 4a 23 8a 42 23:e9 39 39 fa 33 cc ]
…생략
175 errors : !nt (804e33b2-80507724)
MODULE_NAME: Driver3
IMAGE_NAME: Driver3.sys
DEBUG_FLR_IMAGE_TIMESTAMP: 4a5c23df
FOLLOWUP_NAME: MachineOwner
MEMORY_CORRUPTOR: PATCH_Driver3
FAILURE_BUCKET_ID: MEMORY_CORRUPTION_PATCH_Driver3
BUCKET_ID: MEMORY_CORRUPTION_PATCH_Driver3
Followup: MachineOwner
———
보시는 그대로 Stack Overflow 입니다.( Stack Overflow 분석은 이곳을 참고하세요.) 특징적인 부분은 IofCallDriver를 후킹했다는 점입니다.
그럼 왜 Stack Overflow가 발생한것인가 한번 찾아보죠.
이러한 Stack의 경우 반복적인 부분을 유심히 관찰하는게 정말 중요합니다. Driver3+0×6dd8에서 호출한 IopfCompleteRequest 호출도중 Driver1+0×9c28가 호출됐다는 점에서 Completion Routine임을 추정할 수 있습니다. 문제는 이 Completion Routine은 다시 IopfCallDriver( Hooking Function이아닌 그냥 일반 호출 처럼 보이는 이유는 Bypass 되었다고 가정하시면 됩니다. Stack 구성에 대한 이야기는 다음에 또 얘기 하도록 하겠습니다.)를 호출한다는 점입니다. 그렇다면 왜 이렇게 구성이 되었을까?
IopfCallDriver가 후킹되었고 그 내부에서 IopfCompleteRequest를 호출했다는 점을 볼때 해당 I/O을 Drop 하는 목적임을 알 수 있습니다. 즉 다음 Stack으로 해당 I/O를 전달하지 않게 하기 위한 것이지요. 위의 Stack을 볼때 해당 I/O가 Drop 당했을 경우 또는 원하는 Data를 얻지 못할 경우를 대비해 Driver1 드라이버의 개발자는 다시 Irp를 전달하도록 드라이버를 구성하였음을 알 수 있습니다. 이러한 현상이 반복되면서 Stack Overflow는 발생하게 됩니다.
IopfCallDriver를 Hooking한 이유는 I/O Drop이 목적이라면 Driver1 드라이버는 왜 Completion Routine에서 Irp재 전송하는가 !!
그 해답은 Usb Data 전송 방식에 있습니다.
USB에는 크게 4가지 전송방식이 있습니다.
- Control
- Bulk
- Interrupt
- Isochronous
여기서 사용한 방식, 즉 Irp에 Urb를 담아 I/O를 전달하고 그 I/O가 비동기 적으로 Completion 될때 데이터를 받아오고 그리고 그 Data 값에 따라서 Completion Routine에서 재요청 또는 완료를 시도하는 방식, 바로 Bulk Or Interrupt 방식입니다.
아래 코드를 보면 Urb에 Header에 URB_FUNCTION_BULK_OR_INTERRUPT_TRANSFER( 0×00000009 ) 값을 넣어주는 코드를 확인 할 수 있습니다.
3: kd> ub Driver1+0×9796 L30
Driver1+0×96df:
b57656df b89a0000c0 mov eax,0C000009Ah
b57656e4 e9c0000000 jmp Driver1+0×97a9 (b57657a9)
b57656e9 8b45fc mov eax,dword ptr [ebp-4]
b57656ec 89868c000000 mov dword ptr [esi+8Ch],eax
b57656f2 8b868c000000 mov eax,dword ptr [esi+8Ch]
b57656f8 33d2 xor edx,edx
b57656fa f775fc div eax,dword ptr [ebp-4]
b57656fd 0faf45fc imul eax,dword ptr [ebp-4]
b5765701 89868c000000 mov dword ptr [esi+8Ch],eax
b5765707 8b462c mov eax,dword ptr [esi+2Ch]
b576570a 6a01 push 1
b576570c 66c740020900 mov word ptr [eax+2],9
b5765712 8b462c mov eax,dword ptr [esi+2Ch]
b5765715 66c7004800 mov word ptr [eax],48h
b576571a 8b87b8000000 mov eax,dword ptr [edi+0B8h]
b5765720 8b4e2c mov ecx,dword ptr [esi+2Ch]
b5765723 8b440318 mov eax,dword ptr [ebx+eax+18h]
b5765727 5b pop ebx
b5765728 894110 mov dword ptr [ecx+10h],eax
b576572b 8b462c mov eax,dword ptr [esi+2Ch]
b576572e 8b8e8c000000 mov ecx,dword ptr [esi+8Ch]
b5765734 68a05976b5 push offset Driver1+0×99a0 (b57659a0)
b5765739 894818 mov dword ptr [eax+18h],ecx
b576573c 8b462c mov eax,dword ptr [esi+2Ch]
b576573f 83602000 and dword ptr [eax+20h],0
b5765743 8b462c mov eax,dword ptr [esi+2Ch]
b5765746 8b8e94000000 mov ecx,dword ptr [esi+94h]
b576574c 89481c mov dword ptr [eax+1Ch],ecx
b576574f 8b462c mov eax,dword ptr [esi+2Ch]
b5765752 c7401402000000 mov dword ptr [eax+14h],2
b5765759 8b462c mov eax,dword ptr [esi+2Ch]
b576575c 83602400 and dword ptr [eax+24h],0
b5765760 ff762c push dword ptr [esi+2Ch]
b5765763 895e0c mov dword ptr [esi+0Ch],ebx
b5765766 ff7634 push dword ptr [esi+34h]
b5765769 56 push esi
b576576a e85b0e0000 call Driver1+0xa5ca (b57665ca)
b576576f 8b8714010000 mov eax,dword ptr [edi+114h]
b5765775 8b4d24 mov ecx,dword ptr [ebp+24h]
b5765778 8d44080c lea eax,[eax+ecx+0Ch]
b576577c 50 push eax
b576577d 56 push esi
b576577e ff7518 push dword ptr [ebp+18h]
b5765781 57 push edi
b5765782 e829000000 call Driver1+0×97b0 (b57657b0)
b5765787 8b5634 mov edx,dword ptr [esi+34h]
b576578a 8b8fa4000000 mov ecx,dword ptr [edi+0A4h]
b5765790 ff1558c375b5 call dword ptr [Driver1+0x358 (b575c358)] // IopfCallDriver
Enjoy Debugging
최근 답글