243

In Visual Studio, we've all had "baadf00d", have seen seen "CC" and "CD" when inspecting variables in the debugger in C++ during run-time.

From what I understand, "CC" is in DEBUG mode only to indicate when a memory has been new() or alloc() and unitilialized. While "CD" represents delete'd or free'd memory. I've only seen "baadf00d" in RELEASE build (but I may be wrong).

Once in a while, we get into a situation of tacking memory leaks, buffer overflows, etc and these kind of information comes in handy.

Would somebody be kind enough to point out when and in what modes the memory are set to recognizable byte patterns for debugging purpose?

Glenn Slayden
  • 17,543
  • 3
  • 114
  • 108
HidekiAI
  • 3,013
  • 3
  • 20
  • 22
  • [When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?](http://stackoverflow.com/q/370195/995714) – phuclv Feb 23 '16 at 05:56
  • @Lưu Vĩnh Phúc : It's not the OS, it's the debugger. The "D" (as on 0xCD and 0xDD) is for Debug (i.e. malloc_dbg is what gets called via malloc as explained in https://msdn.microsoft.com/en-us/library/aa270812(v=vs.60).aspx). I believe it also adds fence/posts around the heaps for tracking buffer-overruns. It's quite useful to catch issues when you have a bug of double-delete or multiple-free (or even possible calling of delete instead of delete[]) and dangling pointers which has been disposed and when you inspect the data, it's "0xDD" (or when uninitialized heap shows 0xCD) – HidekiAI Feb 23 '16 at 18:19
  • I didn't say thay it's the OS. It's the other asker that wrote the tittle incorrectly – phuclv Feb 23 '16 at 23:40
  • Possible duplicate of [When and why will an OS initialise memory to 0xCD, 0xDD, etc. on malloc/free/new/delete?](https://stackoverflow.com/questions/370195/when-and-why-will-an-os-initialise-memory-to-0xcd-0xdd-etc-on-malloc-free-new) – phuclv May 06 '18 at 16:27

3 Answers3

356

This link has more information:

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

* 0xABABABAB : Used by Microsoft's HeapAlloc() to mark "no man's land" guard bytes after allocated heap memory
* 0xABADCAFE : A startup to this value to initialize all free memory to catch errant pointers
* 0xBAADF00D : Used by Microsoft's LocalAlloc(LMEM_FIXED) to mark uninitialised allocated heap memory
* 0xBADCAB1E : Error Code returned to the Microsoft eVC debugger when connection is severed to the debugger
* 0xBEEFCACE : Used by Microsoft .NET as a magic number in resource files
* 0xCCCCCCCC : Used by Microsoft's C++ debugging runtime library to mark uninitialised stack memory
* 0xCDCDCDCD : Used by Microsoft's C++ debugging runtime library to mark uninitialised heap memory
* 0xDDDDDDDD : Used by Microsoft's C++ debugging heap to mark freed heap memory
* 0xDEADDEAD : A Microsoft Windows STOP Error code used when the user manually initiates the crash.
* 0xFDFDFDFD : Used by Microsoft's C++ debugging heap to mark "no man's land" guard bytes before and after allocated heap memory
* 0xFEEEFEEE : Used by Microsoft's HeapFree() to mark freed heap memory
Ken Y-N
  • 14,644
  • 21
  • 71
  • 114
Mark Ingram
  • 71,849
  • 51
  • 176
  • 230
  • 25
    Here, I see `BAADF00D` (bad food), `BEEFCACE` (beef cake), `BAADCAB1E` (bad cable), `BADCAFE` (bad cafe), and `DEADDEAD` (dead dead). Is this intentional? – Anderson Green Feb 16 '13 at 04:23
  • 47
    @AndersonGreen Of course it's intentional. It's called [hexspeak](http://en.wikipedia.org/wiki/Hexspeak). –  May 09 '13 at 14:20
  • 34
    We used to use C0CAC01A when we did some low-level (operating system kernel) programming back in the days... ;) – Per Lundberg Sep 04 '13 at 12:36
  • 5
    `0xDEADBEEF`, `0xC0EDBABE` also classics even if they didn't fall into MS's vernacular – J. Paulding Apr 08 '15 at 18:52
  • 0xFD is also flood-filled by the debug version of MS strncat_s family to indicate the bytes of the destination string that were not written to. – ajs410 May 14 '15 at 15:44
  • @ajs410 Yes, it is. And this breaks some implementations where strncat did not write more memory than necessary, and the function is replaced by the _s variant. The old implementation just relied on the old behavior, what might be undocumented but verified. – harper Jun 06 '15 at 16:55
  • 4
    As a Paul McCartney fan, I'm fond of `BEA71E5` – BlueRaja - Danny Pflughoeft Jun 06 '15 at 18:22
  • 1
    0xCCCCCCCC is not just used to mark uninitialized stack memory, but also as a canary value to detect buffer overflows and underflows on the stack when /RTCs is specified. – Hadi Brais Oct 15 '17 at 02:47
  • I don't know why vs can't show some human readable message!@microsoft – Albert.Qing Jul 08 '19 at 08:18
  • 3
    @Albert.Qing For C++ developers, this is human-readable. (Or don't count C++ developers as humans?) ;-) (Meanwhile, switch to hex. is the first thing I do when I see unexpected strange variable values in the VS debugger.) Seriously, how to store a human-readable message into a variable which is of type `int` or `double`? Hexspeak is a solution... – Scheff's Cat Jul 09 '19 at 06:48
  • 1
    @PerLundberg `0xC0CAC01A`? Subliminal advertising is _everywhere_. – Varad Mahashabde Jan 06 '20 at 18:43
  • @VaradMahashabde :) https://github.com/chaos4ever/chaos/blob/acb8b52c9a59b8b516f1f6811fb2d935ccdfc115/storm/x86/process.c#L471 – Per Lundberg Jan 07 '20 at 10:15
  • This is like... super useful (not being sarcastic). Thanks so much – Aviv Cohn Mar 16 '20 at 22:18
115

There's actually quite a bit of useful information added to debug allocations. This table is more complete:

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

Address  Offset After HeapAlloc() After malloc() During free() After HeapFree() Comments
0x00320FD8  -40    0x01090009    0x01090009     0x01090009    0x0109005A     Win32 heap info
0x00320FDC  -36    0x01090009    0x00180700     0x01090009    0x00180400     Win32 heap info
0x00320FE0  -32    0xBAADF00D    0x00320798     0xDDDDDDDD    0x00320448     Ptr to next CRT heap block (allocated earlier in time)
0x00320FE4  -28    0xBAADF00D    0x00000000     0xDDDDDDDD    0x00320448     Ptr to prev CRT heap block (allocated later in time)
0x00320FE8  -24    0xBAADF00D    0x00000000     0xDDDDDDDD    0xFEEEFEEE     Filename of malloc() call
0x00320FEC  -20    0xBAADF00D    0x00000000     0xDDDDDDDD    0xFEEEFEEE     Line number of malloc() call
0x00320FF0  -16    0xBAADF00D    0x00000008     0xDDDDDDDD    0xFEEEFEEE     Number of bytes to malloc()
0x00320FF4  -12    0xBAADF00D    0x00000001     0xDDDDDDDD    0xFEEEFEEE     Type (0=Freed, 1=Normal, 2=CRT use, etc)
0x00320FF8  -8     0xBAADF00D    0x00000031     0xDDDDDDDD    0xFEEEFEEE     Request #, increases from 0
0x00320FFC  -4     0xBAADF00D    0xFDFDFDFD     0xDDDDDDDD    0xFEEEFEEE     No mans land
0x00321000  +0     0xBAADF00D    0xCDCDCDCD     0xDDDDDDDD    0xFEEEFEEE     The 8 bytes you wanted
0x00321004  +4     0xBAADF00D    0xCDCDCDCD     0xDDDDDDDD    0xFEEEFEEE     The 8 bytes you wanted
0x00321008  +8     0xBAADF00D    0xFDFDFDFD     0xDDDDDDDD    0xFEEEFEEE     No mans land
0x0032100C  +12    0xBAADF00D    0xBAADF00D     0xDDDDDDDD    0xFEEEFEEE     Win32 heap allocations are rounded up to 16 bytes
0x00321010  +16    0xABABABAB    0xABABABAB     0xABABABAB    0xFEEEFEEE     Win32 heap bookkeeping
0x00321014  +20    0xABABABAB    0xABABABAB     0xABABABAB    0xFEEEFEEE     Win32 heap bookkeeping
0x00321018  +24    0x00000010    0x00000010     0x00000010    0xFEEEFEEE     Win32 heap bookkeeping
0x0032101C  +28    0x00000000    0x00000000     0x00000000    0xFEEEFEEE     Win32 heap bookkeeping
0x00321020  +32    0x00090051    0x00090051     0x00090051    0xFEEEFEEE     Win32 heap bookkeeping
0x00321024  +36    0xFEEE0400    0xFEEE0400     0xFEEE0400    0xFEEEFEEE     Win32 heap bookkeeping
0x00321028  +40    0x00320400    0x00320400     0x00320400    0xFEEEFEEE     Win32 heap bookkeeping
0x0032102C  +44    0x00320400    0x00320400     0x00320400    0xFEEEFEEE     Win32 heap bookkeeping
Michael Myers
  • 188,989
  • 46
  • 291
  • 292
John Dibling
  • 99,718
  • 31
  • 186
  • 324
8

Regarding 0xCC and 0xCD in particular, these are relics from the Intel 8088/8086 processor instruction set back in the 1980s. 0xCC is a special case of the software interrupt opcode INT 0xCD. The special single-byte version 0xCC allows a program to generate interrupt 3.

Although software interrupt numbers are, in principle, arbitrary, INT 3 was traditionally used for the debugger break or breakpoint function, a convention which remains to this day. Whenever a debugger is launched, it installs an interrupt handler for INT 3 such that when that opcode is executed the debugger will be triggered. Typically it will pause the currently running programming and show an interactive prompt.

Normally, the x86 INT opcode is two bytes: 0xCD followed by the desired interrupt number from 0-255. Now although you could issue 0xCD 0x03 for INT 3, Intel decided to add a special version--0xCC with no additional byte--because an opcode must be only one byte in order to function as a reliable 'fill byte' for unused memory.

The point here is to allow for graceful recovery if the processor mistakenly jumps into memory that does not contain any intended instructions. Multi-byte instructions aren't suited this purpose since an erroneous jump could land at any possible byte offset where it would have to continue with a properly formed instruction stream.

Obviously, one-byte opcodes work trivially for this, but there can also be quirky exceptions: for example, considering the fill sequence 0xCDCDCDCD (also mentioned on this page), we can see that it's fairly reliable since no matter where the instruction pointer lands (except perhaps the last filled byte), the CPU can resume executing a valid two-byte x86 instruction CD CD, in this case for generating software interrupt 205 (0xCD).

Weirder still, whereas CD CC CD CC is 100% interpretable--giving either INT 3 or INT 204--the sequence CC CD CC CD is less reliable, only 75% as shown, but generally 99.99% when repeated as an int-sized memory filler.

page from contemporaneous 8088/8086 instruction set manual showing INT instruction
Macro Assembler Reference, 1987

Glenn Slayden
  • 17,543
  • 3
  • 114
  • 108
  • Wow, I did not realize (connect the two) 0xCC was INT3. That makes sense (i.e. not by coincidence). I used to inject "NOP + INT3" on places where there are JMP's to inspect registers before it jumped on few occasions (way back when). Thanks for this insight, mystery solved! – HidekiAI Jan 20 '18 at 14:54
  • What was the `NOP` for? Wouldn't entering a single `0xCC` byte with the `eb` (enter bytes) command suffice? – Glenn Slayden Jan 20 '18 at 23:34
  • Just an habit, back then, some code would read two bytes and try to use it as jump table, or in some cases, when I list the assembly code, by adding NOP, it would not show as '???' or something (more legible) when disassembling; all in all, for multiple reasons, it just became an habit to just inject a NOP before or after the BRK; oh in some cases, some apps would try to do checksum of the block of addresses, so I'd balance out the JMP $XYZW with INT3 + [some-hex] *grin* – HidekiAI Feb 05 '18 at 13:45