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를 구할수 있다는 얘기이다.
그럼.. |