실행중인 주소 알아내기

February 28, 2008

x86 Register 가운데, 현재 실행중인 주소를 담고 있는 것은 IP(Instruction pointer)다. 이건 직접 얻어올 수는 없고 다음과 같은 방법을 사용해야 한다. (x86 assembly language 참조)

inline int GetEIP()
{
int foo;
__asm {
call next_line;
next_line:
pop eax;
mov foo, eax;
}
return foo;
}

call 은 next_line을 호출하기 전에 호출이 끝난 다음에 돌아올 주소, 즉 현재 EIP값을 스택에 쌓는다. 쌓고나서 next_line으로 가면 스택에 쌓인 EIP값을 foo로 옮긴다.

#define malloc(s) MyMalloc(s, GetEIP())

메모리 매니저를 만들어 사용하는 경우, 위와 같이 얻어온 EIP 값을 사용해서 어떤 녀석이 malloc을 하는지 알고 싶을 때 사용할 수 있겠다. 얻어온 주소로부터 심볼을 알아내는 것은 Win32의 경우 SymFromAddr 함수를 사용하면 된다.

위와 같은 방법으로 어디서 malloc을 하는지 알았다고 해도, 심볼을 출력해보니 하필 STL안에서 사용된 것이라면 대략 난감하다.

std::basic_string<char,std::char_traits...

이런 경우는 문자열인 건 알겠는데 이게 어디서 쓴 무슨 문자열인지 참 막막하다. 이럴 때 현재 실행되는 부분을 호출하는 call stack을 따라 몇 단계 올라가고 싶을 수 있다. MSJ 기사에서 Intel CPU의 경우 사용할 수 있는 간단한 방법을 소개하고 있다. 그것을 구현한 intelStackWalk 함수도 쉽게 구할 수 있다. 간단히 설명하면, 어떤 함수 foo에 의해 bar가 호출될 때, 호출이 끝나면 돌아갈 foo안의 주소와 foo가 사용했던 stack base pointer값, 즉 EBP값이 스택에 쌓이고, 쌓여서 늘어난 Stack pointer ESP값이 새 함수 bar의 새로운 stack base pointer, EBP가 된다는 말이다. 그러니 bar가 호출되자마자 EBP[0]의 값은 foo의 EBP일 것이고, EBP[1]의 값은 foo에서 bar를 호출한 다음 돌아갈 주소가 된다.

inline int GetEBP()
{
PDWORD pFrame;
__asm { mov pFrame, ebp; }
if ( (PDWORD)pFrame[0] > pFrame )
pFrame = (PDWORD)pFrame[0]; // stack walk - one step
return pFrame[1];
}

이러면 call stack 을 하나 올라가서 지금 실행 중인 함수를 누가 호출했는지 알 수 있다.

Entry Filed under: Uncategorized. Tags: .

Leave a Comment

Required

Required, hidden

Some HTML allowed:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <pre> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Trackback this post  |  Subscribe to the comments via RSS Feed


Tags

addon android Assembly batch book C++ editor excel google InstallShield lua personal physic security wow

Recent Posts

Recent Comments

지양 on Source Insight – Browse …
조프 on Source Insight – Browse …
조프 on Source Insight – Browse …
랑탕 on Google 크롬의 Crash message
지양 on n&(n-1)

Blogroll