In Visual Studio C ++, quali sono le rappresentazioni di allocazione della memoria?


216

In Visual Studio, tutti abbiamo avuto "baadf00d", abbiamo visto "CC" e "CD" durante l'ispezione delle variabili nel debugger in C ++ durante il runtime.

Da quanto ho capito, "CC" è in modalità DEBUG solo per indicare quando una memoria è stata nuova () o alloc () e unitilializzata. Mentre "CD" rappresenta la memoria eliminata o libera. Ho visto solo "baadf00d" nella build RELEASE (ma potrei sbagliarmi).

Di tanto in tanto ci imbattiamo in una perdita di memoria, buffer overflow, ecc. E questo tipo di informazioni è utile.

Qualcuno sarebbe abbastanza gentile da indicare quando e in quali modalità la memoria è impostata su schemi di byte riconoscibili a scopo di debug?



@ Lưu Vĩnh Phúc: non è il sistema operativo, è il debugger. La "D" (come su 0xCD e 0xDD) è per Debug (ovvero malloc_dbg è ciò che viene chiamato tramite malloc come spiegato in msdn.microsoft.com/en-us/library/aa270812(v=vs.60).aspx ). Credo che aggiunga anche recinzione / messaggi intorno ai cumuli per il monitoraggio dei sovraccarichi del buffer. È abbastanza utile rilevare i problemi quando si dispone di un bug di double-delete o multiple-free (o anche possibile chiamata di delete invece di delete []) e puntatori penzolanti che sono stati eliminati e quando si ispezionano i dati, è "0xDD" (o quando un heap non inizializzato mostra 0xCD)
HidekiAI

Non ho detto che è il sistema operativo. È l'altro richiedente che ha scritto il
tittle in

Risposte:


317

Questo link contiene ulteriori informazioni:

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

* 0xABABABAB: utilizzato da Microsoft HeapAlloc () per contrassegnare i byte di guardia "terra di nessuno" dopo aver allocato la memoria heap
* 0xABADCAFE: avvio a questo valore per inizializzare tutta la memoria libera per rilevare i puntatori errati
* 0xBAADF00D: utilizzato da LocalAlloc di Microsoft (LMEM_FIXED) per contrassegnare la memoria heap allocata non inizializzata
* 0xBADCAB1E: il codice di errore è stato restituito al debugger di Microsoft eVC quando la connessione è interrotta al debugger
* 0xBEEFCACE: utilizzato da Microsoft .NET come numero magico nei file di risorse
* 0xCCCCCCCC: utilizzato dalla libreria di runtime di debug C ++ di Microsoft per contrassegnare la memoria dello stack non inizializzata
* 0xCDCDCDCD: utilizzato dalla libreria di runtime di debug C ++ di Microsoft per contrassegnare la memoria heap non inizializzata
* 0xDDDDDDDD: utilizzato dall'heap di debug C ++ di Microsoft per contrassegnare la memoria dell'heap liberata
* 0xDEADDEAD: un codice di errore STOP di Microsoft Windows utilizzato quando l'utente avvia manualmente l'arresto anomalo.
* 0xFDFDFDFD: utilizzato dall'heap di debug C ++ di Microsoft per contrassegnare i byte di guardia "terra di nessuno" prima e dopo l'allocazione della memoria dell'heap
* 0xFEEEFEEE: utilizzato da Microsoft HeapFree () per contrassegnare la memoria heap liberata

20
Qui vedo BAADF00D(cibo cattivo), BEEFCACE(torta di manzo), BAADCAB1E(cavo cattivo), BADCAFE(caffè cattivo) e DEADDEAD(morto morto). È intenzionale?
Anderson Green,

38
@AndersonGreen Naturalmente è intenzionale. Si chiama hexspeak .

28
Usavamo C0CAC01A quando nei giorni precedenti eseguivamo una programmazione di basso livello (kernel del sistema operativo ...;)
Per Lundberg

2
0xDEADBEEF, 0xC0EDBABEanche classici, anche se non caddero nel volgare della SM
J. Paulding,

3
Come fan di Paul McCartney, sono affezionato aBEA71E5
BlueRaja - Danny Pflughoeft il

111

In realtà ci sono molte informazioni utili aggiunte alle allocazioni di debug. Questa tabella è più completa:

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

Offset indirizzo dopo HeapAlloc () Dopo malloc () Durante i commenti gratuiti () Dopo HeapFree ()
0x00320FD8 -40 0x01090009 0x01090009 0x01090009 0x0109005A Informazioni heap Win32
0x00320FDC -36 0x01090009 0x00180700 0x01090009 0x00180400 Informazioni heap Win32
0x00320FE0 -32 0xBAADF00D 0x00320798 0xDDDDDDDDD 0x00320448 Ptr al successivo blocco heap CRT (allocato prima nel tempo)
0x00320FE4 -28 0xBAADF00D 0x00000000 0xDDDDDDDD 0x00320448 Ptr per prevenire il blocco heap CRT (allocato più avanti nel tempo)
0x00320FE8 -24 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Nome file della chiamata malloc ()
0x00320FEC -20 0xBAADF00D 0x00000000 0xDDDDDDDD 0xFEEEFEEE Numero linea della chiamata malloc ()
0x00320FF0 -16 0xBAADF00D 0x00000008 0xDDDDDDDD 0xFEEEFEEE Numero di byte da malloc ()
0x00320FF4 -12 0xBAADF00D 0x00000001 0xDDDDDDDD 0xFEEEFEEE Tipo (0 = Libero, 1 = Normale, 2 = Uso CRT, ecc.)
0x00320FF8 -8 0xBAADF00D 0x00000031 0xDDDDDDDD 0xFEEEFEEE Numero richiesta, aumenta da 0
0x00320FFC -4 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEFEEE Terra di nessuno
0x00321000 +0 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE Gli 8 byte desiderati
0x00321004 +4 0xBAADF00D 0xCDCDCDCD 0xDDDDDDDD 0xFEEEFEEE Gli 8 byte desiderati
0x00321008 +8 0xBAADF00D 0xFDFDFDFD 0xDDDDDDDD 0xFEEEEEFEEE Terra non equipaggiata
0x0032100C +12 0xBAADF00D 0xBAADF00D 0xDDDDDDDD 0xFEEEFEEE Le allocazioni dell'heap Win32 sono arrotondate a 16 byte
0x00321010 +16 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 contabilità heap
0x00321014 +20 0xABABABAB 0xABABABAB 0xABABABAB 0xFEEEFEEE Win32 contabilità heap
0x00321018 +24 0x00000010 0x00000010 0x00000010 0xFEEEFEEE Win32 contabilità heap
0x0032101C +28 0x00000000 0x00000000 0x00000000 0xFEEEFEEE Win32 contabilità heap
0x00321020 +32 0x00090051 0x00090051 0x00090051 0xFEEEFEEE Win32 contabilità heap
0x00321024 +36 0xFEEE0400 0xFEEE0400 0xFEEE0400 0xFEEEFEEE Win32 contabilità heap
0x00321028 +40 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 contabilità heap
0x0032102C +44 0x00320400 0x00320400 0x00320400 0xFEEEFEEE Win32 contabilità heap

5

Per quanto riguarda 0xCCe 0xCDin particolare, questi sono reperti del Intel 8088 / 8086 set di istruzioni del processore di nuovo nel 1980. 0xCCè un caso speciale del codice operativo di interruzione del software . La speciale versione a byte singolo consente a un programma di generare interrupt 3 .INT 0xCD0xCC

Sebbene i numeri di interruzione del software siano, in linea di principio, arbitrari, INT 3veniva tradizionalmente utilizzato per la funzione break o breakpoint del debugger , una convenzione che rimane fino ai giorni nostri. Ogni volta che viene avviato un debugger, viene installato un gestore di interruzioni in modo INT 3tale che quando viene eseguito quel codice operativo verrà attivato il debugger. In genere mette in pausa la programmazione in esecuzione e mostra un prompt interattivo.

Normalmente, il INTcodice operativo x86 è di due byte: 0xCDseguito dal numero di interruzione desiderato compreso tra 0 e 255. Ora anche se si potrebbe emettere 0xCD 0x03per INT 3, Intel ha deciso di aggiungere una speciale version-- 0xCCsenza ulteriore byte - perché un codice operativo deve essere un solo byte in modo da funzionare come un affidabile 'di riempimento byte' per la memoria inutilizzata.

Il punto qui è consentire un recupero corretto se il processore salta erroneamente nella memoria che non contiene alcuna istruzione prevista . Le istruzioni multi-byte non sono adatte a questo scopo poiché un salto errato potrebbe atterrare a qualsiasi possibile offset di byte in cui dovrebbe continuare con un flusso di istruzioni correttamente formato.

Ovviamente, i codici operativi a un byte funzionano in modo banale per questo, ma ci possono anche essere eccezioni bizzarre: ad esempio, considerando la sequenza di riempimento 0xCDCDCDCD(menzionata anche in questa pagina), possiamo vedere che è abbastanza affidabile poiché non importa dove il puntatore dell'istruzione atterra ( eccetto forse l'ultimo byte riempito), la CPU può riprendere l'esecuzione di un'istruzione x86 a due byte valida CD CD, in questo caso per la generazione dell'interrupt software 205 (0xCD).

Ancora più strano, mentre CD CC CD CCè interpretabile al 100% - dando una INT 3o INT 204- la sequenza CC CD CC CDè meno affidabile, solo il 75% come mostrato, ma generalmente il 99,99% quando ripetuto come riempitivo di memoria di dimensioni int.

pagina dal manuale contemporaneo del set di istruzioni 8088/8086 che mostra le istruzioni INT
Macro Assembler Reference , 1987


Wow, non avevo realizzato (collegare i due) 0xCC era INT3. Questo ha senso (cioè non per coincidenza). Iniettavo "NOP + INT3" in luoghi in cui ci sono JMP per ispezionare i registri prima che saltasse in alcune occasioni (molto tempo fa). Grazie per questa intuizione, mistero risolto!
HidekiAI

A cosa serviva NOP? Non è sufficiente inserire un singolo 0xCCbyte con il ebcomando (inserisci byte)?
Glenn Slayden,

Solo un'abitudine, allora, un po 'di codice avrebbe letto due byte e avrebbe cercato di usarlo come tabella di salto, o in alcuni casi, quando elencherò il codice assembly, aggiungendo NOP, non verrà mostrato come' ??? ' o qualcosa (più leggibile) durante lo smontaggio; tutto sommato, per molteplici ragioni, è diventata solo un'abitudine iniettare un NOP prima o dopo il BRK; oh, in alcuni casi, alcune applicazioni potrebbero cercare di fare checksum del blocco di indirizzi, quindi mi piacerebbe bilanciare il JMP $ XYZW con INT3 + [some-hex] ghigno
HidekiAI
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.