
Strumenti di analisi dell'heap per dlmalloc
libdlmalloc è uno script python progettato per l'uso con GDB che può essere utilizzato per analizzare l'allocatore di Doug Lea, noto anche come dlmalloc. Supporta attualmente le versioni 2.8.x di dlmalloc. Nota che alcune parti possono essere utilizzate anche indipendentemente da GDB, per esempio per eseguire analisi offline di alcuni segmenti di memoria heap catturati.
libdlmalloc è stato ispirato da altri script python per GDB utilizzati per l'analisi degli heap come libtalloc, unmask_jemalloc e libheap. Alcune funzionalità di base sono quasi identiche a quelle di questi progetti.
libdlmalloc è stato testato principalmente su dispositivi Cisco ASA a 32 e 64 bit che utilizzano dlmalloc 2.8.3. Dovrebbe funzionare con altre versioni 2.8.x, tuttavia, a causa di differenze significative, non funzionerà con release precedenti, come <= 2.7.x.
Se testi con successo libdlmalloc su una specifica release 2.8.x o su un dispositivo specifico, per favore informa gli autori e aggiorneremo i documenti.
Lo script richiede solo una versione relativamente moderna di GDB con supporto python3. Abbiamo testato principalmente su python3, quindi ci aspettiamo che su python2.7 al momento possa rompersi.
Se vuoi usare i comandi gdb puoi usare:``` (gdb) source libdlmalloc_28x.py
La maggior parte della logica principale è suddivisa nella classe `dl_helper`, che consente
di importare direttamente libdlmalloc e accedere a determinate strutture importanti
al di fuori di una sessione GDB. Questo è utile se si desidera analizzare snapshot
di chunk/heap offline.
# Utilizzo
Gran parte della funzionalità è modellata sull'approccio di unmask_jemalloc e
libtalloc, dove viene fornito un comando GDB separato. Tuttavia, utilizziamo anche un
buon numero di opzioni.
Per vedere un elenco completo dei comandi attualmente supportati, puoi usare il
comando `dlhelp`:
## dlhelp
Questa è la funzione principale per visualizzare i comandi disponibili. Ciascuno dei comandi
supporta l'opzione `-h` che consente di ottenere istruzioni di utilizzo più dettagliate.```
(gdb) dlhelp
[libdlmalloc] dlmalloc commands for gdb
[libdlmalloc] dlchunk : show one or more chunks metadata and contents
[libdlmalloc] dlmstate : print mstate structure information. caches address after first use
[libdlmalloc] dlcallback : register a callback or query/modify callback status
[libdlmalloc] dlhelp : this help message
[libdlmalloc] NOTE: Pass -h to any of these commands for more extensive usage. Eg: dlchunk -h
dlchunk può fornirti un riepilogo di un chunk, o informazioni più
dettagliate su ogni campo. Puoi anche usarlo per elencare informazioni su
più chunk, cercare chunk, ecc. L'utilizzo di dlchunk è mostrato di seguito:```
(gdb) dlchunk -h
[libdlmalloc] usage: dlchunk [-v] [-f] [-x] [-c ]
[libdlmalloc] a dlmalloc chunk header
[libdlmalloc] -v use verbose output (multiples for more verbosity)
[libdlmalloc] -f use explicitly, rather than be smart
[libdlmalloc] -x hexdump the chunk contents
[libdlmalloc] -m max bytes to dump with -x
[libdlmalloc] -c number of chunks to print
[libdlmalloc] -s search pattern when print chunks
[libdlmalloc] --depth depth to search inside chunk
[libdlmalloc] -d debug and force printing stuff
[libdlmalloc] Flag legend: C=CINUSE, P=PINUSE
L'output di base si presenta così:```
(gdb) dlchunk 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP
Come puoi vedere, vuoi dargli l'indirizzo dei metadati dlmalloc
stessi. Per ottenere un output più dettagliato puoi usare -v.```
(gdb) dlchunk -v 0xacff59d0
struct malloc_chunk @ 0xacff59d0 {
prev_foot = 0x8140d4d0
size = 0xf8 (CINUSE|PINUSE)
Puoi anche elencare più chunk adiacenti utilizzando l'opzione `-c <count>`.```
(gdb) dlchunk -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP
0xacff5ac8 M sz:0x00270 fl:CP
(gdb) dlchunk -v -c 2 0xacff59d0
struct malloc_chunk @ 0xacff59d0 {
prev_foot = 0x8140d4d0
size = 0xf8 (CINUSE|PINUSE)
--
struct malloc_chunk @ 0xacff5ac8 {
prev_foot = 0x8140d4d0
size = 0x270 (CINUSE|PINUSE)
-x e controllare quanti byte vuoi stampare con -m.```
(gdb) dlchunk -v -x -m 16 -c 2 0xacff59d0
struct malloc_chunk @ 0xacff59d0 {
prev_foot = 0x8140d4d0
size = 0xf8 (CINUSE|PINUSE)
0x10 bytes of chunk data:
0xacff59d8: 0xa11c0123 0x000000cc 0x00000000 0x00000000struct malloc_chunk @ 0xacff5ac8 { prev_foot = 0x8140d4d0 size = 0x270 (CINUSE|PINUSE) 0x10 bytes of chunk data: 0xacff5ad0: 0xa11c0123 0x00000244 0x00000000 0x00000000
Puoi anche cercare all'interno dei blocchi. Cerchiamo in 2 blocchi il valore `0x00000244`, che come vediamo sopra è presente solo nel secondo blocco.```
(gdb) dlchunk -s 0x00000244 -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP [NO MATCH]
0xacff5ac8 M sz:0x00270 fl:CP [MATCH]
Tutte le corrispondenze all'interno del numero di chunk cercati verranno mostrate. Cerchiamo 0xa11c01123, che abbiamo visto sopra essere presente in entrambi i chunk:```
(gdb) dlchunk -s 0xa11c0123 -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP [MATCH]
0xacff5ac8 M sz:0x00270 fl:CP [MATCH]
## dlmstate