Ir a contenido principal

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. Cierta información de su perfil de developerWorks será mostrada públicamente, pero usted puede editar la información en cualquier momento. Su nombre, apellido (a menos que usted elija ocultarlo) y nombre de usuario acompañarán el contenido que usted publique.

Toda la información enviada es segura.

  • Cerrar [x]

La primera vez que inicia sesión en developerWorks se crea un perfil para usted, teniendo que elegir un nombre para mostrar en el mismo. Este nombre acompañará el contenido que usted publique en developerWorks.

Por favor elija un nombre de 3 - 31 caracteres. Su nombre de usuario debe ser único en la comunidad developerWorks y debe ser distinto a su dirección de email por motivos de privacidad.

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

Toda la información enviada es segura.

  • Cerrar [x]

Construya una aplicación Python para analizar volcados de memoria compartida

Use la herramienta struct para extraer datos de sistema para análisis

Asha Shivalingaiah, Software Engineer, IBM
Asha Shivalingaiah es Software Engineer y trabaja en pruebas en el Australia Development Lab para la Solución de Seguridad de IBM, Tivoli. Desde que se unió al equipo IBM Rational en el 2008, ha trabajado con Rational Rhapsody y con otras herramientas del portafolio Rational para administrar el ciclo de vida de desarrollo de software. Cuenta con bastante experiencia en lenguajes de modelado como UML 2 y SysML, y en el uso de Rational Rhapsody para desarrollo orientado a modelos.

Resumen:  Aprenda cómo analizar volcados de memoria compartida legibles por máquinas en una plataforma Linux y extraiga su formato de datos esperado usando Python y la herramienta struct . En este artículo primero verá cómo determinar el formato de los datos mediante la lectura del formato de archivo binario del archivo de volcado; usted necesita esto para poder analizar, extraer y analizar los datos. Luego, verá cómo analizar el archivo con base en el formato y luego a hacer que los resultados coincidan con el formato esperado para producir un resultado de validación.

Actualización: En la sección Descargas , encontrará una aplicación Pyhton operacional y un archivo de volcado que puede utilizar tal como está o que puede modificar de acuerdo a sus necesidades. Hemos cambiado el nombre del archivo de volcado a lo largo de este artículo para que coincida con el nombre usado en la descarga. -Ed.

Fecha:  18-07-2011 (Publicado el: 18-07-2011)
Nivel:  Intermediaria Creado originalmente en:  ingles
Actividad:  1199 vistas
Comentario:  


Los volcados de memoria revelan un estado de memoria en funcionamiento en un punto específico en operación. Son una herramienta importante en la administración de sistemas porque proporcionan evidencia "forense" sobre las condiciones del sistema.

Antes de comenzar

Para las instrucciones, muestras de código y descarga de código (vea Descargas, más adelante) en este artículo, utilicé Python versión 2.4, que usted puede descargar del sitio Python (vea Recursos a continuación). Es posible que usted obtenga resultados diferentes con otras versiones.

Antes de comenzar, asegúrese de estar familiarizado(a) con lo siguiente:

  • La implementación /dev/shm de memoria compartida tradicional
  • La visualización manual de volcados de datos de memoria compartida en un sistema Linux
  • Ciertas dependencias (conceptos de apertura, lectura, escritura y cierre de archivos Linux; el uso del descriptor de archivos y los modos en que se puede abrir el archivo; los conceptos básicos de la estructura Python)
  • GNU/Linux, en general

Entendiendo los volcados de memoria compartida en Linux

/dev/shm es una implementación del concepto de memoria compartida tradicional. Es un medio ampliamente utilizado y aceptado para transferir datos entre programas. En /dev/shm, un programa o daemon crea una porción de memoria a la que otros procesos pueden accesar (a los niveles de permiso relevantes). Este es un método rápido y fácil de compartir datos entre procesos.

Cada programa crea su propio archivo en mis ejemplos, uso el archivo de nombre devmem ubicado en /dev/shm/devmem.

Visualizando manualmente el volcado de memoria compartida en Linux

Usted no puede ver los archivos de memoria compartida (conocidos comúnmente como archivos shm) utilizando la herramienta cat utilizada generalmente para mostrar archivos en Linux, porque estos archivos shm están en formato binario. Estos aparecerán como una porción de caracteres confusos si usted intenta visualizarlos con métodos genéricos de visualización de archivos. Yo utilizo la herramienta hexdump) para leer los archivos mem y visualizarlos en un formato legible; también hay otras herramientas disponibles para este propósito.

Para este artículo, el patrón de uso para hexdump se ve así:

hexdump <optional switches> /dev/shm/devmem for <switches> supported

Consulte Recursos donde hallará un enlace hacia más información sobre hexdump.


Definiendo el escenario

El escenario en el que trabajaremos es un rastreador de red que analiza los paquetes recibidos por el host y almacena los datos en un archivo mem compartido, /dev/shm/devmem. Estos datos contienen información sobre el paquete recibido.

Generalmente el archivo se ve así:

  • El almacenamiento del archivo de memoria es /dev/shm/devmem
  • El formato de archivo devmem contiene:
    • 4 bytes de dirección de fuente para notificar quién lo envió
    • 4 bytes de dirección de destino para notificar hacia quién va
    • 2 bytes de puerto fuente (en otras palabras, el puerto en la fuente que utilizó el paquete)
    • 2 bytes de puerto de destino (de forma similar, el puerto de destino que utilizará el paquete)
    • 2 bytes de protocolo (el protocolo del cual es parte el paquete)
    • 4 bytes de tiempo para indicar la indicación de fecha con la que el paquete fue visto por el fragmento de red
  • 1 registro de longitud = la suma de las especificaciones devmem (esto es, 18 bytes)
  • El tamaño máximo del archivo de memoria es 1KByte, así que puede contener 1024 bytes (1024 / 18 = 56 registros)

Si usted hace hexdump y presenta en pantalla manualmente el archivo en una terminal Linux, este se verá más o menos así:


Listado 1. Mostrando un archivo de volcado

# hexdump /dev/shm/devmem
0000000 0004 0000 0400 0000 fc64 0a00 00fb e000
0000010 14e9 14e9 0011 0000 0000 0000 0000 0000
0000020 0000 0000 0000 0000 0000 0000 0000 0800
0000030 1668 0000 0000 0000 0032 0000 0000 0000
0000040 0000 0000 0001 e000 0000 0000 0002 0000
0000050 0000 0000 0000 0000 0000 0000 0000 0000
0000060 0000 0000 0000 0800 0100 0000 0000 0000
0000070 0008 0000 0000 0000 fc64 0a00 fd64 0a00
0000080 2328 03ea 0006 0000 0000 0000 0000 0000
0000090 0000 0000 0000 0000 0000 0000 0000 0800
00000a0 7700 0001 0000 0000 0040 0000 0000 0000
00000b0 fd64 0a00 fc64 0a00 03ea 2328 0006 0000
00000c0 0000 0000 0000 0000 0000 0000 0000 0000
00000d0 0000 0000 0000 0800 0a00 0000 0000 0000
00000e0 0040 0000 0000 0000 fc64 0a00 fd64 0a00
00000f0 2328 03ec 0006 0000 0000 0000 0000 0000
0000100 0000 0000 0000 0000 0000 0000 0000 0800
0000110 7700 0001 0000 0000 0040 0000 0000 0000

Vamos a ver los pasos necesarios para analizar el archivo.


Analizando el archivo volcado

Los pasos para comprender los datos en un archivo de volcado de memoria (identificar el formato, analizar y leer el archivo) son relativamente simples:

  1. Abra el archivo.
  2. Lea los bytes con un descriptor de archivos.
  3. Convierta los datos a un formato de cadena de caracteres legible cuando sea necesario.
  4. Verifique si el almacenamiento intermedio está intacto o si está truncado o tiene errores.
  5. Desempaquete los datos del almacenamiento intermedio.
  6. Extraiga la información.
  7. Imprima los datos.
  8. Construya un bucle para efectuar los pasos del 1 al 7 en cada registro de un volcado de datos compartidos. (Usted no querría hacerlo manualmente, ¿cierto?)

Vamos a ver el flujo del proceso más detalladamente.

Abra el archivo

Para abrir el archivo de memoria compartida, use la forma general fd = open(fileName, mode). fd es el descriptor del archivo, un apuntador hacia el archivo. Para este ejemplo, use lo siguiente:

  • fileName: /dev/shm/devmem
  • mode: rb (leer sólo en modo binario)

Listado 2. Abriendo un archivo de memoria compartida

fd = open('/dev/shm/devmem ','rb')

Lea los bytes

Para leer los bytes usando el descriptor de archivo obtenido en la función de llamado anterior, utilizo el siguiente código. Este lee el número indicado de bytes del parámetro de archivo que se pasó:


Listado 3. Abriendo un archivo de memoria compartida

def ReadBytes(self, fd, noBytes):
 '''
 Read file and return the number of bytes as specified
 '''
 data = fd.read(noBytes)
 return data

buffer = ReadBytes('/dev/shm/devmem ', 18)
# Pass the file name and pass the number of bytes
# Number of bytes is 18 since in the example scenario each record
#  is of length 18

Aquí, leer los bytes no es suficiente para extraer la información necesaria; retorna un almacenamiento intermedio si se lee la cadena de caracteres. Necesita analizarse y convertirse en un formato de cadena de caracteres comprensible.

Convierta los datos

Los struct de Python pueden usarse para manejar los datos binarios almacenados en los archivos o de conexiones de red, entre otras fuentes. El struct de Python también tiene dos amplias funcionalidades: pack y unpack.

El trabajo de pack es retornar una cadena de caracteres que contiene los valores v1, v2, ... empaquetados, de acuerdo al formato dado. Los argumentos deben coincidir exactamente con los valores requeridos por el formato.

El rol de unpack es desempaquetar la cadena de caracteres (presumiblemente empaquetada por pack(fmt, ...)) de acuerdo al formato dado. El resultado es una tupla incluso si contiene exactamente un elemento. La cadena de caracteres debe contener exactamente la cantidad de datos requeridos por el formato: len(string) debe ser igual a calcsize(fmt).

Formatos aceptables:

  • Formatos de 1-byte:
    • b para caracter firmado
    • B para caracter no firmado
  • Formatos de 2-bytes:
    • h para entero corto
    • H para corto no firmado
  • Formatos de 4-bytes:
    • l para largo
    • L para largo no firmado
  • Formatos de 8-bytes:
    • q para largo largo
    • Q para largo largo no firmad

Para otros formatos soportados para empaquetar y desempaquetar los bytes del almacenamiento intermedio, consulte la literatura Python listada en Recursos.

Verifique el almacenamiento intermedio

Para verificar que el almacenamiento intermedio de 18 bytes que se ha leído esté intacto y que no esté truncado ni tenga errores, puede usar la función calcsize para verificar si el tamaño de bytes todavía es 18 como se espera cuando se lea. Puede usar la función assert de Python para este propósito.


Listado 4. Verificando que el tamaño del almacenamiento intermedio sea correcto

self.assertEqual(len(buffer), struct.calcsize('llllh'))

# 4 l's is 4*4 bytes = 16 bytes and h is 2 bytes so that is 18 bytes
# we could use QQh which is 2*8 + 2 = 18 bytes as well

Desempaquete los datos

Ahora que ha verificado que el almacenamiento intermedio realmente tiene 18 bytes, puede desempaquetar sus datos de este. struct proporciona una función útil, unpack_from , que proporciona el número de bytes, el nombre del almacenamiento intermedio y el desplazamiento en el cual necesita leerse:

struct.unpack_from(fmt, buffer[, offset=0])

Extraiga los detalles

En nuestro escenario, estos son los detalles que deseamos extraer:


Listado 5. Detalles a extraer

sourceAddress = (struct.unpack_from('B', buffer,0),
                     struct.unpack_from('B', buffer,1),
                     struct.unpack_from('B', buffer,2),
                     struct.unpack_from('B', buffer,3))
destinationAddress = (struct.unpack_from('B', buffer,4),
                     struct.unpack_from('B', buffer,5),
                     struct.unpack_from('B', buffer,6),
                     struct.unpack_from('B', buffer,7))
sourcePort = (struct.unpack_from('B', buffer,8),
                     struct.unpack_from('B', buffer,9))
destinationPort = (struct.unpack_from('B', buffer,10),
                     struct.unpack_from('B', buffer,11))
protocolUsed = (struct.unpack_from('B', buffer,12),
                     struct.unpack_from('B', buffer,13))
timeStamp = (struct.unpack_from('B', buffer,14),
                     struct.unpack_from('B', buffer,15),
                     struct.unpack_from('B', buffer,16),
                     struct.unpack_from('B', buffer,17))

Nota: Dependiendo de la plataforma y de si la estructura mem está en formato big endian o little endian, usted podrá necesitar intercambiar el orden en que los bytes se leen.

Imprima el resultado

Ahora que ha desempaquetado los valores del almacenamiento intermedio binario que leyó, puede usar los comandos estándar print para obtener el resultado necesario.


Listado 6. Imprimiendo los detalles

print "sourceAddress =" ,  
      (struct.unpack_from('B', buffer,0),struct.unpack_from('B', buffer,1),
      struct.unpack_from('B', buffer,2),struct.unpack_from('B', buffer,3))
print "destinationAddress = " ,
      (struct.unpack_from('B', buffer,4),struct.unpack_from('B', buffer,5),
      struct.unpack_from('B', buffer,6),struct.unpack_from('B', buffer,7))
print "sourcePort = " , (struct.unpack_from('H',buffer,8))
print "destinationPort = " , (struct.unpack_from('H',buffer,10))
print "protocolUsed = " , (struct.unpack_from('H',buffer,12))
print "timeStamp = " ,  
      (struct.unpack_from('B', buffer,14),struct.unpack_from('B', buffer,15),
      struct.unpack_from('B', buffer,16),struct.unpack_from('B', buffer,17))

El resultado esperado del Listado 6 deberá estar en este formato:


Listado 7. Resultado de la impresión

sourceAddress =  ((192,), (168,), (10,), (102,))
destinationAddress =  ((207,), (168,), (1,), (103,))
sourcePort =  (11299,)
destinationPort =  (11555,)
protocolUsed =  (256,)
timeStamp =  ((1,), (12,), (0,), (1,))

Automatice el proceso para todos los registros

Ahora, para leer e imprimir todos los registros de todo el archivo de memoria compartida, cree un bucle:


Listado 8. Creando un bucle para leer e imprimir todos los registros

for element in range (0,56):
#loop 18 since we know the file size and
#the record length: 1024/18 = 56 records
		
      buffer = ReadBytes('/dev/shm/devmem ', 18)
      self.assertEqual(len(buffer), struct.calcsize('llllh'))
        
      sourceAddress = struct.unpack_from('B', buffer,0),
                  struct.unpack_from('B', buffer,1),
                  struct.unpack_from('B', buffer,2),
                  struct.unpack_from('B', buffer,3))
      destinationAddress = struct.unpack_from('B', buffer,4),
                       struct.unpack_from('B', buffer,5),
                       struct.unpack_from('B', buffer,6),
                       struct.unpack_from('B', buffer,7))
      sourcePort = struct.unpack_from('B', buffer,8),
                 struct.unpack_from('B', buffer,9)
      destinationPort = struct.unpack_from('B', buffer,10),
                    struct.unpack_from('B', buffer,11))
      protocolUsed = ,struct.unpack_from('B', buffer,12),
                  struct.unpack_from('B', buffer,13))
      timeStamp = struct.unpack_from('B', buffer,14),
                struct.unpack_from('B', buffer,15),
                struct.unpack_from('B', buffer,16),
                struct.unpack_from('B', buffer,17))
        
      print "sourceAddress = " ,  
            struct.unpack_from('B', buffer,0),
            struct.unpack_from('B', buffer,1),
            struct.unpack_from('B', buffer,2),
            struct.unpack_from('B', buffer,3))
      print "destinationAddress =  " ,
            struct.unpack_from('B', buffer,4),
            struct.unpack_from('B', buffer,5),
            struct.unpack_from('B', buffer,6),
            struct.unpack_from('B', buffer,7))
      print "sourcePort =  " ,
            struct.unpack_from('H',buffer,8))
      print "destinationPort =  " ,
            struct.unpack_from('H',buffer,10))
      print "protocolUsed =  " ,
            struct.unpack_from('H',buffer,12))
      print "timeStamp = " ,  
            struct.unpack_from('B', buffer,14),
            struct.unpack_from('B', buffer,15),
            struct.unpack_from('B', buffer,16),
            struct.unpack_from('B', buffer,17))

¡Eso es todo lo que se necesita! Hemos analizado un formato conocido de volcado de memoria binaria en Linux, y usamos structs de Python para leer el volcado de datos binarios y los hemos presentado en un formato legible.



Descargar

DescripciónNombretamañoMetodo de descarga
Python app for parsing memory dumpParseBinaryInPython.zip6KBHTTP

Información sobre métodos de descarga


Recursos

Aprender

Obtener los productos y tecnologías

  • Descargue Python del sitio web Python.

  • Evalúe productos de IBM de la forma que mejor se ajuste a usted: Descargue una prueba de producto, ensaye un producto en línea, use un producto en un entorno en nube, o pase algunas horas en el SOA Sandbox aprendiendo a implementar la Arquitectura Orientada a Servicios con eficiencia.

Comentar

  • Participe en la Comunidad My developerWorks. Conéctese con otros usuarios developerWorks mientras explora los blogs, foros, grupos y wikis dirigidos a desarrolladores.

Sobre el autor

Asha Shivalingaiah es Software Engineer y trabaja en pruebas en el Australia Development Lab para la Solución de Seguridad de IBM, Tivoli. Desde que se unió al equipo IBM Rational en el 2008, ha trabajado con Rational Rhapsody y con otras herramientas del portafolio Rational para administrar el ciclo de vida de desarrollo de software. Cuenta con bastante experiencia en lenguajes de modelado como UML 2 y SysML, y en el uso de Rational Rhapsody para desarrollo orientado a modelos.

Ayuda para reportar abusos

Reportar abusos

Gracias. Esta entrada ha sido marcada para la atención de un moderador.


Ayuda para reportar abusos

Reportar abusos

Falló el envío del reporte de abusos. Por favor intente después.


developerWorks: Ingresar


¿Necesita un IBM ID?
¿Olvidó su IBM ID?


¿Olvidó su Password?
Cambie su Password

Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. Cierta información de su perfil será mostrada públicamente, pero usted puede editar la información en cualquier momento. Su nombre, apellido (a menos que usted elija ocultarlo), y nombre de usuario acompañarán el contenido que usted publica.

Elija su nombre de usuario

La primera vez que inicie sesión en developerWorks, se creará un perfil para usted. Cierta información de su perfil de developerWorks será mostrada públicamente, pero usted puede editar la información en cualquier momento. Su nombre, apellido (a menos que usted elija ocultarlo) y nombre de usuario acompañarán el contenido que usted publique.

(Debe ser entre 3 – 31 caracteres.)


Al hacer clic en Enviar, usted está de acuerdo con los términos y condiciones de developerWorks.

 


Califique este artículo

Comentario

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=90
Zone=Linux
ArticleID=732603
ArticleTitle=Construya una aplicación Python para analizar volcados de memoria compartida
publish-date=07182011
author1-email=ashashiv@au1.ibm.com
author1-email-cc=

Etiquétalo Etiquetas

Help
Utilice el campo de búsqueda para encontrar todo tipo de contenido en My developerWorks con esa etiqueta.

Utilice el deslizador para controlar cuántas etiquetas deben mostrarse.

Las etiquetas populares muestran las etiquetas más difundidas en esta zona particular de contenido (por ejemplo: Java, Linux, WebSphere).

Mis Etiquetas muestra sus etiquetas en esta zona particular de contenido (por ejemplo: Java, Linux, WebSphere).

Utilice el campo de búsqueda para encontrar todo tipo de contenido en My developerWorks con esa etiqueta. Las etiquetas populares muestran las etiquetas más difundidas en esta zona particular de contenido (por ejemplo: Java, Linux, WebSphere). Mis Etiquetas muestra sus etiquetas en esta zona particular de contenido (por ejemplo: Java, Linux, WebSphere).