Visual Studio C ++에서 메모리 할당 표현은 무엇입니까?


216

Visual Studio에서 우리는 모두 "baadf00d"를 가지고 있으며 런타임 동안 C ++에서 디버거의 변수를 검사 할 때 "CC"와 "CD"를 보았습니다.

내가 이해 한 바에 따르면, "CC"는 메모리가 new () 또는 alloc ()이고 단위 화되었을 때만 표시하기 위해 DEBUG 모드에 있습니다. "CD"는 삭제 또는 해제 된 메모리를 나타냅니다. RELEASE 빌드에서 "baadf00d"만 보았습니다 (그러나 잘못되었을 수 있습니다).

때때로 우리는 메모리 누수, 버퍼 오버플로 등의 상황에 처해 있으며 이런 종류의 정보는 유용합니다.

디버깅 목적으로 메모리가 인식 가능한 바이트 패턴으로 설정되는 시점과 시점을 누군가가 지적 할만큼 친절합니까?



@ Lưu Vĩnh Phúc : OS가 아니라 디버거입니다. "D"(0xCD 및 0xDD에서와 같이)는 디버그 용입니다 (예 : malloc_dbg는 msdn.microsoft.com/en-us/library/aa270812(v=vs.60).aspx에 설명 된대로 malloc을 통해 호출되는 것입니다 ). 버퍼 오버런을 추적하기 위해 힙 주위에 울타리 / 게시물을 추가한다고 생각합니다. double-delete 또는 multiple-free 버그 (또는 delete [] 대신 delete 호출 가능)와 폐기 된 포인터를 매달고 데이터를 검사 할 때 "0xDD"인 경우 문제를 포착하는 것이 매우 유용합니다. (또는 초기화되지 않은 힙에 0xCD가 표시되는 경우)
HidekiAI

나는 그것이 OS라고 말하지 않았다. 제목을 잘못 쓴 것은 다른 질문자입니다
phuclv

답변:


317

이 링크에는 자세한 정보가 있습니다.

http://en.wikipedia.org/wiki/Magic_number_ (프로그래밍)

* 0xABABABAB : 힙 메모리 할당 후 "사람의 토지 없음"보호 바이트를 표시하기 위해 Microsoft의 HeapAlloc ()에서 사용
* 0xABADCAFE : 잘못된 포인터를 포착하기 위해 사용 가능한 모든 메모리를 초기화하기 위해이 값으로 시작
* 0xBAADF00D : 초기화되지 않은 할당 힙 메모리를 표시하기 위해 Microsoft의 LocalAlloc (LMEM_FIXED)에서 사용
* 0xBADCAB1E : 디버거에 대한 연결이 끊어지면 오류 코드가 Microsoft eVC 디버거에 반환 됨
* 0xBEEFCACE : Microsoft .NET에서 리소스 파일의 매직 넘버로 사용
* 0xCCCCCCCC : 초기화되지 않은 스택 메모리를 표시하기 위해 Microsoft의 C ++ 디버깅 런타임 라이브러리에서 사용
* 0xCDCDCDCD : 초기화되지 않은 힙 메모리를 표시하기 위해 Microsoft의 C ++ 디버깅 런타임 라이브러리에서 사용
* 0xDDDDDDDDDD : 해제 된 힙 메모리를 표시하기 위해 Microsoft의 C ++ 디버깅 힙에서 사용
* 0xDEADDEAD : 사용자가 수동으로 충돌을 시작할 때 사용되는 Microsoft Windows STOP 오류 코드입니다.
* 0xFDFDFDFD : 할당 된 힙 메모리 전후에 "man 's land"가드 바이트를 표시하기 위해 Microsoft의 C ++ 디버깅 힙에서 사용
* 0xFEEEFEEE : 사용 가능한 힙 메모리를 표시하기 위해 Microsoft의 HeapFree ()에서 사용

20
여기에 BAADF00D(나쁜 음식), BEEFCACE(쇠고기 케이크), BAADCAB1E(나쁜 케이블), BADCAFE(나쁜 카페), DEADDEAD(죽은 시체)가 있습니다. 이것은 의도적 인 것입니까?
Anderson Green

38
@AndersonGreen 물론 의도적입니다. 그것은 hexspeak 라고 합니다 .

28
우리는 과거에 저수준 (운영 체제 커널) 프로그래밍을 할 때 C0CAC01A를 사용했습니다 ...;)
Per Lundberg

2
0xDEADBEEF, 0xC0EDBABEMS의 언어에 속하지 않더라도 고전
J. Paulding

3
폴 매카트니 팬으로서, 나는 좋아 해요BEA71E5
대니 Pflughoeft - BlueRaja

111

실제로 디버그 할당에 유용한 유용한 정보가 많이 있습니다. 이 테이블은 더 완전합니다.

http://www.nobugs.org/developer/win32/debug_crt_heap.html#table

HeapAlloc () 후 주소 오프셋 malloc () 후 free () 동안 HeapFree () 후 주석
0x00320FD8 -40 0x01090009 0x01090009 0x01090009 0x0109005A Win32 힙 정보
0x00320FDC -36 0x01090009 0x00180700 0x01090009 0x00180400 Win32 힙 정보
0x00320FE0 -32 0xBAADF00D 0x00320798 0xDDDDDDDD 0x00320448 다음 CRT 힙 블록에 대한 Ptr (초기 할당 됨)
0x00320FE4 -28 0xBAADF00D 0x00000000 0xDDDDDDDD 0x00320448 CRT 힙 블록 이전 Ptr (나중에 할당 됨)
0x00320FE8 -24 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE malloc () 호출의 파일 이름
0x00320FEC -20 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE malloc () 호출 라인 번호
0x00320FF0 -16 0xBAADF00D 0x00000008 0xDDDDDDDD 0xFEEEFEEE malloc ()의 바이트 수
0x00320FF4 -12 0xBAADF00D 0x00000001 0xDDDDDDDD 0xFEEEFEEE 유형 (0 = 해제, 1 = 정상, 2 = CRT 사용 등)
0x00320FF8-8 0xBAADF00D 0x00000031 0xDDDDDDDD 0xFEEEFEEE 요청 번호, 0에서 증가
0x00320FFC -4 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE 맨스 랜드 없음
0x00321000 +0 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE 원하는 8 바이트
0x00321004 +4 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE 원하는 8 바이트
0x00321008 +8 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE 맨스 랜드 없음
0x0032100C +12 0xBAADF00D 0xBAADF00D 0xDDDDDDDD 0xFEEEFEEE Win32 힙 할당은 16 바이트로 반올림됩니다.
0x00321010 +16 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 힙 부기
0x00321014 +20 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 힙 부기
0x00321018 +24 0x00000010 0x00000010 0x00000010 0xFEEEFEEE Win32 힙 부기
0x0032101C +28 0x00000000 0x00000000 0x00000000 0xFEEEFEEE Win32 힙 부기
0x00321020 +32 0x00090051 0x00090051 0x00090051 0xFEEEFEEE Win32 힙 부기
0x00321024 +36 0xFEEE0400 0xFEEE0400 0xFEEE0400 0xFEEEFEEE Win32 힙 부기
0x00321028 +40 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 힙 부기
0x0032102C +44 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 힙 부기

5

관하여 0xCC0xCD특히, 이들의 유물이다 인텔 8088 / 8086 1980 프로세서 명령어 세트의 뒷면. 소프트웨어 인터럽트 opcode 0xCC의 특별한 경우입니다 . 특수한 1 바이트 버전 에서는 프로그램이 인터럽트 3 을 생성 할 수 있습니다 .INT 0xCD0xCC

원칙적으로 소프트웨어 인터럽트 번호는 임의적이지만 디버거 브레이크 또는 브레이크 포인트 기능 INT 3에는 전통적으로 사용 되었지만 오늘날까지 유지되고 있습니다. 디버거가 시작될 때마다 해당 opcode가 실행될 때 디버거가 트리거되도록 인터럽트 처리기를 설치합니다 . 일반적으로 현재 실행중인 프로그래밍을 일시 중지하고 대화식 프롬프트를 표시합니다.INT 3

일반적으로 x86 INTopcode는 2 바이트이며 0xCD그 뒤에 원하는 인터럽트 번호는 0-255입니다. 이제는 문제 0xCD 0x03를 해결할 수 있지만 INT 3인텔은 0xCC사용하지 않는 메모리의 안정적인 '채우기 바이트'로 작동하기 위해 opcode가 1 바이트 만되기 때문에 추가 바이트없이 특수 버전을 추가하기로 결정했습니다 .

여기서 요점 은 프로세서가 의도 한 명령이 포함되지 않은 메모리로 실수로 점프하는 경우 정상적인 복구를 가능하게 하는 것 입니다. 멀티 바이트 명령어는 잘못된 점프가 올바르게 구성된 명령어 스트림을 계속해야하는 가능한 바이트 오프셋에 도달 할 수 있으므로이 목적에 적합하지 않습니다.

기발한 예외를 분명히 1 바이트 연산 코드는이를 위해 하찮게 일뿐만 아니라이있을 수있다 : 예를 들어, 채우기 순서 고려 0xCDCDCDCD(이 페이지에 언급), 우리가 어디에 상관없이 이후 상당히 신뢰성이 있다고 볼 수 있습니다 명령 포인터의 땅 ( 제외시켰다 아마도 CPU는 올바른 실행을 재개 할 수) 마지막 충전 바이트 2 바이트 x86 명령어를 CD CD205 (0XCD) 소프트웨어 인터럽트를 생성하는데,이 경우에는.

Weirder는 여전히 CD CC CD CC100 % 해석 가능합니다.- INT 3또는 INT 204-시퀀스 CC CD CC CD를 신뢰할 수없고, 표시된 것처럼 75 %에 불과하지만 int 크기의 메모리 필러로 반복하면 일반적으로 99.99 %입니다.

INT 명령을 표시하는 동시 8088/8086 명령 세트 매뉴얼의 페이지
1987 년 매크로 어셈블러 참조


와우, 나는 0xCC가 INT3이라는 것을 알지 못했다. 그것은 의미가 있습니다 (즉, 우연의 일치가 아닙니다). 나는 JMP가 레지스터를 검사하기 위해 JMP가있는 곳에 "NOP + INT3"을 주입하는 경우가있었습니다. 이 통찰력에 감사드립니다, 미스터리가 해결되었습니다!
HidekiAI

무엇을 NOP위해? (바이트 입력) 명령 으로 단일 0xCC바이트를 입력하지 eb않습니까?
Glenn Slayden

단지 습관은 그때, 일부 코드는 2 바이트를 읽고 그것을 점프 테이블로 사용하려고하거나 경우에 따라 어셈블리 코드를 나열 할 때 NOP를 추가하여 '???'로 표시되지 않습니다. 또는 분해 할 때 (더 읽기 쉬운) 것; 결국 여러 가지 이유로 BRK 전후에 NOP를 주입하는 습관이되었습니다. 내가 INT3 + [일부-진수]와 JMP $ XYZW 균형 것, 그래서 이런 경우에, 어떤 앱이 주소 블록의 체크섬을 수행하려고 할 것입니다 미소
HidekiAI
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.