외규장각 도서 환수 모금 캠페인

Search Results for 'SEH'

1 POSTS

  1. 2007.06.11 예외 핸들러 (SEH)

예외 핸들러 (SEH)

Posted 2007. 6. 11. 14:46, Filed under: Study/Computer Science

예외 핸들러를 지정하는 방식은

PUSH    EAX                                       <==  예외 처리하기 위한 코드의 주소를 넣는다.
PUSH    DWORD PTR FS:[0]                 <==  이전 핸들러의 주소값 저장
MOV     DWORD PTR FS:[0], ESP         <== 새로운 핸들러의 주소값 입력

이러한 방식으로  SEH를 연결한다.

구조체는 아래와 같다.

typedef struct _EXCEPTION_REGISTRATION
{
 EXCEPTION_REGISTRATION  *prev;
 EXCP_HANDLER   handler;
} EXCEPTION_REGISTRATION, *PEXCEPTION_REGISTRATION;


예외가 발생했을 때 수행되는 함수는 아래와 같은 형태이다.

// callback function definition
typedef EXCEPTION_DISPOSITION (*EXCP_HANDLER)
(
 EXCEPTION_RECORD   *pExcpRec,      <== 예외 정보를 포함한 구조체 포인터
 EXCEPTION_REGISTRATION  *pFrame,  <== EXCEPTION_REGISTRATION 포인터
 CONTEXT     *pCtx,                          <== 예외 발생시 CPU 상태를 나타내는 구조체 포인터
 VOID      *pValue    // ESP+10
)

EXCEPTION_RECORD구조체는 아래와 같다.

typedef struct _EXCEPTION_RECORD
{
 DWORD    ExceptionCode;      <== 예외 코드
 DWORD    ExceptionFlags;      <== 플래그
 EXCEPTION_RECORD   *ExceptionRecord;   <== 관련 예외 레코드
 PVOID     ExceptionAddress;     <== 예외가 발생한 주소
 DWORD    NumberParameters;   <== 예외 정보수
 UINT_PTR    ExceptionInformation[0Fh];      <== 예외 정보
} EXCEPTION_RECORD;

위 정보를 사용해서 예외를 발생 시키고 해당 핸들러에서는 예외 처리를 마치고 복귀되는
주소값을 바꿔서 엉뚱한 곳으로 복귀시킬도 있고 복귀할 곳의 값을 바꾸어서 다른 코드를
수행할 수도 있다.

MOV     EDX, DWORD PTR SS:[ESP+4]    
<== EDX에 EXCEPTION_RECORD의 포인터값을 넣느다.

MOV     EDX, DWORD PTR DS:[EDX+C]       <== 예외가 발생한 주소값을 EDX에 넣고
MOV     BYTE PTR DS:[EDX], 0E9               <== 수정
이제 예외 처리를 마치고 돌아가면 다른코드로 변경되어 있다.

- 중요 -

예외 처리 후 ZwContinue명령을 수행해서 예외가 발생한 주소로 돌아오게되는데
이때.. 디버깅하는 프로그램에서는 돌아와서 첫번째 명령수행은 그냥 넘어간다.


MOV  <== 예외발생

MOV <== 디버깅 프로그램에서는 여기로 복귀 하지만 위 MOV명령어 위치로 복귀되는것임.


Response : ,


Recent Posts

Recent Comments

Recent Trackbacks

Total hit (Today , Yesterday )

Admin Write Post