BLOG main image
분류 전체보기 (17)
Life (2)
Dump Analysis (9)
Reversing (1)
Windows (1)
Book (2)
Reference (2)
Visitors up to today!
Today hit, Yesterday hit
daisy rss
tistory 티스토리 가입하기!
'2018/07/12'에 해당되는 글 1건
2018. 7. 12. 23:14

이번 덤프는 BugCheck 0x1A: MEMORY_MANAGEMENT다.

0x1A는 커널에서 메모리 주소를 관리하는 과정 중에 문제가 생기면 발생한다. 다양한 원인이 있을 수 있는데, 예를 들어 메모리 관리자가 특정 메모리 주소를 변환하려고 페이지 테이블 엔트리(PTE)를 참조할 때 엔트리 손상이 감지되면 이 오류 코드를 발생시킨다.

대부분 커널 내부 코드에서 발생하기 때문에 분석 자체가 굉장히 어렵고 불가능한 경우도 많다. 물론 시작도 안하고 포기할 수는 없으니 일단 시작해보자.

kd> !analyze -v

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

*      *

*      Bugcheck Analysis   *

*      *

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

MEMORY_MANAGEMENT (1a)

# Any other values for parameter 1 must be individually examined.

Arguments:

Arg1: 00041287, An illegal page fault occurred while holding working set

synchronization.

Parameter 2 contains the referenced virtual address.

Arg2: 34333231

Arg3: 00000000

Arg4: 00000000

Debugging Details:

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

BUGCHECK_STR: 0x1a_41287

DEFAULT_BUCKET_ID: WIN7_DRIVER_FAULT

PROCESS_NAME: WerFault.exe

CURRENT_IRQL: 0

ANALYSIS_VERSION: 6.3.9600.16384 (debuggers(dbg).130821-1623) amd64fre

TRAP_FRAME: aa9ff594 -- (.trap 0xffffffffaa9ff594)

ErrCode = 00000000

eax=34333231 ebx=85c5c000 ecx=29a00000 edx=0f349000 esi=00000000 edi=831a7100

eip=830d8f0f esp=aa9ff608 ebp=aa9ff618 iopl=0 nv up ei pl nz na po nc

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

nt!MiAllocateAccessLog+0x54:

830d8f0f 3930 cmp dword ptr [eax],esi

ds:0023:34333231=????????

Resetting default scope

LAST_CONTROL_TRANSFER: from 8307ca78 to 830c99ad

STACK_TEXT:

aa9ff57c 8307ca78 00000000 34333231 00000000 nt!MmAccessFault+0x104

aa9ff57c 830d8f0f 00000000 34333231 00000000 nt!KiTrap0E+0xdc

aa9ff618 830c111e c0699800 84a94e2c 842f4804 nt!MiAllocateAccessLog+0x54

aa9ff664 830c7907 c0699800 00000000 85a9b630 nt!MiLogPageAccess+0x40

aa9ff8d4 8326b0c4 d3300000 cdf693f0 00000000 nt!MmUnmapViewInSystemCache+0x1c1

aa9ff90c 830c97b5 85a9b630 85e8f5a8 00000000 nt!CcUnmapVacb+0x18c

aa9ff94c 830c76ff 01e8f5a8 831a7400 00000001 nt!CcUnmapVacbArray+0x292

aa9ff96c 830c7d9c 831a7400 00000000 85e8f5a8 nt!CcUnmapAndPurge+0x2e

aa9ff988 830c7514 00000001 85de1f80 00000000 nt!CcDeleteSharedCacheMap+0x82

aa9ff9bc 830e74a6 aa9ff9ec 812c5e91 01000000 nt!CcWriteBehind+0x715

aa9ffa1c 83261c3f 87d9af80 00000000 00000000 nt!CcWaitForUninitializeCacheMap+0x15e

aa9ffb3c 832613c9 aa9ffb90 00000007 00000000 nt!MmCreateSection+0x339

aa9ffbb0 936eef93 0010d600 00000007 00000000 nt!NtCreateSection+0x16e

aa9ffc10 83079896 0010d600 00000007 00000000 SomeDrv+0xdf93

aa9ffc10 76df70f4 0010d600 00000007 00000000 nt!KiSystemServicePostCall

0010d720 00000000 00000000 00000000 00000000 0x76df70f4

STACK_COMMAND: kb

FOLLOWUP_IP:

SomeDrv+df93

936eef93 8bf0 mov esi,eax

SYMBOL_STACK_INDEX: d

SYMBOL_NAME: SomeDrv+df93

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: SomeDrv

IMAGE_NAME: SomeDrv.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 53268cfa

FAILURE_BUCKET_ID: 0x1a_41287_SomeDrv+df93

BUCKET_ID: 0x1a_41287_SomeDrv+df93

ANALYSIS_SOURCE: KM

FAILURE_ID_HASH_STRING: km:0x1a_41287_SomeDrv+df93

FAILURE_ID_HASH: {385bcdbd-2174-4449-cfff-dcc030b0a015}

Followup: MachineOwner

---------


오류 코드 0x1A만 보면 마음이 무겁다. 분석도 어렵고 고통스러울 뿐 아니라 들인 시간에 비해 소득이 없는 경우가 많기 때문이다.

경험상 커널 자체적인 문제보다 외부 모듈에서 하필 메모리 주소 관리 영역을 깨 버려 발생한 경우가 대부분인데 커널 내부 깊숙한 곳에서 오류가 발생하기 때문에 메모리 손상에 대한 증거가 남아 있지 않는 경우가 많다.

그래도 분석이 가능한 경우도 있으니 BugCode의 파라미터 정보부터 살펴보자.

Arg1: 00041287, An illegal page fault occurred while holding working set synchronization. Parameter 2 contains the referenced virtual address.

Arg2: 34333231


Arg1 값은 세부 오류 코드로 다양한 값이 존재하는데 도움말(F1)의 검색 탭에서 Bug Check 0x1A 로 검색하면 이 파라미터 값이 의미하는 바를 알 수 있다.

워킹셋 동기화를 잡고 있는 상태에서 접근한 페이지 정보에 문제가 있었는데, Arg2에 문제를 일으킨 주소가 34333231이라고 말해준다.

물론, 분석에 별 도움은 되지 않는다. 단지 34333231이라는 값이 정상적인 주소 값 형태가 아니기 때문에 누군가가 또 메모리를 손상 시켰으리라 의심할 따름이다.

analyze 결과의 아래 FAILURE_BUCKET_ID를 보면 0x1a_41287_SomeDrv+df93이 있다. SomeDrv로 인해 문제가 발생한 것처럼 보여주고 있다.

나는 이 정보도 크게 신뢰하지 않는다. 왜냐하면 WinDbg는 단지 콜 스택에서 nt 커널 모듈을 제외하고 마지막 모듈을 보여주기 때문이다. 당연하게도 메모리 손상 이슈에서는 전혀 다른 모듈이 범인인 경우가 매우 많다.

언제나처럼 .trap 명령을 사용해서 문제가 발생한 부분으로 컨텍스트 정보를 설정해보자.

kd> .trap 0xffffffffaa9ff594

ErrCode = 00000000

eax=34333231 ebx=85c5c000 ecx=29a00000 edx=0f349000 esi=00000000 edi=831a7100

eip=830d8f0f esp=aa9ff608 ebp=aa9ff618 iopl=0 nv up ei pl nz na po nc

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

nt!MiAllocateAccessLog+0x54:

830d8f0f 3930 cmp dword ptr [eax],esi

ds:0023:34333231=????????


eax에 있는 34333231 주소가 접근할 수 없는 영역이라 문제가 발생했다고 한다.

이제 kv 명령어로 파라미터를 포함한 콜 스택을 확인해보자.

kd> kv

*** Stack trace for last set context - .thread/.cxr resets it

# ChildEBP RetAddr Args to Child

00 aa9ff618 830c111e c0699800 84a94e2c 842f4804 nt!MiAllocateAccessLog+0x54

01 aa9ff664 830c7907 c0699800 00000000 85a9b630 nt!MiLogPageAccess+0x40

02 aa9ff8d4 8326b0c4 d3300000 cdf693f0 00000000 nt!MmUnmapViewInSystemCache+0x1c1

03 aa9ff90c 830c97b5 85a9b630 85e8f5a8 00000000 nt!CcUnmapVacb+0x18c

04 aa9ff94c 830c76ff 01e8f5a8 831a7400 00000001 nt!CcUnmapVacbArray+0x292

05 aa9ff96c 830c7d9c 831a7400 00000000 85e8f5a8 nt!CcUnmapAndPurge+0x2e

06 aa9ff988 830c7514 00000001 85de1f80 00000000 nt!CcDeleteSharedCacheMap+0x82

07 aa9ff9bc 830e74a6 aa9ff9ec 812c5e91 01000000 nt!CcWriteBehind+0x715

08 aa9ffa1c 83261c3f 87d9af80 00000000 00000000 nt!CcWaitForUninitializeCacheMap+0x15e

09 aa9ffb3c 832613c9 aa9ffb90 00000007 00000000 nt!MmCreateSection+0x339

0a aa9ffbb0 936eef93 0010d600 00000007 00000000 nt!NtCreateSection+0x16e

0b aa9ffc10 83079896 0010d600 00000007 00000000 SomeDrv+0xdf93

0c aa9ffc10 76df70f4 0010d600 00000007 00000000 nt!KiSystemServicePostCall (FPO: [0,3] TrapFrame @ aa9ffc34)

0d 0010d720 00000000 00000000 00000000 00000000 0x76df70f4


정말이지 nt 커널 함수만 잔뜩 있는 이런 콜 스택을 보면 한숨이 절로 나온다.

nt!MiAllocateAccessLog+0x54에서 문제가 발생했으니 여기 안에서 메모리 손상과 관련된 단서가 발견되기를 기대해보자.

다음은 nt!MiAllocateAccessLog+0x54 부분을 디스어셈블링한 내용이다.

kd> u nt!MiAllocateAccessLog L1d

nt!MiAllocateAccessLog:

830d8ebb 8bff mov edi,edi

830d8ebd 55 push ebp

830d8ebe 8bec mov ebp,esp

830d8ec0 51 push ecx

830d8ec1 51 push ecx

830d8ec2 8b0d80b41683 mov ecx,dword ptr [nt!MmAvailablePages(8316b480)]

830d8ec8 b800040000 mov eax,400h

830d8ecd 53 push ebx

830d8ece 56 push esi

830d8ecf 3bc8 cmp ecx,eax

830d8ed1 721d jb nt!MiAllocateAccessLog+0x35 (830d8ef0)

830d8ed3 8b0d00b51683 mov ecx,dword ptr [nt!MmResidentAvailablePages(8316b500)]

830d8ed9 3bc8 cmp ecx,eax

830d8edb 7c13 jl nt!MiAllocateAccessLog+0x35 (830d8ef0)

830d8edd e84badffff call nt!MI_FREE_NON_PAGED_POOL_PAGES_LEFT(830d3c2d)

830d8ee2 c745fc00100000 mov dword ptr [ebp-4],1000h

830d8ee9 3d00080000 cmp eax,800h

830d8eee 7307 jae nt!MiAllocateAccessLog+0x3c (830d8ef7)

830d8ef0 c745fc00020000 mov dword ptr [ebp-4],200h

830d8ef7 8b5f08 mov ebx,dword ptr [edi+8]

830d8efa 33f6 xor esi,esi

830d8efc 3bde cmp ebx,esi

830d8efe 741e je nt!MiAllocateAccessLog+0x63 (830d8f1e)

830d8f00 817dfc00020000 cmp dword ptr [ebp-4],200h

830d8f07 8b03 mov eax,dword ptr [ebx] // 2) ebx eax

830d8f09 7408 je nt!MiAllocateAccessLog+0x58 (830d8f13)

830d8f0b 3bc6 cmp eax,esi

830d8f0d 740f je nt!MiAllocateAccessLog+0x63 (830d8f1e)

830d8f0f 3930 cmp dword ptr [eax],esi // 1) eax 설정된 값과 esi 비교하다 문제 발생


1) eax에 있던 값은 34333231이며 유효하지 않은 주소 값이다. cmp dword ptr [eax],esi 명령으로 eax에 있는 34333231 주소에서 값을 읽으려다 문제가 발생했다. eax 레지스터 내용을 확인해보자.

kd> r eax

Last set context:

eax=34333231

 

kd> dd eax L1

34333231 ????????


34333231??로 접근할 수 없는 영역이다. eax34333231이 설정된 원인을 찾기 위해 약간 앞 쪽 코드를 살펴보면 2)번에서 ebx를 통해 설정하고 있다.

ebx를 한 번 살펴보자.

kd> r ebx

Last set context:

ebx=85c5c000

 

kd> dd 85c5c000 L1

85c5c000 34333231


ebx에는 85c5c000 값이 있고 85c5c000에 찾고 있던 34333231 값이 담겨 있다.

85c5c000은 값만 보면 유효한 주소 값 형태로 보인다. 일반적으로 정상적인 주소 값의 경우 xxxxxxx0, xxxxxxx8로 끝난다.

유효한 주소 값은 스택 상의 주소나 동적 할당된 메모리 혹은 모듈 내의 주소인 경우가 많다.

!thread 명령으로 현재 스레드 정보를 보면 문제가 발생한 프로세스 및 현재 스레드의 스택 정보를 알 수 있다.

kd> !thread

THREAD 88eac540 Cid 0d10.0d14 Teb: 7ffdf000 Win32Thread: fd601700 RUNNING on processor 2

Not impersonating

DeviceMap ae1d7a28

Owning Process 890b22a8 Image: WerFault.exe

Attached Process N/A Image: N/A

Wait Start TickCount 6552 Ticks: 0

Context Switch Count 9853 IdealProcessor: 3

UserTime 00:00:00.015

KernelTime 00:00:05.116

Win32 Start Address 0x006f80c7

Stack Init aa9ffed0 Current aa9ff6a8 Base aaa00000 Limit aa9fd000 Call 0

Priority 8 BasePriority 7 UnusualBoost 0 ForegroundBoost 0 IoPriority 2 PagePriority 5

ChildEBP RetAddr Args to Child

aa9ff57c 8307ca78 00000000 34333231 00000000 nt!MmAccessFault+0x104

aa9ff57c 830d8f0f 00000000 34333231 00000000 nt!KiTrap0E+0xdc (FPO: [0,0] TrapFrame @ aa9ff594)

aa9ff618 830c111e c0699800 84a94e2c 842f4804 nt!MiAllocateAccessLog+0x54

aa9ff664 830c7907 c0699800 00000000 85a9b630 nt!MiLogPageAccess+0x40

aa9ff8d4 8326b0c4 d3300000 cdf693f0 00000000 nt!MmUnmapViewInSystemCache+0x1c1

aa9ff90c 830c97b5 85a9b630 85e8f5a8 00000000 nt!CcUnmapVacb+0x18c

aa9ff94c 830c76ff 01e8f5a8 831a7400 00000001 nt!CcUnmapVacbArray+0x292

aa9ff96c 830c7d9c 831a7400 00000000 85e8f5a8 nt!CcUnmapAndPurge+0x2e

aa9ff988 830c7514 00000001 85de1f80 00000000 nt!CcDeleteSharedCacheMap+0x82

aa9ff9bc 830e74a6 aa9ff9ec 812c5e91 01000000 nt!CcWriteBehind+0x715

aa9ffa1c 83261c3f 87d9af80 00000000 00000000 nt!CcWaitForUninitializeCacheMap+0x15e

aa9ffb3c 832613c9 aa9ffb90 00000007 00000000 nt!MmCreateSection+0x339

aa9ffbb0 936eef93 0010d600 00000007 00000000 nt!NtCreateSection+0x16e

aa9ffc10 83079896 0010d600 00000007 00000000 SomeDrv+0xdf93

aa9ffc10 76df70f4 0010d600 00000007 00000000 nt!KiSystemServicePostCall (FPO:[0,3] TrapFrame @ aa9ffc34)

0010d720 00000000 00000000 00000000 00000000 0x76df70f4


Stack 주소 영역은 Limit aa9fd000부터 Base aaa00000까지라고 나온다.

또한 lmva 명령으로 모듈 내의 주소인지도 확인 가능하다.

kd> lmva 85c5c000

Browse full module list

start end module name


아무런 출력 결과가 없다. 일치되는 모듈 주소가 없다는 의미다. 그렇다면 동적으로 할당된 메모리 주소일 가능성이 높다.

!pool 명령을 사용해서 확인해보자.

kd> !pool 85c5c000

Pool page 85c5c000 region is Nonpaged pool

*85c5c000 : large page allocation, tag is MmAc, size is 0x1000 bytes

Pooltag MmAc : Mm access log buffers, Binary : nt!mm


역시나 MmAc 풀 태그로 할당된 Nonpaged 풀이라고 친절하게 알려 준다. 풀 태그 설명을 보니 Mm access log buffers이고, 85c5c000 값은 MiAllocateAccessLog 내에서 사용된 값이니 정상적인 값일 것이다.

그렇다면 ebx에 설정된 85c5c000은 정상이었는데 85c5c000의 값을 누군가 34333231로 덮어 썼을 가능성이 매우 높다.

보통 이런 외부 모듈에 의한 메모리 손상은 주로 다음 2가지 시나리오에 의해 발생한다.

1.    외부 모듈이 메모리 주소 앞쪽 부분부터 문제 발생 위치까지 덮어 썼을 가능성

2.    외부 모듈이 문제 발생 위치만 덮어 썼을 가능성

 

흔히 1번 시나리오가 발생 빈도도 높고 메모리 앞쪽 부분을 살펴보면 원인을 찾을 가능성도 높다. 반면에 2번 같은 경우에는 증거를 찾기가 무척 어려워 분석이 불가능한 경우가 많다.

희망을 가지고 85c5c000의 앞쪽 메모리를 한 번 살펴보자.

100 bytes 정도 앞의 값을 !pool 명령으로 보면 앞 쪽에 할당된 풀 정보를 함께 확인할 수 있다.

kd> !pool 85c5c000-100

Pool page 85c5bf00 region is Nonpaged pool

85c5b000 size: 270 previous size: 0 (Free ) Irp

85c5b270 size: 8 previous size: 270 (Free) .(..

85c5b278 size: 128 previous size: 8 (Allocated) Ntfi

85c5b3a0 size: 140 previous size: 128 (Allocated) Io Process: 887dfd40

85c5b4e0 size: 10 previous size: 140 (Free) Io

85c5b4f0 size: 28 previous size: 10 (Allocated) ABss

85c5b518 size: b8 previous size: 28 (Allocated) File (Protected)

85c5b5d0 size: 298 previous size: b8 (Allocated) AbcH

85c5b868 size: 118 previous size: 298 (Allocated) AbcH

85c5b980 size: 8 previous size: 118 (Free) Ifs

85c5b988 size: 28 previous size: 8 (Allocated) ABss

85c5b9b0 size: a8 previous size: 28 (Allocated) File (Protected)

85c5ba58 size: 8 previous size: a8 (Free) Ifs

85c5ba60 size: 198 previous size: 8 (Free ) Ifs

*85c5bbf8 size: 408 previous size: 198 (Allocated) *BaDr

Owning component : Unknown (update pooltag.txt)


85c5bbf8 BaDr 풀 태그와 함께 408 바이트로 할당된 풀이 보인다. 직감적으로 이 곳에 중요한 단서가 있음이 느껴진다.

db 명령을 통해 BaDr 풀 영역을 확인해보자.

kd> db 85c5bbf8 L408

85c5bbf8 33 00 81 04 42 61 44 72-3b 3b 3b 3b f8 0a 88 01 3...BaDr;;;;....

85c5bc08 f8 0a 88 01 f3 0a 88 01-3b 3b c4 88 3b 88 01 a7 ........;;..;...

85c5bc18 3b 01 d0 ec be 02 3b 3b-02 3b 18 3b 30 3b 04 ee ;.....;;.;.;0;..

85c5bc28 be 02 3b 3b 3b 3b 3b 3b-c8 ed be 02 cc 6f e0 76 ..;;;;;;.....o.v

85c5bc38 3b 3b 3b 3b 3b 3b d0 58-2a c0 65 96 76 d0 58 2a ;;;;;;.X*.e.v.X*

85c5bc48 3b 3b c0 65 96 76 e4 ed-be 02 09 d9 8e 76 c0 65 ;;.e.v.......v.e

85c5bc58 96 76 3b 3b f5 0a 44 76-9d 69 96 a4 58 ee be 02 .v;;..Dv.i..X...

85c5bc68 b5 d5 8e 76 3c 02 3b 1c-ee be 02 34 ee be 02 3b ...v<.;....4...;

85c5bc78 3b 38 ee be 02 30 ee be-02 29 6a 96 a4 fc ee be ;8...0...)j.....

85c5bc88 02 ef be 02 2d 46 3f 76-36 38 b0 0a 88 01 f4 ed ....-F?v68......

85c5bc98 be 02 3b 3b 3b 3b 3b 3b-3b 3b 3b 3b 3b 3b 0c ee ..;;;;;;;;;;;;..

85c5bca8 be 02 30 3b bc ee be 02-22 a0 94 76 51 52 a6 d0 ..0;...."..vQR..

85c5bcb8 fe ff ff ff 3b 3b ab cf-81 01 3c 02 3b b0 0a 88 ....;;....<.;...

85c5bcc8 01 3b 3b 3b 3b 3b 3b 8c-ee be 02 75 45 e5 a6 07 .;;;;;;....uE...

85c5bcd8 3b 20 ef be 02 c0 f7 be-02 3b 3b 3b 3b 3c 02 3b ; .......;;;;<.;

85c5bce8 60 3b e8 ee be 02 20 ef-be 02 c8 96 84 01 5b 76 `;.... .......[v

85c5bcf8 81 01 f8 0a 88 01 6e 3b-c8 96 84 01 60 3b 85 45 ......n;....`;.E

85c5bd08 e5 a6 40 ef be 02 08 e4-83 01 ff ff ff ff 43 d4 ..@...........C.

85c5bd18 81 01 20 ef be 02 dd 45-e5 a6 08 3b 64 ef be 02 .. ....E...;d...

85c5bd28 c0 f7 be 02 0f 3b 3b 3b-20 ef be 02 40 29 88 01 .....;;; ...@)..

85c5bd38 40 29 88 01 30 34 88 01-80 ef be 02 64 ef be 02 @)..04......d...

85c5bd48 b0 0a 88 01 0f 3b 18 89-84 01 e8 83 84 01 1b 3b .....;.........;

85c5bd58 1f 3b 05 3b 01 3b 3c ef-be 02 f8 0a 88 01 f8 89 .;.;.;<.........

85c5bd68 84 01 a0 ef be 02 3b 3b-30 3b 37 3b ed 45 e5 a6 ......;;0;7;.E..

85c5bd78 c4 ff be 02 08 f3 83 01-02 3b 30 53 81 01 80 ef .........;0S....

85c5bd88 be 02 01 3b d0 f0 40 d0-51 81 01 3b 3b b8 ef be ...;..@.Q..;;...

85c5bd98 02 b0 0a 88 01 01 3b 3b-3b d4 ef be 02 0f 3b 0f ......;;;.....;.

85c5bda8 3b 3b 3b 78 0a 88 01 02-3b 10 02 10 02 10 02 10 ;;;x....;.......

85c5bdb8 02 0f 3b 17 3b 3b 8a 76-31 3b 02 03 02 03 20 f4 ..;.;;.v1;.... .

85c5bdc8 be 02 85 9f 20 75 01 3b-07 3b 00 00 00 00 00 00 .... u.;.;......

85c5bdd8 00 00 00 00 00 00 00 00-00 3f 3f 31 3b be 02 3b .........??1;..;

85c5bde8 3b 3b 3b 3b 3b 3b 08 02-0c f2 be 02 3b 08 02 04 ;;;;;;......;...

85c5bdf8 f0 be 02 3b 3b 3b 8a 76-48 02 48 02 48 02 48 02 ...;;;.vH.H.H.H.

85c5be08 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be18 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be28 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be38 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be48 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be58 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be68 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be78 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be88 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5be98 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5bea8 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5beb8 48 02 48 02 48 02 48 02-48 02 48 02 48 02 48 02 H.H.H.H.H.H.H.H.

85c5bec8 48 02 48 02 48 02 02 20-01 02 03 04 05 06 07 08 H.H.H.. ........

85c5bed8 09 0a 0b 0c 0d 0e 0f 10-11 12 13 14 15 16 17 18 ................

85c5bee8 19 1a 1b 1c 1d 1e 1f 20-21 22 23 24 25 26 27 28 ....... !"#$%&'(

85c5bef8 29 2a 2b 2c 2d 2e 2f 30-31 32 33 34 35 36 37 38 )*+,-./012345678

85c5bf08 39 3a 3b 3c 3d 3e 3f 40-41 42 43 44 45 46 47 48 9:;<=>?@ABCDEFGH

85c5bf18 49 4a 4b 4c 4d 4e 4f 50-51 52 53 54 55 56 57 58 IJKLMNOPQRSTUVWX

85c5bf28 59 5a 5b 5c 5d 5e 5f 60-41 42 43 44 45 46 47 48 YZ[\]^_`ABCDEFGH

85c5bf38 49 4a 4b 4c 4d 4e 4f 50-51 52 53 54 55 56 57 58 IJKLMNOPQRSTUVWX

85c5bf48 59 5a 7b 7c 7d 7e 7f 80-20 20 20 20 20 20 20 20 YZ{|}~..

85c5bf58 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf68 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf78 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf88 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf98 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bfa8 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bfb8 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bfc8 20 20 20 20 20 20 ff 20-01 02 03 04 05 06 07 08 . ........

85c5bfd8 09 0a 0b 0c 0d 0e 0f 10-11 12 13 14 15 16 17 18 ................

85c5bfe8 19 1a 1b 1c 1d 1e 1f 20-21 22 23 24 25 26 27 28 ....... !"#$%&'(

(BaDr)  85c5bfff | 85c5c000  (MmAc)

                        ↓  ↓

85c5bff8 29 2a 2b 2c 2d 2e 2f 30-31 32 33 34 35 36 37 3b )*+,-./01234567;


BaDr 풀은 408바이트 크기인 85c5bfff까지만 사용 가능하다. MmAc 풀의 시작 부분이 문제가 발생한85c5c000주소인데 시작 위치를 보면 31 32 33 34 값이 보인다.

이 값을DWORD 크기인 4바이트로 읽으면 34333231이 된다. 바로 유효하지 않았던 그 값이다. 이해가 안 된다면 85c5c000 주소를 db dd 명령으로 확인해보자.

재미있게도 85c5c000 주소에 담긴 31 32 33 34 값을 ASCII 문자열로 읽으면 "1234".

.format 명령을 사용하면 문자열 값을 확인할 수 있다.

kd> .formats 31323334

Evaluate expression:

... ...

Chars: 1234

... ...


무엇보다 85c5bee8 주소부터 시작된 문자열 패턴과 85c5bfe8 주소부터 시작된 문자열 패턴이 매우 유사하다.

kd> db 85c5bee8 L120

1) 패턴 1 : BaDr 영역

85c5bee8 19 1a 1b 1c 1d 1e 1f 20-21 22 23 24 25 26 27 28 ....... !"#$%&'(

85c5bef8 29 2a 2b 2c 2d 2e 2f 30-31 32 33 34 35 36 37 38 )*+,-./012345678

85c5bf08 39 3a 3b 3c 3d 3e 3f 40-41 42 43 44 45 46 47 48 9:;<=>?@ABCDEFGH

85c5bf18 49 4a 4b 4c 4d 4e 4f 50-51 52 53 54 55 56 57 58 IJKLMNOPQRSTUVWX

85c5bf28 59 5a 5b 5c 5d 5e 5f 60-41 42 43 44 45 46 47 48 YZ[\]^_`ABCDEFGH

85c5bf38 49 4a 4b 4c 4d 4e 4f 50-51 52 53 54 55 56 57 58 IJKLMNOPQRSTUVWX

85c5bf48 59 5a 7b 7c 7d 7e 7f 80-20 20 20 20 20 20 20 20 YZ{|}~..

85c5bf58 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf68 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf78 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf88 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bf98 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bfa8 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bfb8 20 20 20 20 20 20 20 20-20 20 20 20 20 20 20 20

85c5bfc8 20 20 20 20 20 20 ff 20-01 02 03 04 05 06 07 08 . ........

85c5bfd8 09 0a 0b 0c 0d 0e 0f 10-11 12 13 14 15 16 17 18 ................

2) 패턴 2 : BaDr 영역

85c5bfe8 19 1a 1b 1c 1d 1e 1f 20-21 22 23 24 25 26 27 28 ....... !"#$%&'(

3) BaDr에서 MmAc 바뀌는 부분     | => 여기부터는 MmAc 영역

85c5bff8 29 2a 2b 2c 2d 2e 2f 30-31 32 33 34 35 36 37 3b )*+,-./01234567;


1)번 패턴과 2)번 패턴은 "19 1a 1b 1c"로 시작하는 부분부터 "31 32 33 34 35 36 37(1234567)"까지 완전히 동일하다.

그런데 2)번 패턴의 중간 위치인 3)번은 이미 BaDr이 아닌 커널의 MmAc의 풀 영역이다.

, 누군가 정해진 버퍼 크기를 넘어 문자열 복사를 해서 BaDr 다음 위치인 MmAc 풀 영역을 손상시켰고, 이후 MiAllocateAccessLog 함수에서 손상된 값에 접근하다 문제가 발생한 것이다.

이런 경우 대부분 BaDr 풀 태그로 메모리를 할당한 모듈이 범인이다.

풀 태그 문자열은 모듈 내에 포함되어 있기 때문에 !for_each_module 명령을 통해 메모리에 로드된 모든 모듈에서 풀 태그 문자열을 검색하는 방법으로 찾을 수 있다.

kd> !for_each_module s -a @#Base @#End BaDr

936fc159 42 61 44 72 83 c0 02 50-57 ff d3 8b f8 85 ff 74 BaDr...PW......t

936fc19e 42 61 44 72 57 ff 15 18-f0 6f 93 8b 45 08 8d 70 BaDrW....o..E..p

... ...


몇 개의 결과가 확인된다. 앞서 lmva 명령을 사용하면 어떤 모듈 주소 영역인지 확인 가능하다고 배웠다. 제일 먼저 출력된 936fc159 주소가 어떤 모듈인지 확인해보자.

kd> lmva 936fc159

Browse full module list

start end module name

936fb000 93746000 BadDrv (deferred)

Image path: \??\C:\Windows\system32\drivers\BadDrv.SYS

Image name: BadDrv.SYS

Browse all global symbols functions data

Timestamp: Fri Feb 07 09:42:37 2014 (52F42BFD)

CheckSum: 000139FD

ImageSize: 0004B000

Translations: 0000.04b0 0000.04e4 0409.04b0 0409.04e4


범인은 BadDrv 모듈이었다. BadDrv 모듈에서 BaDr 풀 태그로 할당된 문자열 버퍼를 할당된 크기 이상으로 사용해서 커널 메모리 영역을 손상시킨 것으로 보인다.

BadDrv 모듈에서 문제의 문자열을 처리하는 곳을 찾아 버그를 수정해주면 이번 문제는 해결될 것이다.

문제 발생 위치는 분석하기 까다로운 곳이었지만 다행히도 메모리 손상 범위나 유형이 복잡하지 않아 원인을 분석할 수 있었다.

이번 예제에서 얻은 교훈은 미리 겁 먹을 필요가 없다는 것이다. 어려워 보이더라도 분석하는 것을 두려워하지 말자.



'Dump Analysis' 카테고리의 다른 글

[0xC5] 해제 리스트 손상  (0) 2018.07.19
[0xC5] 풀 헤더 손상  (0) 2018.07.16
[0x50] 해제된 핸들  (0) 2018.07.09
[0x50] 숨겨진 콜 스택  (0) 2018.07.07
[0x50] UNICODE_STRING  (0) 2018.07.05
prev"" #1 next