Memory Corruption Heap

2,402 views

Published on

Published in: Technology, Education
0 Comments
2 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,402
On SlideShare
0
From Embeds
0
Number of Embeds
139
Actions
Shares
0
Downloads
49
Comments
0
Likes
2
Embeds 0
No embeds

No notes for slide

Memory Corruption Heap

  1. 1. Memory Corruption - Heap 아꿈사 (http://cafe.naver.com/architect1.cafe) Codevania (http://codevania.textcube.com)
  2. 2. Index <ul><li>What is Heap? </li></ul><ul><ul><li>Heap </li></ul></ul><ul><ul><li>Front End Allocator </li></ul></ul><ul><ul><li>Back End Allocator </li></ul></ul><ul><ul><li>Under the hood of Heap Allocation </li></ul></ul><ul><li>Heap Corruptions </li></ul><ul><ul><li>Using Uninitialized State </li></ul></ul><ul><ul><li>Heap Overruns and Underruns </li></ul></ul><ul><ul><li>Heap Handle Miss Matches </li></ul></ul><ul><ul><li>Heap Reuse After Deletion </li></ul></ul><ul><li>Summary </li></ul>
  3. 3. What is Heap? <ul><li>Heap </li></ul><ul><ul><li>정의 </li></ul></ul><ul><ul><ul><li>애클리케이션이 메모리를 동적으로 할당하고 해제할 필요가 있을 때 사용할 수 있는 메모리 관리자의 한 형태 </li></ul></ul></ul><ul><ul><li>언제 필요한가 ? </li></ul></ul><ul><ul><ul><li>필요한 메모리의 크기를 사전에 알 수 없을 때 </li></ul></ul></ul><ul><ul><ul><li>필요한 메모리가 너무 커서 스택에 할당 할 수 없을 때 </li></ul></ul></ul><ul><ul><li>하이레벨 메모리 관리자 </li></ul></ul><ul><ul><ul><li>가상 메모리 관리자를 이용하는 윈도우 힙 관리자를 사용 </li></ul></ul></ul><ul><ul><ul><li>일반적으로 힙 관리자를 사용 </li></ul></ul></ul><ul><ul><ul><ul><li>다음 페이지에 그림 6.1 첨부 </li></ul></ul></ul></ul>
  4. 4. What is Heap? <ul><li>윈도우 메모리 관리 아키텍쳐 개요 </li></ul>
  5. 5. Allocator <ul><li>Front End Allocator ( 이하 FEA) </li></ul><ul><li>Back End Allocator ( 이하 BEA) </li></ul>
  6. 6. Allocator <ul><li>Front End Allocator </li></ul><ul><ul><li>BEA 를 위한 추상적인 최적화 계층 </li></ul></ul><ul><ul><li>상이한 FEA 를 둠 </li></ul></ul><ul><ul><ul><li>다른 메모리 요구를 가진 애플리케이션은 적절한 할당자를 선택 가능 </li></ul></ul></ul><ul><ul><ul><li>Ex) 작은 메모리 할당을 빈번하게 할 것으로 예상되는 애플리케이션 </li></ul></ul></ul><ul><ul><ul><ul><li>단편화를 피하기 위해 LowFragment FEA 를 선호할 수 있다 </li></ul></ul></ul></ul><ul><ul><ul><li>윈도우에는 두 가지 FEA 가 존재 </li></ul></ul></ul><ul><ul><ul><ul><li>Look aside list (LAL) front end allocator </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>메모리 할당의 가장 빠른 방법 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><li>Low fragment (LF) front end allocator </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>참조 : http://msdn.microsoft.com/en-us/library/aa366750(VS.85).aspx </li></ul></ul></ul></ul></ul>
  7. 7. Allocator <ul><li>Front End Allocator </li></ul><ul><ul><li>할당 요청 시나리오 [ 성공 ] </li></ul></ul><ul><ul><ul><li>초기 </li></ul></ul></ul><ul><ul><ul><ul><li>[1] 크기가 16 인 3 개의 힙 블록 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>[3] 크기가 32 인 2 개의 힙 블록 </li></ul></ul></ul></ul><ul><ul><ul><li>크기가 24 인 힙 블록 할당 요청 </li></ul></ul></ul><ul><ul><ul><ul><li>24 + 8 (Metadata) = 32 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>32 / 8 = 4 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>4 – 1 (Zero-Based Table) = 3 </li></ul></ul></ul></ul><ul><ul><ul><li>[3] 조사 </li></ul></ul></ul><ul><ul><ul><ul><li>2 개 이용 가능 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>첫 블록 제거 , 호출자에게 반환 </li></ul></ul></ul></ul><ul><ul><li>할당 요청 시나리오 [ 실패 ] </li></ul></ul><ul><ul><ul><li>크기가 16 인 힙 블록 요청 </li></ul></ul></ul><ul><ul><ul><li>[2] 에 없음  BEA 로 포워딩 </li></ul></ul></ul>
  8. 8. Allocator <ul><li>Back End Allocator </li></ul>
  9. 9. Allocator <ul><li>Back End Allocator </li></ul><ul><ul><li>프리 리스트라 불리는 리스트 테이블을 소유 </li></ul></ul><ul><ul><ul><li>프리 리스트 </li></ul></ul></ul><ul><ul><ul><ul><li>책임 : 특정 힙 내의 모든 프리 힙 블록을 추적 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>개수 : 128 개 . </li></ul></ul></ul></ul><ul><ul><ul><ul><li>크기 </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>각 리스트는 특정 크기의 힙 블록을 소유 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>각 크기는 이전 크기에서 8 바이트씩 증가 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>최대 할당 크기를 초과하는 할당은 [0] 에 위치 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><li>관리 : 효율을 위해 비트맵 사용 </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>0: 프리 힙 블록 없음 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>1: 프리 힙 블록 소유 </li></ul></ul></ul></ul></ul>
  10. 10. Allocator <ul><li>Back End Allocator </li></ul><ul><ul><li>블록 분리 (Block Splitting) </li></ul></ul><ul><ul><ul><li>요청받은 크기의 프리 힙 블록을 발견하지 못할 때 사용 </li></ul></ul></ul><ul><ul><ul><li>요청된 프리 힙 블록보다 큰 블록을 같은 크기의 두 블록으로 나누어서 할당 요청을 만족시킴 </li></ul></ul></ul>
  11. 11. Allocator <ul><li>Back End Allocator </li></ul><ul><ul><li>큰 할당 </li></ul></ul><ul><ul><ul><li>프리 리스트 [0] </li></ul></ul></ul><ul><ul><ul><ul><li>1016 ~ 0x7FFF0(524272) 바이트 까지만 포함 가능 </li></ul></ul></ul></ul><ul><ul><ul><li>0x7FFF0 보다 큰 할당 </li></ul></ul></ul><ul><ul><ul><ul><li>힙 관리자는 가상 메모리 관리자에게 명시적인 할당 요청 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>이들 할당을 가상 할당 리스트에 보관 </li></ul></ul></ul></ul>
  12. 12. Heap Manager <ul><li>cf1. 힙 관리자는 메모리를 어디서 가져오나 ? </li></ul><ul><ul><li>큰 덩어리 (chunk) 의 메모리를 할당하기 위해 윈도우 가상 메모리 관리자를 사용 </li></ul></ul><ul><ul><li>힙 세그먼트 </li></ul></ul><ul><ul><ul><li>가상 메모리 관리자에게 요청하는 덩어리 </li></ul></ul></ul>
  13. 13. Heap segment <ul><li>cf2. 힙 세그먼트의 기본적인 배치 </li></ul><ul><ul><li>Figure 6.7 은 두 개의 할당과 커밋되지 않은 메모리 영역이 존재하는 상태 </li></ul></ul><ul><ul><li>새로운 세그먼트가 생성되면…  힙 관리자는 새롭게 생성된 세그먼트를 추적 리스트에 추가 </li></ul></ul>
  14. 14. Pre- & Post- Allocation Metadata <ul><li>cf3. 선 / 후 할당 메타데이터의 구조 </li></ul><ul><ul><li>메타데이터 </li></ul></ul><ul><ul><ul><li>세그먼트 내의 힙 블록의 효과적인 관리를 위해 사용 </li></ul></ul></ul>
  15. 15. Heap Coalescing <ul><li>cf4. 힙 합병 (Heap Coalescing) </li></ul><ul><ul><li>메모리 단편화 문제를 피하기 위한 메커니즘 </li></ul></ul><ul><ul><li>인접한 프리 블록을 하나의 큰 블록으로 합침 </li></ul></ul><ul><ul><li>비용 높음 </li></ul></ul>
  16. 16. What is Heap? <ul><li>Summary </li></ul><ul><ul><li>메모리 블록 할당 </li></ul></ul><ul><ul><ul><li>프리 블록 메모리가 이용 가능한지 확인 </li></ul></ul></ul><ul><ul><ul><ul><li>FEA 의 Look Aside List 를 참조 </li></ul></ul></ul></ul><ul><ul><ul><li>이용 가능 </li></ul></ul></ul><ul><ul><ul><ul><li>프리 블록 메모리를 호출자에게 반환 </li></ul></ul></ul></ul><ul><ul><ul><li>이용 불가 </li></ul></ul></ul><ul><ul><ul><ul><li>BEA 의 프리 리스트가 참조됨 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>정확하게 크기가 일치함 </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>플래그 갱신  해당 블록이 Busy 함을 나타냄 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>이 블록은 프리 리스트에서 제거되고 , 호출자로 반환됨 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><li>정확하게 크기가 일치하지 않음 </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>요청된 할당 크기보다 큰 블록을 양분할 수 있는지 검사 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>가능하면 양분 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>하나는 Busy 상태로 갱신되어 반환됨 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>다른 하나는 Free 상태로 설정되어 프리 리스트에 추가됨 </li></ul></ul></ul></ul></ul>
  17. 17. What is Heap? <ul><li>Summary </li></ul><ul><ul><li>메모리 블록 해제 </li></ul></ul><ul><ul><ul><li>FEA 가 해당 프리 블록을 처리할 수 있는지 요구 </li></ul></ul></ul><ul><ul><ul><li>처리 가능 </li></ul></ul></ul><ul><ul><ul><ul><li>프리 리스트에 추가 </li></ul></ul></ul></ul><ul><ul><ul><li>처리 불가 </li></ul></ul></ul><ul><ul><ul><ul><li>인접한 프리 블록이 존재 </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>두 개의 인접한 프리 블록이 프리 리스트에서 제거됨 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>새로운 큰 블록이 Free List 나 Look-aside List 에 추가됨 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>새로운 큰 블록의 플래그 필드 갱신  Free 상태 </li></ul></ul></ul></ul></ul><ul><ul><ul><ul><li>인접한 프리 불록이 부재 </li></ul></ul></ul></ul><ul><ul><ul><ul><ul><li>이 블록은 Free List 나 Look-aside List 로 이동되고 플래그는 Free 상태로 갱신됨 </li></ul></ul></ul></ul></ul>
  18. 18. Under the hood of Heap Allocation
  19. 19. Under the hood of Heap Allocation <ul><li>PEB (Process Environment Block) </li></ul><ul><ul><li>실행 중인 각 프로세스가 유지하는 액티브 힙 리스트 포함프로세스에 관한 정보용 구조체 </li></ul></ul>
  20. 20. Under the hood of Heap Allocation <ul><li>힙 포인터의 배열 덤프 </li></ul><ul><ul><li>5 개의 힙이 덤프되어 있음 ( 책에는 3 개임 ) </li></ul></ul><ul><ul><li>왜 하나 이상의 힙이 존재 ? </li></ul></ul><ul><ul><ul><li>자신들만의 힙을 생성하는 컴포넌트를 내부적으로 사용 </li></ul></ul></ul><ul><ul><ul><li>초기화 동안에 자신의 힙을 생성하는 C 런타임이 좋은 예 </li></ul></ul></ul>
  21. 21. Under the hood of Heap Allocation <ul><li>프로세스 힙에 관한 정보 덤프 </li></ul>
  22. 22. Under the hood of Heap Allocation <ul><li>HeapAlloc 함수 수행 전 / 후 </li></ul>
  23. 23. Heap Corruptions <ul><li>Using Uninitialized State </li></ul><ul><ul><li>초기화 되지 않은 상태란 ? </li></ul></ul><ul><ul><ul><li>성공적으로 할당은 이뤄졌으나 </li></ul></ul></ul><ul><ul><ul><li>사용하기에 유효한 상태로 초기화되지 않은 메모리 블록 </li></ul></ul></ul>
  24. 24. Heap Corruptions <ul><li>Using Uninitialized State </li></ul><ul><ul><li>애플리케이션 실패 원인 </li></ul></ul><ul><ul><ul><li>첫 번째 항목을 디레퍼런스 할 때 </li></ul></ul></ul><ul><ul><ul><li>주소가 유효하지 않다면 접근 위반 </li></ul></ul></ul><ul><ul><ul><li>무엇이 발생할 것인가는 임의의 포인터 값에 의존 </li></ul></ul></ul>
  25. 25. Heap Corruptions <ul><li>Using Uninitialized State </li></ul><ul><ul><li>디버거에서 실행 </li></ul></ul>힙 관리자는 자동으로 모든 메모리를 채움 패턴으로 초기화 . c0c0c0c0  힙 블록이 할당되었지만 아직 초기화되지 않았음을 표현
  26. 26. Heap Corruptions <ul><li>Using Uninitialized State </li></ul><ul><ul><li>실행 후 디버거 어태치 </li></ul></ul><ul><ul><ul><li>책에서는 디버거에서 실행하는 것과 다르다고 하는데 뭘 잘못했는지 계속 동일하게 나옴 ;; </li></ul></ul></ul><ul><ul><li>위반이 즉시 발견되지 않는 경우라면 </li></ul></ul><ul><ul><ul><li>위반이 발생할 때의 스택은 코드와 아무런 관계 없음 </li></ul></ul></ul><ul><ul><ul><li>이 위치에서 손상의 출처를 찾는 것은 , 극도로 난해 </li></ul></ul></ul><ul><ul><ul><li>디버거에서 프로세스를 시작해 채움패턴을 사용하도록 </li></ul></ul></ul>
  27. 27. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul><ul><ul><li>오류 코드가 메타데이터를 덮어 쓴다 </li></ul></ul><ul><ul><ul><li>힙의 무결성 손상  애플리케이션 폴트 </li></ul></ul></ul><ul><ul><ul><li>힙 블록의 소유자가 블록의 경계를 소홀히 할 때 발생 </li></ul></ul></ul>
  28. 28. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul>
  29. 29. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul>
  30. 30. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul><ul><ul><li>스택 </li></ul></ul><ul><ul><ul><li>접근 위반시 셧다운 중이었을 것으로 추정됨 </li></ul></ul></ul><ul><ul><li>문제점 </li></ul></ul><ul><ul><ul><li>스택에 코드가 보이지 않음 </li></ul></ul></ul><ul><ul><ul><li>가장 큰 문제는 , </li></ul></ul></ul><ul><ul><ul><ul><li>폴트를 유발한 코드가 손상 시점에 쉽게 트랩 될 수 없음 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>손상은 실행이 한참 진행된 이후에 나타남 </li></ul></ul></ul></ul><ul><ul><li>실마리 추적 </li></ul></ul><ul><ul><ul><li>힙의 어느 부분이 손상됐는지 모름 </li></ul></ul></ul><ul><ul><ul><li> 세그먼트 보존 여부 확인 (!heap 확장 명령 사용 ) </li></ul></ul></ul>
  31. 31. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul>
  32. 32. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul>
  33. 33. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul><ul><ul><li>힙 관리자는 덮어쓰기가 발생한 바로 그 시점에 감지하지 못했고 , 실행이 한참 진행된 이후에 감지 </li></ul></ul><ul><ul><li>힙상태가 불완전하게 되어 접근 위반으로 이어졌음 </li></ul></ul>
  34. 34. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul><ul><ul><li>쓰여진 후가 아니라 쓰여질 때에 실행을 중단하자 </li></ul></ul><ul><ul><ul><li>애플리케이션 베리파이어 사용 </li></ul></ul></ul><ul><ul><ul><ul><li>힙 블록을 서로 격리해 보호하는 페이지 힙을 이용 </li></ul></ul></ul></ul>기존 Varifier 사용으로 인한 추가 메모리
  35. 35. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul><ul><ul><li>Application Varifier 사용 (Not Full) </li></ul></ul>
  36. 36. Heap Corruptions <ul><li>Heap Overruns and Underruns </li></ul><ul><ul><li>Application Varifier 사용 (Full) </li></ul></ul>
  37. 37. Heap Corruptions <ul><li>완전 페이지 힙 </li></ul><ul><ul><li>왜 항상 사용하지 않나 ? </li></ul></ul><ul><ul><ul><li>너무 많은 자원을 소비하기 때문 </li></ul></ul></ul><ul><ul><ul><li>메모리 소비를 엄청나게 증가시킬 수 있음 </li></ul></ul></ul><ul><ul><ul><li>디폴트는 보호 페이지가 끝부분에 위치 . </li></ul></ul></ul><ul><ul><ul><ul><li>Backward Option 을 활성화 시키면 앞부분에도 보호 가능 </li></ul></ul></ul></ul><ul><li>Heap Underruns </li></ul><ul><ul><li>잘못된 포인터 연산으로 인해서 힙 블록의 앞부분에 쓰게 되는 경우 발생 </li></ul></ul>
  38. 38. Heap Corruptions <ul><li>Heap Handle Miss Matches </li></ul><ul><ul><li>힙 관리자 </li></ul></ul><ul><ul><ul><li>프로세스 내의 액티브 힙에 대한 리스트를 유지 </li></ul></ul></ul><ul><ul><ul><li>메모리를 할당 / 해제 시 정확한 힙 사용을 보장해야함 </li></ul></ul></ul><ul><ul><ul><ul><li>힙의 내부 상태는 그 특정 힙 컨텍스트 내에서만 유효 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>즉 , 힙은 별개의 개체라고 할 수 있음 </li></ul></ul></ul></ul><ul><ul><li>힙 핸들 </li></ul></ul><ul><ul><ul><li>힙의 고유성을 보장하기 위함 </li></ul></ul></ul><ul><ul><ul><li>고유성이 보장되지 못한다면 힙 손상 발생 </li></ul></ul></ul>
  39. 39. Heap Corruptions <ul><li>Heap Handle Miss Matches </li></ul>
  40. 40. Heap Corruptions <ul><li>Heap Handle Miss Matches </li></ul>
  41. 41. Heap Corruptions <ul><li>Heap Reuse after Deletion </li></ul>
  42. 42. <ul><li>Heap Reuse after Deletion </li></ul>Before After 바뀌었음
  43. 43. Heap Corruptions <ul><li>Heap Reuse after Deletion </li></ul>
  44. 44. Heap Corruptions <ul><li>Heap Reuse after Deletion </li></ul>
  45. 45. Summary <ul><li>힙 손상 </li></ul><ul><ul><li>애플리케이션에 손상을 가할 수 있느 심각한 에러 </li></ul></ul><ul><ul><ul><li>한 바이트 차이 손상일지라도 , 애플리케이션이… </li></ul></ul></ul><ul><ul><ul><ul><li>크래시되거나 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>예측할 수 없는 행위를 하거나 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>무한 루프에 빠질 수 있다 </li></ul></ul></ul></ul><ul><ul><li>결과를 즉시 볼 수 없음 </li></ul></ul><ul><ul><ul><li>손상이 일어난 후까지도 , 일반적으로 드러나지 않음 </li></ul></ul></ul><ul><ul><ul><ul><li>힙 손상의 출처 파악을 매우 어렵게 만듬 </li></ul></ul></ul></ul><ul><ul><ul><ul><li>Application Varifier 를 사용하면 좀 쉽게 찾을 수 있음 </li></ul></ul></ul></ul>

×