WinDbg 디버깅2013. 11. 22. 21:46
반응형

커널 메모리가 손상되면 분석하기 매우 곤란한 경우가 많은데요.

그중에서 분석이 가능한 한 가지 상황에 대해 분석을 진행해 보겠습니다.


이번 분석의 초식은 "깨진 메모리 앞쪽 메모리를 의심하라" 입니다.


MyDrv.sys가 사용중인 메모리가 손상돼 발생한 덤프입니다.


0: kd> !analyze -v

*******************************************************************************

*                                                                             *

*                        Bugcheck Analysis                                    *

*                                                                             *

*******************************************************************************


DRIVER_IRQL_NOT_LESS_OR_EQUAL (d1)

An attempt was made to access a pageable (or completely invalid) address at an

interrupt request level (IRQL) that is too high.  This is usually

caused by drivers using improper addresses.

If kernel debugger is available get stack backtrace.

Arguments:

Arg1: 00000008, memory referenced

Arg2: 00000002, IRQL

Arg3: 00000000, value 0 = read operation, 1 = write operation

Arg4: 8c032fa5, address which referenced memory


Debugging Details:

------------------

READ_ADDRESS:  00000008 

CURRENT_IRQL:  2


FAULTING_IP: 

MyDrv!GetListEntry+85 

8c032fa5 3b5108          cmp     edx,dword ptr [ecx+8]


DEFAULT_BUCKET_ID:  WIN7_DRIVER_FAULT

BUGCHECK_STR:  0xD1

PROCESS_NAME:  SomeProcess.exe


TRAP_FRAME:  bdf939b4 -- (.trap 0xffffffffbdf939b4)

ErrCode = 00000000

eax=00000000 ebx=8c0344b0 ecx=00000000 edx=c339fdc0 esi=0101ed94 edi=bdf93b60

eip=8c032fa5 esp=bdf93a28 ebp=bdf93a4c iopl=0         nv up ei pl nz na pe cy

cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010207

MyDrv!GetListEntry+0x85:

8c032fa5 3b5108          cmp     edx,dword ptr [ecx+8] ds:0023:00000008=????????

Resetting default scope


LAST_CONTROL_TRANSFER:  from 8c032fa5 to 83248b7f


STACK_TEXT:  

bdf939b4 8c032fa5 badb0d00 c339fdc0 00000000 nt!KiTrap0E+0x1b3

bdf93a4c 8c03331d c339fdc0 a0fa8b08 bdf93a68 MyDrv!GetListEntry+0x85 

bdf93a5c 8c0325fc c339fdc0 bdf93a7c 8c0364e5 MyDrv!GetEntryTable+0xd 

...

bdf93c10 76e270f4 0101f08c 00020019 0101eda0 nt!KiSystemServicePostCall

WARNING: Frame IP not in any known module. Following frames may be wrong.

0101ef94 00000000 00000000 00000000 00000000 0x76e270f4


STACK_COMMAND:  kb


FOLLOWUP_IP: 

MyDrv!GetListEntry+85 

8c032fa5 3b5108          cmp     edx,dword ptr [ecx+8]


SYMBOL_STACK_INDEX:  1

SYMBOL_NAME:  MyDrv!GetListEntry+85

FOLLOWUP_NAME:  MachineOwner

MODULE_NAME: MyDrv

IMAGE_NAME:  MyDrv.sys


DEBUG_FLR_IMAGE_TIMESTAMP:  5099ff75

FAILURE_BUCKET_ID:  0xD1_MyDrv!GetListEntry+85

BUCKET_ID:  0xD1_MyDrv!GetListEntry+85

Followup: MachineOwner

---------




.trap 명령으로 죽은 시점을 복원합니다.


0: kd> .trap 0xffffffffbdf939b4

ErrCode = 00000000

eax=00000000 ebx=8c0344b0 ecx=00000000 edx=c339fdc0 esi=0101ed94 edi=bdf93b60

eip=8c032fa5 esp=bdf93a28 ebp=bdf93a4c iopl=0         nv up ei pl nz na pe cy

cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010207

MyDrv!GetListEntry+0x85:

8c032fa5 3b5108          cmp     edx,dword ptr [ecx+8] ds:0023:00000008=????????



GetListEntry 함수에서 죽었는데 변수를 살펴보면 pListEntry 가 NULL이어서 문제가 발생했습니다.


0: kd> dv

     pListHead = 0x8c038d00 [ 0x89e95988 - 0x864f3ea8 ]

     pListEntry = 0x00000000



pListEntry는 pListHead에서 연결되는 리스트이므로 pListHead를 살펴봅니다.


0: kd> dl 0x8c038d00 

8c038d00  89e95988 864f3ea8 8c038d08 8c038d08

89e95988  00000000 00000000 00000000 00000000



pListHead가 가리키는 89e95988의 내용은 더블 링크드 리스트라서 00000000이면 안되고 어떤 포인터가 들어 있어야 하는데 00000000 이 들어 있습니다.


기존에 있던 포인터 값이 0으로 덮어써진 것으로 추정됩니다.


0: kd> db 89e95988

89e95988  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

89e95998  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

89e959a8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

89e959b8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

89e959c8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

89e959d8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

89e959e8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................

89e959f8  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................



어떤 모듈이 이 영역을 덮어쓰는지 추적합니다.

일단 메모리 정보를 확인합니다.


0: kd> !pool 89e95988  

Pool page 89e95988 region is Nonpaged pool


89e95808 doesn't look like a valid small pool allocation, checking to see

if the entire page is actually part of a large page allocation...


89e95808 is freed (or corrupt) pool

Bad previous allocation size @89e95808, last size was 0


...


Pool page [ 89e95000 ] is __inVALID.


Analyzing linked list...

[ 89e95000 ]: invalid previous size [ 0x43 ] should be [ 0x0 ]

[ 89e95000 --> 89e95c10 (size = 0xc10 bytes)]: Corrupt region


Scanning for single bit errors...

None found



메모리 헤더까지 손상되어 정보가 나오지 않습니다.


바로 앞 페이지의 정보를 확인합니다. 

보통은 앞의 메모리를 사용하는 모듈이 뒤 부분의 메모리를 손상시키기 때문입니다.


0: kd> !pool 89e94378 

Pool page 89e94378 region is Nonpaged pool

*89e89000 : large page allocation, Tag is Ddk , size is 0xc808 bytes

Pooltag Ddk  : Default for driver allocated memory (user's of ntddk.h)



Ddk 태그를 가진 메모리가 확인됩니다. 이 부분은 손상되지 않았습니다.

이 메모리를 사용하는 모듈이 메모리를 손상했을 가능성이 높습니다.


89e89000 메모리를 들여다보면 특정한 패턴을 가지고 있고 이 패턴이 0xc808 길이를 넘어서 이어집니다.

따라서 이 메모리를 사용하던 모듈이 메모리 경계를 넘어서 메모리를 손상시켰다고 가정할 수 있습니다.


Ddk는 디폴트 태그라서 태그로는 어떤 모듈이 사용중인지 알 수 없으니...

시스템에 로드된 모듈중에서 89e89000 라는 메모리 포인터를 가지고 있는 모듈을 검색합니다.


0: kd> !for_each_module s @#Base @#End 00 90 e8 89

Page 69a9 not present in the dump file. Type ".hh dbgerr004" for details

Page 6414d not present in the dump file. Type ".hh dbgerr004" for details

Page 63b60 not present in the dump file. Type ".hh dbgerr004" for details

bebb5424  00 90 e8 89 21 00 00 00-00 00 00 00 01 00 00 00  ....!...........



다행히 bebb5424 하나만 찾아지네요.

bebb5424 위치에서 89e89000 포인터를 보관하고 있습니다.


bebb5424 은 어떤 모듈인지 확인합니다.


0: kd> u bebb5424

NotMyDrv+0x6424:

bebb5424 0090e8892100    add     byte ptr [eax+2189E8h],dl

bebb542a 0000            add     byte ptr [eax],al

bebb542c 0000            add     byte ptr [eax],al

bebb542e 0000            add     byte ptr [eax],al

bebb5430 0100            add     dword ptr [eax],eax

bebb5432 0000            add     byte ptr [eax],al

bebb5434 0800            or      byte ptr [eax],al

bebb5436 0000            add     byte ptr [eax],al



NotMyDrv.sys 모듈의 내부로 나옵니다.

NotMyDrv.sys 내부의 어떤 위치인지 확인합니다.


0: kd> lmvm NotMyDrv

start    end        module name

bebaf000 bebbe780   NotMyDrv     (no symbols)           

    Loaded symbol image file: NotMyDrv.sys

    Image path: \??\C:\Windows\system32\Drivers\NotMyDrv.sys

    Image name: NotMyDrv.sys


0: kd> !dh bebaf000


File Type: EXECUTABLE IMAGE

FILE HEADER VALUES

     14C machine (i386)

       5 number of sections

4D880A01 time date stamp Tue Mar 22 11:31:29 2011


       0 file pointer to symbol table

       0 number of symbols

      E0 size of optional header

     10E characteristics

            Executable

            Line numbers stripped

            Symbols stripped

            32 bit word machine


OPTIONAL HEADER VALUES

     10B magic #

    6.00 linker version

    6300 size of code

    9200 size of initialized data

       0 size of uninitialized data

    50D3 address of entry point

     280 base of code

         ----- new -----

00010000 image base

      80 section alignment

      80 file alignment

       1 subsystem (Native)

    5.00 operating system version

    5.00 image version

    1.10 subsystem version

    F780 size of image

     280 size of headers

   16350 checksum

00040000 size of stack reserve

00001000 size of stack commit

00100000 size of heap reserve

00001000 size of heap commit

       0  DLL characteristics

       0 [       0] address [size] of Export Directory

    E680 [      3C] address [size] of Import Directory

    EC00 [     4A8] address [size] of Resource Directory

       0 [       0] address [size] of Exception Directory

       0 [       0] address [size] of Security Directory

    F100 [     4F8] address [size] of Base Relocation Directory

     370 [      1C] address [size] of Debug Directory

       0 [       0] address [size] of Description Directory

       0 [       0] address [size] of Special Directory

       0 [       0] address [size] of Thread Storage Directory

       0 [       0] address [size] of Load Configuration Directory

       0 [       0] address [size] of Bound Import Directory

     280 [      F0] address [size] of Import Address Table Directory

       0 [       0] address [size] of Delay Import Directory

       0 [       0] address [size] of COR20 Header Directory

       0 [       0] address [size] of Reserved Directory



SECTION HEADER #1

   .text name

    5D18 virtual size

     280 virtual address

    5D80 size of raw data

     280 file pointer to raw data

       0 file pointer to relocation table

       0 file pointer to line numbers

       0 number of relocations

       0 number of line numbers

68000020 flags

         Code

         Not Paged

         (no align specified)

         Execute Read



Debug Directories(1)

     Type       Size     Address  Pointer

     cv           8d           0     f780 [Debug data not mapped]



SECTION HEADER #2

   .data name

    8680 virtual size

    6000 virtual address

    8680 size of raw data

    6000 file pointer to raw data

       0 file pointer to relocation table

       0 file pointer to line numbers

       0 number of relocations

       0 number of line numbers

C8000040 flags

         Initialized Data

         Not Paged

         (no align specified)

         Read Write


SECTION HEADER #3

    INIT name

     556 virtual size

    E680 virtual address

     580 size of raw data

    E680 file pointer to raw data

       0 file pointer to relocation table

       0 file pointer to line numbers

       0 number of relocations

       0 number of line numbers

E2000020 flags

         Code

         Discardable

         (no align specified)

         Execute Read Write


SECTION HEADER #4

   .rsrc name

     4A8 virtual size

    EC00 virtual address

     500 size of raw data

    EC00 file pointer to raw data

       0 file pointer to relocation table

       0 file pointer to line numbers

       0 number of relocations

       0 number of line numbers

42000040 flags

         Initialized Data

         Discardable

         (no align specified)

         Read Only


SECTION HEADER #5

  .reloc name

     61E virtual size

    F100 virtual address

     680 size of raw data

    F100 file pointer to raw data

       0 file pointer to relocation table

       0 file pointer to line numbers

       0 number of relocations

       0 number of line numbers

42000040 flags

         Initialized Data

         Discardable

         (no align specified)

         Read Only




bebb5424은 bebaf000 + 6000 에서 시작하는 data SECTION에 위치하는 메모리입니다.

NotMyDrv.sys의 데이터 영역에 있으므로 이 드라이버에서 사용하는 전역변수로 추정됩니다.


결국 NotMyDrv.sys라는 드라이버가 MyDrv.sys가 사용하는 메모리를 overwrite해서 발생하는 문제로 볼 수 있습니다.



반응형
Posted by GreeMate