[질문] cdecl로 정의된 함수에서 프레임 포인터가 비정상적으로 들어가는 경우?
글쓴이: ssukmaec / 작성시간: 화, 2009/11/17 - 6:27오후
디버깅을 위해 stackwalk64 라이브러리를 쓰는데, 출력이 제대로 안되는(스택 중간에 더이상 트레이스가 안되는) 부분이 있어서 살펴봤더니 pcontext의 ebp값이 엉뚱하게 들어가있었습니다
vc++ 를 사용중이고, 마지막으로 호출된 함수는 output.c라는 파일에 정의된 ...output... 라는 이름의 함수입니다. (fprintf 내부에서 불려지는 함수같은데 컴파일 옵션에 따라 이름이 여러가지네요)
push ebp lea ebp,[esp-1F8h] sub esp,278h mov eax,dword ptr [___security_cookie (781C19E0h)] xor eax,ebp mov dword ptr [ebp+1F4h],eax
문제가 되는 함수 시작부분인데요,
보통 함수가 시작될 때 ebp를 푸쉬하고는 ebp에 esp를 넣는줄로만 알았는데
esp(스택 꼭대기)에서 500바이트정도 여분을 두고 베이스포인터를 잡네요...
그럼 당연히 ebp가 가리키는 부분에 이전스택의 베이스 주소가 아닌 엉뚱한 값이 들어있을테고 stackwalk도 제대로 동작을 못할거구요...
그러면 도대체 리턴은 어떻게할수있는건가 해서 살펴보니 리턴하기 직전에 다시 ebp를 복구하는 코드가 있네요...
add ebp,1F8h leave ret
C 코드상으로는 저렇게 될 이유가 없어보이는데 컴파일 결과가 저런식으로 나온 이유가 궁금합니다.
그리고 일부러 스택메모리 중간에 공백을 두는 목적이 무엇인지도 알고싶습니다.
함수 선언부에
#define _CRTIMP __declspec(dllimport) _CRTIMP int __cdecl _vtcprintf_l ( ... )
처럼 되어있는 부분이 보이는데 혹시 이것이 원인일 수도 있나요?( __declspec 이 뭔지 잘 모르겠습니다)
답변 부탁드립니다
Forums:
댓글 달기