Domanda

Ho un codice C app. che stavo costruendo utilizzando MS-VS2005. Ho avuto un buffer di dati di uscita che veniva allocato dinamicamente utilizzando malloc.

Per alcuni casi di test, la dimensione della memoria che veniva malloc'd cadeva breve rispetto alla dimensione uscita effettiva in byte che è stato generato. Che la produzione di maggiori dimensioni è stato scritto nel buffer di dimensioni più ridotte causando buffer overflow. Come risultato di cui il test-run stava arrestando con MSVS del 2005 che mostra una finestra "corruzione Heap ...."

Sapevo che aveva a che fare con un po 'allocazione dinamica della memoria, ma ho preso molto tempo per trovare in realtà la causa principale, in quanto non ho dubbio l'allocazione di memoria perché ero l'allocazione di grandi dimensioni abbastanza necessaria per l'uscita. Ma un caso particolare test è stato generando più uscita di quello che avevo calcolato quindi l'arresto, risultante.

La mia domanda è:

1). Quali strumenti posso utilizzare per rilevare tale tampone memoria dinamica condizioni di sovra-flusso. Possono anche contribuire a rilevare eventuali condizioni di buffer overflow (indipendentemente dal fatto che il buffer / matrice è sul mucchio, pila, area di memoria globale)?

2.) Saranno strumenti di perdita di memoria (come dire Purify) o strumenti di analisi del codice, come niente, klocworks avrebbe aiutato nel caso particolare? Credo che abbiano da eseguire strumenti di analisi in tempo.

Grazie.

-AD.

È stato utile?

Soluzione

Una soluzione, che ho incontrato nel scrittura di un solido codice , è quello di "avvolgere" il malloc() API con codice diagnostico.

In primo luogo, il malloc() diagnostica provvede ad allocare byte aggiuntivi per una sentinella finale. Ad esempio, un ulteriore quattro byte successivi alla memoria allocata sono riservati e contengono i caratteri 'AMMENDA'.

In seguito, quando il puntatore da malloc() viene passato a free(), una versione diagnostica corrispondente free() si chiama. Prima di chiamare l'implementazione standard di free() e abbandonare la memoria, la sentinella trascinamento viene verificata; dovrebbe essere modificato. Se la sentinella viene modificata, quindi il puntatore del blocco è stato abusato a un certo punto successivo di essere rimpatriato dal malloc() diagnostica.

Ci sono vantaggi di utilizzare una pagina carter di protezione memoria anziché un modello sentinella per rilevare buffer overflow. In particolare, con un metodo basato su modelli, l'accesso alla memoria illegale viene rilevata solo dopo il fatto. Solo scritture illegali vengono rilevati con il metodo del modello sentinella. Il metodo di protezione della memoria cattura sia legge illegale e scrive, ed essi vengono rilevati immediatamente quando si verificano.

funzioni contenitore diagnostica per malloc() possono affrontare anche altri usi impropri malloc(), come più chiamate a free() per lo stesso blocco di memoria. Inoltre, realloc() può essere modificato per spostare sempre blocchi quando eseguito in un ambiente di debug, per testare i chiamanti realloc().

In particolare, gli involucri diagnostici possono registrare tutti i blocchi allocati e liberati, e segnalare le perdite di memoria quando il programma termina. perdite di memoria sono blocchi che sono assegnati da non liberati durante l'esecuzione del programma.

Quando avvolgendo l'API malloc(), si deve avvolgere tutti i relativi funzioni, tra cui calloc(), realloc(), e strdup().

Il modo tipico di avvolgere queste funzioni è tramite macro del preprocessore:

#define malloc(s)   diagnostic_malloc(s, __FILE__, __LINE__)
/* etc.... */

Se sorge la necessità di codificare una chiamata alla implementazione standard (per esempio, il blocco allocato verrà passato ad un terzo, biblioteca solo binario che prevede di liberare il blocco con l'attuazione free() standard, la funzione originale i nomi sono accessibili piuttosto che la macro preprocessore utilizzando (malloc)(s) -. che è, posto tra parentesi il nome della funzione

Altri suggerimenti

Qualcosa si può provare è allocare abbastanza pagine + 1 utilizzando VirtualAlloc, usano VirtualProtect con PAGE_READONLY | bandiere PAGE_GUARD l'ultima pagina, quindi allineare l'allocazione sospetta modo che l'estremità dell'oggetto è vicino all'inizio della pagina protetta. Se tutto va bene si dovrebbe ottenere una violazione di accesso quando la pagina di guardia si accede. Aiuta se si conosce circa che l'allocazione viene sovrascritto. In caso contrario, richiede ignorando tutte le allocazioni che possono richiedere un sacco di memoria aggiuntiva (almeno 2 pagine per l'assegnazione). Una variante di questa tecnica che sto presente battesimo come "guardia pagina statistico" è allocare solo casualmente memoria per una percentuale relativamente piccola di allocazioni in tal modo di evitare grandi sovradimensionato per piccoli oggetti. Nel corso di un gran numero di esecuzione viene eseguito si dovrebbe essere in grado di colpire l'errore. Il generatore di numeri casuali dovrebbe essere testa di serie fuori qualcosa come il tempo in questo caso. Allo stesso modo è possibile allocare la pagina di guardia di fronte all'oggetto se si sospetta una sovrascrittura ad un indirizzo più basso (non può fare entrambe le cose allo stesso tempo, ma possibile mescolare in modo casuale su pure).

Un aggiornamento: si scopre il Gflags.exe (usato per essere Pageheap.exe) Microsoft utilità supporta già "guardia pagina statistico" così ho reinventato la ruota :) Tutto quello che dovete fare è eseguire Gflags.exe / p / abilitare [/ random 0-100] YourApplication.exe ed eseguire la vostra applicazione. Se si utilizza un mucchio personalizzato o guardie personalizzati sulle allocazioni di heap allora si può semplicemente passare ad usare HeapAlloc almeno per la cattura di insetti e poi tornare indietro. Gflags.exe è una parte del pacchetto Strumenti di supporto e può essere scaricato dall'Area download Microsoft, basta fare una ricerca lì.

PC-Lint può prendere alcune forme di nuovi problemi di dimensione malloc /, ma non sono sicuro se avrebbe trovato la tua.

VS2005 ha buona buffer overflow controllando oggetti stack in modalità debug (corre alla fine della funzione). E lo fa il controllo periodico del mucchio.

Per quanto riguarda lo aiutare a rintracciare dove si sono verificati i problemi, questo è dove io tendo a iniziare a utilizzare macro per eseguire il dump di tutte le allocazioni per abbinare contro la memoria corrotta in seguito (quando è rilevato).

processo doloroso, quindi sono desiderosi di imparare modi migliori anche.

Consideriamo il nostro memoria Controllo di sicurezza . Penso che sarà catturare tutti gli errori che descrivi. Sì, è il controllo di runtime di tutti accesso, con qualche notevole sovraccarico (non così male come valgrind pensiamo) con il beneficio di diagnosticare la prima azione programma che è errorneous.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top