티스토리 뷰

pdb를 배포하는 것은 너무나 쉽게 리버싱을 허용하는 것이기 때문에, 조금이라도 리버싱을 어렵게 하기 위해선 exe 파일만 배포해야 합니다.
보통 서버의 경우 디버깅 정보를 매칭 시키는 수단으로 pdb도 바이너리와 같이 두기도 하는데요, 이렇게 하는 것에는 장단점이 있기에 이에 대한 코멘트는 생략하겠습니다.

pdb가 없을때와 있을때 VS2005를 통한 덤프 확인시에 어떻게 다른지 보여드리겠습니다.

정상적으로 매칭되는 pdb 파일이 존재할 때 남은 덤프 파일의 콜스택과 스레드 소스 코드 매칭 정보.

pdb 파일이 존재하지 않을때 남은 덤프 파일의 콜스택과 스레드.


이렇게 차이가 납니다. 실제로 pdb 파일이 없을 시에는 어느 함수에서 크래시가 났는지 확인하기 매우 어렵죠.
위에 크래시 난 곳의 주소를 보시면, 004010f5 입니다.

이 정보를 바탕으로 크래시 주소를 찾아보겠습니다.
004010f5 는 위 두 함수 사이의 주소입니다. 그 중에서 정확한 크래시 함수는 보다 작은 주소에 존재하는 함수입니다.
왜냐하면, 위 주소는 함수 주소 + 라인으로 구성되어 있기 때문이죠.


이렇게해서 찾은 함수는 Main 클래스의 Constructer 함수라는 것을 알 수 있었습니다.
여기서 어느 라인에서 문제가 발생했는지 보고 싶으시다면,  "Preferred load address" 를 알아내야 합니다.


찾아보니 00400000 이군요~ 이를 바탕으로 정확한 라인도 찾아 볼까요?

라인 정보는 아래 공식을 통해 얻어낼 수 있습니다.

Line number information = crash address - Preferred load address - the Size of PE
f5 = 004010f5 - 0040000 - 0x1000
바로 f5가 line number information 입니다.

하지만 안타깝게도, 2005버전 이상에서는 위 정보를 바탕으로 라인 정보를 얻어 낼 수 없습니다.
Mapfile에 line information을 export 하는 /MAPINFO:LINES 옵션이 2005 이상에서는 지원하지 않기 때문입니다.

이에 대한 내용이 밑에 링크에 논의되어있습니다. 허나 맘에 드는 정보는 찾을 수 없었습니다. (MAP파일에 LINE 정보를 export 하는)

오히려 msdn 토론보다 알찬 정보는 티스토리에 있었습니다.

Debugging Tips (1) - .map 파일과 .cod 파일 분석하기

위 링크에는 cod 파일을 생성하는 법도 포함되어있습니다.

여기서 제가 좀 헤멘 부분은, cod 파일내의 어셈블 코드를 얻는 방법이었어요.

35 = 004010f5 (Crash Address) - 004010c0 (Function Address) 을 해야 원하는 값이 나왔습니다.
그래서 나온 값이 35. 이 값은 Main.cod 파일 안의 Constructer 함수내에 어셈블 코드 라인을 의미하죠.


보시면, 00035에 해당하는 어셈블 코드는 idiv ecx 입니다. 이 코드에서 integer divide zero 가 발생했고, 그래서 크래시가 발생한 것이라고 알 수 있었습니다.

이렇게 충돌 주소만으로 크래시 난 곳을 알아내는 방법을 알아보았는데요, 사실 요즘은 이보다 pdb를 이용하는 추세이긴하지만, 이런 방법도 있고 나름의 활용법도 있지 않을까 하는 의미에서 정리해보았습니다.

긴 글 읽어주셔서 감사합니다 (__) 꾸벅~

참고 문서 -
Finding crash information using the MAP file (VS 2003 .net 기준)
http://www.codeproject.com/KB/debug/mapfile.aspx

'C++ > Debugging' 카테고리의 다른 글

사고뭉치를 위한 디버깅 방법 #02  (0) 2012.05.09
사고뭉치를 위한 디버깅 방법 #01  (2) 2012.02.06
Windbg 사용법  (0) 2010.03.30
Application Verifier 적용하기  (0) 2010.02.09
Userdump로 Dump 생성 하는 방법  (0) 2008.05.09
댓글