driver-online
  log-inmypagesitemap
top
   자유게시판
   로그북
    견우일지
    시스템팀 개발일지
    Beginning Driver
   유용한 팁&강좌
   CrashDump분석(beta)
   개발QnA
    WDM 입문
    USB
    NDIS
    File System
    Debugging 관련
    그 외
 
개발자 포럼 > 유용한 팁&강좌
스택 구조 1
 ·작성일 2010.08.25:11.13 (수)  · 작성자 올엠  · 조 회 7,978


이미 여러 책에서 기초로 많이 다루었던 스택의 구조에 대해 간단히 설명할까 합니다.

제가 생각하기에 분석시 가장 먼저 해야할일은 스택의 구조를 파악하는 일을 해야한다 생각합니다.
(어셈블리 포함 ^^;)
검색해보았는데 마땅한 비슷한 내용은 없는것 같아서 귀차니즘 타파도 하고 공유도 할 겸 여기에 올립니다.
(어딘가 있을듯 --;;)
그럼..

컴퓨터를 하시는 분들은 메모리가 스택구조로 되어 있다고 알고 있으실 겁니다.

선입후출 이라는 것이죠

 

그럼 다음 내용을 보고 어떤 내용인지 알수 있을까요?

42 01001360 8bff mov edi,edi

    42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

    47 0100138b 8d45f0 lea eax,[ebp-10h]

    47 0100138e 50 push eax

    47 0100138f 8b4dec mov ecx,dword ptr [ebp-14h]

    47 01001392 51 push ecx

    47 01001393 8d55f4 lea edx,[ebp-0Ch]

    47 01001396 52 push edx

    47 01001397 e824000000 call 05stackdesc!Sum (010013c0)

    48 0100139c 8b45f0 mov eax,dword ptr [ebp-10h]

    48 0100139f 50 push eax

    48 010013a0 6874110001 push offset 05stackdesc!`string' (01001174)

    48 010013a5 ff1584100001 call dword ptr [05stackdesc!_imp__wprintf (01001084)]

    48 010013ab 83c408 add esp,8

     49 010013ae 8be5 mov esp,ebp

    49 010013b0 5d pop ebp

    49 010013b1 c3 ret
자 선입후출의 의미로만 알수 있을까요?

이 의미만으로는 아무것도 알수가 없지요..

 

정확히 메모리의 구조를 이해하기 위해서는 스레드들이 어떻게 처리되는지 더 자세히 확인해볼 필요가 있습니다.

 

그럼 위 구조 내용을 통해, 확인해 보도록하겠습니다.

 

스택은 아래와 같이 구분할 수 있습니다.

함수 도입부

함수 코드

함수 종결부

 

그러다면 함수 도입부를 확인해 보도록 하겠습니다.

42 01001360 8bff mov edi,edi

    42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

    47 0100138b 8d45f0 lea eax,[ebp-10h]

    47 0100138e 50 push eax

    47 0100138f 8b4dec mov ecx,dword ptr [ebp-14h]

    47 01001392 51 push ecx

    47 01001393 8d55f4 lea edx,[ebp-0Ch]

    47 01001396 52 push edx

양이 많죠? 위 부분이 함수 도입부 인데, 함수를 저장할 공간을 할당하고, 기존 포인터 위치를 기억하는 게 주된 목적 입니다.

위 부분에서 ebp에 대해 알아 보도록 합시다.

ebp는 알아두어야 할 내용이 항상 주어진 프레임의 베이스 포인터(Base Pointer)를 포함한다고 생각하시면 됩니다.

그럼 아래내용은 무엇을 뜻하는 것일까요?

42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

Push 명령을 통해 ebp를 집어넣으라는 명령으로, Stack에 자료를 집어넣을 때 사용하는 것입니다.

쉽게 말해 ebp를 집어넣으라는 뜻이지요

그래서 mov 명령으로 esp 값(Stack Pointer)을 ebp에 저장하라는 명령이 나오게됩니다.

esp는 현재 스택 포인터 값으로, 이 포인터 위치는 항상 변하게 되므로, 항상 호출 이전의 원래 상태로 복귀됨을 보장하여야하는 메모리 구조상 esp의 복귀 주소를 사용할수 없기 때문에 ebp를 통해 복귀할 수 있는 주소를 저장하게 됩니다. (이 행동의 거희 모든 스택의 기본 동작으로 들어가 있습니다.)

mov edi,edi는 긴급 패치를 위해 사용하는데 대부분 nop(no operation)으로 상태가 됩니다. 가용성 측면으로 비사용시간을 줄이기위해 필수적으로 사용하게 됩니다. 이는 나중에 jmp 코드를 이용하기 위해 넣어 둔것이라고 생각하시면 됩니다.

 

자 그럼 도입부분으로 프레임의 베이스 포인터 위치를 ebp에 저장하여 프레임 복귀위치를 저장하였습니다.

이제 다음 스택을 보도록 하겠습니다.

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

esp, 14h가 의미하는건 14h를 10진수로 변환해 보면, 20바이트가 되며, sub는 빼는것으로, 20바이트 만큼 공간을 생성하도록 되어 있습니다.

왜 이렇게 공간을 생성하는게 빼기를 하였을까요?

메모리의 저장 위치를 잘 보시면 저장 위치의 값이 감소하도록 되어 있습니다.

즉 밑으로 갈수록 값이 감소하고 있는것이지요

그래서 아래 공간은 빼기를 통해 확보하게 됩니다.

그렇게 확보한 공간에 ebp(베이스 포인터)의 위치 값을 이용하여 (베이스 포인터는 절대 위치 값처럼 그 프레임 내에서는 변화하지 않기 때문에 변수 저장과 같은 절대 위치가 필요한 값 저장에 사용하게 됩니다.)스택기반 지역 변수를 초기화 하게 됩니다.

그 내용이

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

위 부분이 되겠습니다.

그리고 포인터 전달 명령인 lea를 통해 인자를 스택에 저장 합니다.

42 01001360 8bff mov edi,edi

    42 01001362 55 push ebp

    42 01001363 8bec mov ebp,esp

    42 01001365 83ec14 sub esp,14h

    43 01001368 c745ec03000000 mov dword ptr [ebp-14h],3

    44 0100136f c745f401000000 mov dword ptr [ebp-0Ch],1

    44 01001376 c745f802000000 mov dword ptr [ebp-8],2

    44 0100137d c745fc03000000 mov dword ptr [ebp-4],3

    45 01001384 c745f000000000 mov dword ptr [ebp-10h],0

    47 0100138b 8d45f0 lea eax,[ebp-10h]

    47 0100138e 50 push eax

    47 0100138f 8b4dec mov ecx,dword ptr [ebp-14h]

    47 01001392 51 push ecx

    47 01001393 8d55f4 lea edx,[ebp-0Ch]

    47 01001396 52 push edx

이렇게 지역 변수를 다 저장하고 나면, Call 명령을 통해 해당 변수를 사용하게 됩니다.

그리고 수행을 마치고 마지막에 esp에 처음 저장한 ebp를 대입하여, 복귀하고, 해당 프레임을 빠져 나오게 됩니다.

49 010013ae 8be5 mov esp,ebp

    49 010013b0 5d pop ebp

    49 010013b1 c3 ret

이렇게 하나하나의 프레임의 복귀 주소를 저장하고 변수를 저장후 Call을 통해 해당 명령을 수행하는 구조가 메모리의 기본 구조가 되겠습니다.

^^;

아직 알아야하는부분은 더 많지만 오늘은 이 정도로 마무리 하도록 할께요, 너무 짧죠 흐.. 조만간 2차도 올릴께요

*답변을 받은 후 감사의 글을 남기는 것은 꼭 지켜야할 네티켓입니다.
    

다 음 : 답변 가능하신지요.

 
quick-menu
event
study
QnA
pds
family-site concert used used2 intro
address
address