이번에는 VC++로 컴파일 했을 때 나오는 바이너리 파일에서 예외가 발생했을 때 어떠한 주소로 가게되는지 알아보겠습니다.
간단하게 EXCEPTION_BREAKPOINT를 발생시키는 코드를 보겠습니다.
이제 올디로 봐보겠습니다.
이 부분이 예외처리 루틴을 설정하는 부분입니다.
원래 있던 예외처리 루틴이 아닌 제가 코드상으로 추가한 예외처리 루틴입니다.
여기서 TEB구조체를 봐보겠습니다.
우리가 예외처리 루틴을 등록하기 전에는 메모리에 위 그림과 같이 값이 들어있지만
저희가 등록하는 예외처리 루틴은 쫌 형태가 다릅니다. 제가 만든 예외를 넣어주기 때문이죠.
다시 올디로 봐본 그림을 보면 FS:[0]에 ESP를 넣는데 그 전에 5개의 값을 push하고 있습니다.
그림으로 나타내보겠습니다.
제가 만든 예외처리 루틴이 등록되면 위 그림처럼 값이 들어가게 됩니다.
__except_handler3은 Visual C++이 이미 만들어 놓은 함수입니다.
이제 예외가 발생하게 되면 제가 만든 예외처리 루틴보다 __except_handler3 함수가 먼저 호출되게 됩니다.
scopetable을 설명하기 전에 예외가 발생했을 때 언제 __except_handler3이 호출되는지 봐보겠습니다.
먼저 예외가 발생하는 지점에서 F8을 누르게 되면 ntdll.dll 내부로 들어오게 됩니다.
하얀색에 있는 위치입니다.
그리고 0x77238C8A 함수 리턴 값에 의해 ZwContinue, ZwRaiseException함수가 호출 될 것입니다.
하지만 이번 경우는 예외가 발생했을 때 예외처리를 개발자가 직접 해주었으므로 이러한 경우는 0x77238C8A함수로 들어가면
내부적으로는 개발자가 만든 코드 위치로 다시 가게 됩니다.
그래서 ZwContiue, ZwRaiseException함수가 호출되지 않습니다.
0x77238C8A 함수 내부를 잘 뒤져보면 이러한 코드가 나오게 됩니다.
호출하는 함수 주소를 보니 __except_handler3 주소입니다.
바로 저 부분에서 __except_handler3을 호출하고 있습니다.
그리고 __except_handler3 함수에서는 scopetable이 가리키고 있는 구조체에서 두번째 세번째 멤버인
Filter, Handler 루틴을 다룹니다.
여기서 Filter 루틴은 예외가 발생했을 때 그 예외를 어떻게 처리할건지에 대한 값을 리턴합니다. 즉 코드로 보면
__except(EXCEPTION_EXECUTE_HANDLER)
이 부분입니다.
리턴 값이 1입니다. EXCEPTION_EXECUTE_HANDLER 값이 1이기 때문이죠.
이 리턴 값에 따라 예외를 어떻게 처리할 건지 __except_handler3이 정하게 됩니다.
이제 리턴 값이 1이므로 Handler 루틴을 호출하게 됩니다. 이 때 Handler루틴의 주소가 우리가 원하는 예외처리 루틴입니다.
그 주소로 가보겠습니다.
우리가 작성한 예외처리 루틴으로 들어왔습니다.
이렇게 처리가 되는군요.
FS:[0]값부터 쭉 봐보겠습니다.
감사합니다.
'My Study > Reversing' 카테고리의 다른 글
User Callback Address (0) | 2011.01.10 |
---|---|
Cheat Engine의 축하 메시지?? (3) | 2010.12.27 |
실행 시 함수 얻어오는 바이너리 분석 (2) | 2010.10.11 |
Machine Code & C Language (2) | 2010.09.28 |
Stack Based Obfuscation ( Binary Code ) (2) | 2010.09.10 |