C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 팁&트릭
C++Builder Programming Tip&Tricks
[887] [Exception] 예외처리3 - AccessViolation발생시 에러 위치 찾기2
장성호 [nasilso] 12473 읽음    2009-04-23 00:00

AccessViolation발생위치 찾기2



앞에 기사에 AccessViolation이 발생했을때 에러발생위치를 찾는 방법을 소개했습니다.

그런데 만약 다름과 같이 에러발생위치가 xxx.exe가 아니라  xxx.dll 또는 xxx.bpl 등인경우엔 어떻게 해야할까요?

 

이경우는 Module의 Base-Address인 HInstance를 찾아서 그만큼 빼주면 됩다.

HINSTANCE hInst=GetModule("test.dll);

hInst 가 0x00E30000이 인경우  0x00E31458 에서 Base-Addr  0x00E30000을 빼면 0x00001458이 에러발생 위치입니다.

문론 Dll 을 컴파일할때도 map파일을 만들어 둬야 하구요..

여기서 잠깐 모듈의 맵핑 주소에 대해 살펴보겠습니다.

간단한 TestProject 를 만들고  proecss에서 load한 모듈을 리스트해보았습니다.

 

C++Builder로 만든 간단한 Delphi로 만든 exe

Project1.exe = 400000
ntdll.dll = 7c930000
kernel32.dll = 7c7d0000
vcl60.bpl = 400b0000
rtl60.bpl = 40000000
user32.dll = 77cf0000
GDI32.dll = 77e20000
advapi32.dll = 77f50000
RPCRT4.dll = 77d80000
Secur32.dll = 77ef0000
oleaut32.dll = 770d0000
msvcrt.dll = 77bc0000
ole32.dll = 76970000
mpr.dll = 71a50000
wsock32.dll = 71a00000
WS2_32.dll = 719e0000
WS2HELP.dll = 719d0000
version.dll = 77bb0000
comctl32.dll = 5c820000
winspool.drv = 72f50000
comdlg32.dll = 76300000
SHELL32.dll = 7d5a0000
SHLWAPI.dll = 77e70000
oledlg.dll = 7df80000
BORLNDMM.DLL = 21150000
CC3260MT.DLL = 32600000
PSAPI.DLL = 76ba0000
IMM32.DLL = 762e0000
LPK.DLL = 62340000
USP10.dll = 73f80000
comctl32.dll = 77160000
uxtheme.dll = 5a480000
MSCTF.dll = 74660000
SCUREDLL.dll = 10000000
msctfime.ime = 75110000
IMKR12.IME = 3a700000
MSVCR80.dll = 78130000
MSVCP80.dll = 7c420000
McIdle.dll = e30000
test.dll = f50000

Project1.exe = 0x00400000
ntdll.dll    = 0x7C930000
KERNEL32.dll = 0x7C7D0000
rtl70.bpl    = 0x40000000
USER32.dll   = 0x77CF0000
GDI32.dll    = 0x77E20000
ADVAPI32.dll = 0x77F50000
RPCRT4.dll   = 0x77D80000
Secur32.dll  = 0x77EF0000
OLEAUT32.dll = 0x770D0000
msvcrt.dll   = 0x77BC0000
ole32.dll    = 0x76970000
MPR.dll      = 0x71A50000
VERSION.dll  = 0x77BB0000
WSOCK32.dll  = 0x71A00000
WS2_32.dll   = 0x719E0000
WS2HELP.dll  = 0x719D0000
vcl70.bpl    = 0x00410000
COMCTL32.dll = 0x5C820000
WINSPOOL.DRV = 0x72F50000
comdlg32.dll = 0x76300000
SHELL32.dll  = 0x7D5A0000
SHLWAPI.dll  = 0x77E70000
oledlg.dll   = 0x7DF80000
IMM32.dll    = 0x762E0000
LPK.dll      = 0x62340000
USP10.dll    = 0x73F80000
COMCTL32.dll = 0x77160000
UxTheme.dll  = 0x5A480000
MSCTF.dll    = 0x74660000
SCUREDLL.dll = 0x10000000
msctfime.ime = 0x75110000
IMEKR.dll    = 0x3A700000
MSVCR80.dll  = 0x78130000
MSVCP80.dll  = 0x7C420000
McIdle.dll   = 0x00E60000
test.dll        =  0x00F70000



위 내용을 통해 알수 있는것이 한두가지가 있다.

첫째.  xxx.exe의 Base-Address는 항상 0x00400000 이라는 사실...
        너무나 잘 알려진것이니 넘어가자..

둘째. ntdll.dll 이나 Kernel32.dll  , User32.dll 등은
           load되는 순서가 틀려도 proecess에 상관없이 base-address가 똑같다는 사실이다.
          거의 0x70000000 번대의 Module은 대게 System(Windows)에서 사용하는 모듈인것 같은데,
          모두 process상관없이 똑같은듯하다. 
       ; 이걸  역공학에서 종종 이용하기도 한다.
         
       ;  test.dll은 분명 같은 dll을 load했는데 base-address가 다르다.
         이는 load될때마다 다를수 있다.
  
셋째. 모듈의 Base-Address가 뒤에 4자리는 모두 0 이다
        모듈Base-Address를 잘 몰라도 AccessViolation이 발생했을때 앞에 4자리 떼고
         뒤에 4자리 가지고만 계산하면 대충 예외발생 address를 구할수 있다는 얘기이다.

 

그럼..


+ -

관련 글 리스트
887 [Exception] 예외처리3 - AccessViolation발생시 에러 위치 찾기2 장성호 12473 2009/04/23
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.