Stack Corruption 2

다음과 같은 Crash는 빈번하게 볼 수 있다. Stack이 깨져있는 모습.

 

0:003> kbL

ChildEBP RetAddr  Args to Child             

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

0470fc54 1a43fa39 058dfe44 00000000 001db2c0 0x251fcf

0470fc70 1a41dfdb 00000001 0470fc94 1a406bd4 ttt!CBaseMy::Neutralize+0x35

 

0:003> r

eax=050d2000 ebx=00000000 ecx=00251f18 edx=00000000 esi=001db2c0 edi=00000000

eip=00251fcf esp=0470fc58 ebp=0470fc70 iopl=0         nv up ei pl nz na pe nc

cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000206

00251fcf 006022          add     byte ptr [eax+22h],ah      ds:0023:050d2022=??

 

보면, 0x251fcf Function Name은 아닐 것이다. Garbage 임에 틀림없다. 그리고 Register 를 보면, eax 는 잘못되었음을 보여주고 있다. 이러한 Callstack에서 문제가 발생한 원인을 찾기 위해서는 마지막에 정상적으로 수행된 Function에서 부터 Check 할 필요가 있다. Windbg에서 kb 명령어를 수행할 줄 알아도 그 의미를 알지 못하면 아무 소용이 없다. . 그럼 어디를 어떻게 봐야 할 까. 다시 한번 Callstack을 보자.

 

0:003> kbL

ChildEBP RetAddr  Args to Child             

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

0470fc54 1a43fa39 058dfe44 00000000 001db2c0 0x251fcf

0470fc70 1a41dfdb 00000001 0470fc94 1a406bd4 ttt!CBaseMy::Neutralize+0x35

 

Callstack에서 보여주고 있는 것은 Neutralize Function 안에서 뭔가 임의의 Function Call되었고 그것의 Function Name은 알 수 없다는 것이다. 만일 적절한 Function Name Debugger가 알 수 있었다면, 0x251fcf 라는 값을 출력하진 않았을 것이다. 하지만, 또 한가지 알 수 있는 것은 뭔지 모르는 마지막 Function Call에 대한 return address 0x1a43fa39 라는 것이다. 이것이 깨졌는지 Check 해 봐야 한다. 만일, 이것 역시 깨졌다면, 다시 raw stack을 점검해야 할 것이다. 그러므로, 일단, Neutralize Function Assembly code를 확인할 수 있다.

 

0:003> uf ttt!CBaseMy::Neutralize

  664 1a41df5a 8bff            mov     edi,edi

  664 1a41df5c 56              push    esi

  664 1a41df5d 8bf1            mov     esi,ecx

. . .<중략>

  675 1a41df7d 8b460c          mov     eax,dword ptr [esi+0Ch]

  675 1a41df80 3bc7            cmp     eax,edi

  675 1a41df82 0f85ab1a0200    jne     ttt!CBaseMy::Neutralize +0x2f (1a43fa33)

  677 1a43fa33 8b08            mov     ecx,dword ptr [eax]

  677 1a43fa35 50              push    eax

  677 1a43fa36 ff5108          call    dword ptr [ecx+8]

  678 1a43fa39 897e0c          mov     dword ptr [esi+0Ch],edi

 

결국, 1a43fa39 Assembly code에서 Class member function call 'call dword ptr[ecx+8]' 에 대한 Return Address이다. 다시 assembly code register 값을 살펴보자.

 

0:003> dd @ecx

00251f18  ???????? ???????? ???????? ????????

00251f28  ???????? ???????? ???????? ????????

00251f38  ???????? ???????? ???????? ????????

00251f48  ???????? ???????? 0000ffff 00252c04

 

확실히 ecx 값은 잘못되었다. assembly code를 따라가보면, ecx값은 esi register의 임의의 Offset으로 부터 얻은 값이고, Function의 초입부에 ecx 를 통해서 esi 값을 전달 받는 것으로 봐서는 esithis pointer가 틀림없다. 그러므로, this pointer member class 또는 member 변수에 대한 member function을 호출하는 것에 문제가 있었기 때문에 stack이 깨진 것으로 추측할 수 있으며, member 변수(ecx register) garbage 값이 들어 온 이유에 대해서 Code review를 통해 verify 해야 할 것이다.

by 강세윤 | 2009/04/06 13:27 | Windows debugging | 트랙백 | 덧글(0)
트랙백 주소 : http://byung.egloos.com/tb/4861866
☞ 내 이글루에 이 글과 관련된 글 쓰기 (트랙백 보내기) [도움말]

:         :

:

비공개 덧글

< 이전페이지 다음페이지 >