
Herramientas de análisis de heap para dlmalloc
libdlmalloc es un script de python diseñado para su uso con GDB que puede utilizarse para analizar el asignador de Doug Lea, también conocido como dlmalloc. Actualmente soporta versiones 2.8.x de dlmalloc. Ten en cuenta que algunas partes también pueden usarse de forma independiente de GDB, por ejemplo para realizar análisis sin conexión de alguna memoria de heap capturada.
libdlmalloc se inspiró en otros scripts de python para GDB dedicados al análisis de heaps como libtalloc, unmask_jemalloc y libheap. Parte de la funcionalidad básica es casi idéntica a la de estos proyectos.
libdlmalloc ha sido probado predominantemente en dispositivos Cisco ASA de 32 y 64 bits que usan dlmalloc 2.8.3. Debería funcionar con otras versiones 2.8.x, sin embargo, debido a diferencias significativas, no funcionará en versiones anteriores, como <= 2.7.x.
Si pruebas libdlmalloc con éxito en alguna versión 2.8.x específica o en algún dispositivo concreto, por favor informa a los autores y actualizaremos los documentos.
El script solo requiere una versión relativamente moderna de GDB con soporte para python3. Lo hemos probado principalmente en python3, por lo que esperamos que falle en python2.7 por ahora.
Si quieres usar los comandos de gdb puedes usar:``` (gdb) source libdlmalloc_28x.py
Una gran parte de la lógica central está dividida en la clase `dl_helper`, que permite importar directamente libdlmalloc y acceder a ciertas estructuras importantes fuera de una sesión de GDB. Esto es útil si quieres analizar instantáneas de chunks/heap sin conexión.
# Uso
La mayor parte de la funcionalidad está modelada según el enfoque de unmask_jemalloc y libtalloc, donde se proporciona un comando GDB separado. Aunque también usamos un buen número de opciones.
Para ver una lista completa de los comandos actualmente soportados, puedes usar el comando `dlhelp`:
## dlhelp
Esta es la función principal para ver los comandos disponibles. Cada uno de los comandos admite la opción `-h`, que te permite obtener instrucciones de uso más detalladas.```
(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 puede proporcionarte un resumen de un fragmento, o información
más detallada de cada campo. También puedes usarlo para listar información sobre
múltiples fragmentos, buscar fragmentos, etc. El uso de dlchunk se puede ver a continuación:```
(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
La salida básica se ve así:```
(gdb) dlchunk 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP
Como puedes ver, quieres darle la dirección de los metadatos reales de dlmalloc. Para obtener una salida más detallada puedes usar -v.```
(gdb) dlchunk -v 0xacff59d0
struct malloc_chunk @ 0xacff59d0 {
prev_foot = 0x8140d4d0
size = 0xf8 (CINUSE|PINUSE)
También puedes listar múltiples fragmentos adyacentes usando la opción `-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 y controlar cuántos bytes
quieres volcar 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
También puedes buscar dentro de los chunks. Busquemos en 2 chunks el valor `0x00000244`, que como vemos arriba solo está en el segundo chunk.```
(gdb) dlchunk -s 0x00000244 -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP [NO MATCH]
0xacff5ac8 M sz:0x00270 fl:CP [MATCH]
Se mostrarán todas las coincidencias dentro de los fragmentos buscados. Busquemos 0xa11c01123 que, como vimos antes, está presente en ambos fragmentos:```
(gdb) dlchunk -s 0xa11c0123 -c 2 0xacff59d0
0xacff59d0 M sz:0x000f8 fl:CP [MATCH]
0xacff5ac8 M sz:0x00270 fl:CP [MATCH]
## dlmstate