SEH(Structured Exception Handling).pdf
SEH의 설명은 첨부파일의 내용을 참조하면 이해하기 쉽다.
컴파일러의 도움 없이 에러처리를 수행하는 예제코드의 디버깅
디버깅에 사용된 전체소스 ↓ (더보기 클릭, 출처: Windows 구조와 원리)
예제 소스는?
1. SEH 설치: 스택과 FS:[0]에 에러 핸들링을 수행할 nHandler함수를 등록
2. SEH 발생: 0번 주소의 메모리에 접근하여 에러가 발생하였을 때
3. 예외 처리: 이미 등록한 nHandler에서 받아 에러가 발생할 당시의 참조 레지스터 eax를 프로그래머가 정의한 전역 변수의 주소 값 G_nValid로 바꾸어 준 후 에어가 발생했던 코드를 다시 실행시키도록 하는 코드
1. SEH의 설치
ULONG nHandler = (ULONG)except_handler;
__asm
{
__asm
{
MOV eax, FS:[0]
push nHandler
push FS:[0]
MOV FS:[0], ESP
MOV eax, FS:[0]
}
1) FS:[0] 값 확인 : MOV eax, FS:[0]
FS:[0]에는 해당 스레드의 EXCEPTION_REGISTATION_RECORD의 포인터가 저장되어 있어 사용자가 지정한 에러 핸들러를 찾을 수 있도록 하고 있다. 1
eax에 FS:[0] 값을 넣어 FS:[0]값을 확인해보면,
2) nHandler의 값을 스택에 Push : push nHandler
ESP 레지스터 값을 통해 현재 스택위치에 nHandler가 잘 들어갔는지 확인할 수 있다.
push nHandler 명령을 수행한후 실제 디버깅을 해보면 다음과 같은 결과가 나온다.
3) 기존의 FS:[0]을 스택에 Push : push FS:[0]
ESP 레지스터 값을 통해 현재 스택위치를 쫓아가보면, 1)에서 EAX에 넣어서 확인해 보았던 FS:[0]값이 잘 들어가 있음을 알수 있다.
SEH의 구조에 따라 FS:[0], FS[4]: FS:[8]의 메모리를 확인해보면,
4) SEH 설치:MOV FS:[0], ESP, MOV eax, FS:[0]
FS:[0]에 현재 ESP를 넣고, 변경된 FS:[0]을 확인하기 위해 EAX에 넣어 다시 확인을 해보았다.
위와 같이 스택과 FS:[0]의 값을 변경하여 예외가 발생 되었을 때 Windows가 처리 할 수 있는 구조를 만들어주는 것이다.
2. SEH 발생
__asm
{
mov eax, 0
mov [eax], 'a' // SEH 발생
}
{
mov eax, 0
mov [eax], 'a' // SEH 발생
}
3. 예외처리
SEH가 발생하면 아까 1번에서 설치하였던 SEH에 따라 해당 에러 핸들러를 호출한다.
1) 에러핸들러의 리턴값 2
2) 에러핸들러의 파라미터값
- ExceptionCode: Error Code 값 3
여기서 0xc0000005는 헤더파일을 찾아보면 STATUS_ACCEESS_VIOLATION이라고 나온다.
- EstablisherFrame: SEH를 설치할 때 코드에서 설치한 ESP값을 저장하고 있다.
- ContextRecord: Exception이 발생할 당시의 레지스터 값을 가지고 있다.
4. SEH 제거
// 3. SEH 제거하기
__asm
{
mov eax,[ESP]
mov FS:[0], EAX
add esp, 8
}
__asm
{
mov eax,[ESP]
mov FS:[0], EAX
add esp, 8
}
설치할때 변경했던 스택과 FS:[0]을 원상복귀 하는 코드이며, 디버깅 하면 아래와 같다.
'컴&프로그래밍 > C++_Win API_ MFC' 카테고리의 다른 글
Visual Studio 6.0에서 통합 빌드 프로젝트 생성하기 (1) | 2010.12.07 |
---|---|
MFC에서 xp visual style theme 적용시 응용프로그램 툴바 gripper 잘못 그려지는 오류 (0) | 2010.09.22 |