Error - 처리되지 않은 예외가 있습니다. 힙이 손상되었습니다.

2022. 6. 12. 04:40TIP

반응형

본 티스토리 블로그는 PC 환경에 최적화되어 있습니다.

모바일 유저분들은 네이버블로그를 이용해 주세요.

 

 

Error - 처리되지 않은 예외가 있습니다. 힙이 손상되었습니다.

본 네이버 블로그는 모바일 환경에 최적화되어 있습니다. PC 유저분들은 티스토리 블로그를 이용해 주세...

blog.naver.com

 

 

음에는 이러한 실수를 반복하지 않고자 하는 다짐 차원에서 이렇게 글을 쓰게 된다.

개발을 진행하다 보니 스레드가 힙을 생성 받고 리스트에 추가하는 동작이 있었는데 list insert 연산이 두 번 정도 진행되다가 갑자기 스레드가 죽는 일이 벌어졌다.

 

스레드는 일반적인 디버깅 방식과는 다르기에 익숙하지 않았고 결국 코드 전체를 단일 함수로 하나의 프로세스에서만 동작하도록 했더니 malloc 함수가 중간에 중단되는 예외 사항이 계속 발생한다는 것을 알 수 있었다.

 

그래서 코드 하나하나 따라가며 추적해 보니 다음과 같은 문구를 확인할 수 있었다.

0x00007FF8DBDAF249(ntdll.dll)에(프로젝트.exe의) 처리되지 않은 예외가 있습니다.
0xC0000374: 힙이 손상되었습니다(매개 변수: 0x00007FF8DBE177F0).

 

이런 에러 정보 말고도 많은 내용이 나왔으나 해당 버그를 찾는데 많은 시간이 걸렸었다. ㄷㄷ

일단 "처리되지 않은 예외가 있습니다. 힙이 손상되었습니다."라는 말은 힙을 관리하는 메모리 구조가 오염됐다는 말이다.

 

malloc은 메모리를 할당하면서 링크드 리스트처럼 각각의 할당 메모리 영역에 자신들의 메모리 사이즈 정보 같은 내용을 포인터처럼 저장하고 있다.

 

정확한 동작 방식은 아래 링크를 참조.

 

01.Malloc - glibc(ptmalloc2)[Korean] - TechNote - Lazenca.0x0

“html” 매크로 렌더링 오류 Notify your Confluence administrator that "Bob Swift Atlassian Apps - HTML" requires a valid license. Reason: VERSION_MISMATCH Excuse the ads! We need some help to keep our site up. “html” 매크로 렌더링 오

www.lazenca.net

 

그런데 임의로 어떤 프로세스가 해당 링크 정보를 수정하면 관리, 보안 측면에서 아주 큰 문제가 발생한다.

대부분 이런 일이 발생하는 이유가 Overflow, double free, dangling pointer,.. 등 잘못된 포인터 변수 및 힙 관리 함수를 사용해서 벌어진다.

 

중복 free 시도나 허상 포인터는 대부분? IDE에서 경고하거나 오류를 띄워주는데 힙 오버플로는 전적으로 프로그래머가 찾는 방법밖에 없다.

일단 디버깅을 진행했는데 malloc이 호출 실패하면서 아래와 같은 문구가 출력된다면 해당 내용을 참고하는 것이 정신건강에 이롭다.

 

Visual C++ Debugging memory state

0xABABABAB : HeapAlloc으로 메모리 할당 후 가드 바이트에 채워진 값
0xCCCCCCCC : 초기화되지 않은 스택 메모리
0xCDCDCDCD : 메모리 할당 후 초기화되지 않은 힙 메모리
0xBAADF00D : LocalAlloc(LMEM_FIXED) 메모리 할당된 후 초기화되지 않은 값
0xFDFDFDFD : 할당된 메모리의 전후 가드용 바이트에 채워지는 값
0xFEEEFEEE : 힙 메모리를 해제한 후 채워지는 값

https://en.wikipedia.org/wiki/Magic_number_(programming)
 

위의 6가지 경우는 대표적으로 힙 버그가 발생하는 힙 영역들인데 대부분 free를 중복 호출하거나 허상 포인트, 할당 메모리 해제하지 않아서 발생하는 메모리 누수에 주로 확인할 수 있다.

 

0x00007ff8dbdaf249(ntdll.dll)에(프로젝트.exe의) 처리되지 않은 예외가 있습니다.
0xc0000374: 힙이 손상되었습니다(매개 변수: 0x00007ff8dbe177f0).

이 경우가 제일 골치 아픈데, 디버깅 시 에러 로그에 아무런 정보가 뜨지 않는다.
(매직넘버 정보가 뜨지 않는다.)

해당 정보가 뜨면서 프로그램이 종료되는 이유는 힙 Overflow가 발생하기 때문에 발생하는 것이므로 앞서 말한 힙 영역의 관리를 위한 메모리 상의 관리 포인터 값? 이 임의로 변경되었기 때문이다.

해당 버그를 고치기 위해서는 디버깅을 통해 malloc 호출 실패 지점을 찾고 그 이전에 호출된 함수들의 동작을 확인하여 오버플로 버그가 될만한 부분이 없는지 확인해야 한다.

예를 들어 문자열 복사(strcpy, ...)연산이나 객체 복사, malloc 함수 호출을 잘못했던가 등 overflow가 발생할 만한 부분 모두 확인해야 한다.

 

만약 이 글을 읽는 여러분들이 windbg 등을 활용할 수 있다면 Crash 정보를 확인한다면 보다 자세한 정보를 얻을 수 있을 것이며, 아래 heap 관련 에러가 발생했을 시 디버깅 관련 유용한 정보를 포스팅해놓은 글이니 참고하면 좋을 듯하다.

 

 

 

Heap 메모리 버퍼 오버플로우 디버깅 팁

이번 글은 Heap 메모리 버퍼 오버플로우가 발생하는 경우 간단한 디버깅 팁을 알려드리겠습니다. 응용 프...

blog.naver.com

반응형

'TIP' 카테고리의 다른 글

arm-linux-gcc not found error  (0) 2022.01.16
TIP) IDA & GDB Debugger 연동  (0) 2022.01.11