push 할 때 조심할 것

@codemaru · February 28, 2011 · 2 min read

너무 어처구니 없는 실수를 해서 끄적여 봅니다. 어제부터 xfavorites 코드를 좀 수정하고 있었는데요. 이 놈이 64비트에서는 WH_KEYBOARD가 인터센더블 훅이라 제대로 동작하지 않는 경우가 좀 있더라고요. 여튼 그런 이유 때문에 방식을 조금 변경하고 있었는데, 문제는 이상하게 해당 코드가 실행만 되면 탐색기가 크래시가 난다는 것이었습니다. 어제 한참 신나게 디버깅 하다가 잠와서 잤는데 오늘 방금 들어와서 밥먹고는 다시 코드를 좀 살펴보니 정말 어처구니 없는 오류였습니다.

push dword ptr [esp+16]

push dword ptr [esp+12]

push dword ptr [esp+8]

push dword ptr [esp+4]

call eax

특별한건 없고 단순히 인자로 넘어온 파라미터를 넣어서 다시 함수를 호출하는 과정입니다. 그런데 자꾸 이 함수의 실행 결과가 이상해서 크래시가 발생하는 거였습니다. 그래서 도대체 왜 그렇지 하면서 익스플로러를 디버깅을 해보니 스택에는 제가 생각한 값들이 없더라고요. 네. 당연한거 맞습니다. 스택에 푸시를 하면 esp 값이 변하는데 그걸 생각을 안한 것이죠. 위와 동일한 코드를 만드려면 실제로는 다음과 같이 해야 정상적인 동작을 합니다.

push dword ptr [esp+16]

push dword ptr [esp+16]

push dword ptr [esp+16]

push dword ptr [esp+16]

call eax

가독성은 좀 떨어지죠. 인덱스, 포인터 개념이 괜히 있는건 아니겠지요. 아래처럼 바꾸면 가독성이 좀 나아집니다. ㅎㅎ~

mov ecx, esp

push dword ptr [ecx+16]

push dword ptr [ecx+12]

push dword ptr [ecx+8]

push dword ptr [ecx+4]

call eax

이걸 세 시간 넘게 디버깅을 하다뉘… 헐킈…

 0  0

 

@codemaru
돌아보니 좋은 날도 있었고, 나쁜 날도 있었다. 그런 나의 모든 소소한 일상과 배움을 기록한다. 여기에 기록된 모든 내용은 한 개인의 관점이고 의견이다. 내가 속한 조직과는 1도 상관이 없다.
(C) 2001 YoungJin Shin, 0일째 운영 중