¿Cuál es el formato de los registros de Android?

8

Estoy tratando de recopilar datos sobre mi teléfono analizando los archivos de registro /dev/log. Estoy mirando específicamente /dev/log/main. Siempre pensé que cualquier formato de registro sensato sería texto sin formato, sin embargo, estos archivos parecen ser binarios o en algún conjunto de caracteres que ni yo ni mis editores de texto de Linux podemos identificar.

Cual es el formato

Aquí hay un par de capturas de pantalla:

  • Primero, aquí hay un fragmento del registro tal como lo interpreta vim(se ^@refiere al byte nulo; no estoy seguro acerca de las otras secuencias de control de color): empuje

  • A continuación, así es como se ve el registro en un editor hexadecimal: editor hexadecimal

Estoy usando un Galaxy Nexus con Jelly Bean. Los registros se recopilaron usando root y un emulador de terminal, ya que aLogcat no parece usar root y, por lo tanto, no puede acceder a toda la información de registro.

Scott Cesantía
fuente

Respuestas:

6

Si quieres información sensata, te recomiendo comandos sensatos :) (sin ofender, solo bromeo). Entonces la pregunta debería leer:

¿Cómo obtener información de registro de un dispositivo Android?

Y ahora estamos en el mejor lado. Existen múltiples enfoques que pueden usarse:

  • utilizar aplicaciones para mostrar información de registro (codificada por color)
  • utilizar ADB (parte del SDK de Android) para extraer de forma remota la misma información
  • use ssh desde el control remoto (o una aplicación de terminal local) para obtener la información directamente desde el dispositivo

Para manejar completamente este tema, se necesita más que esta simple respuesta (si está interesado, por ejemplo, puede encontrar información más detallada en muchos sitios web, o en el libro de Andrew Hoog Android Forensics: Investigación, Análisis y Seguridad Móvil para Google Android , que obtuve el honor para traducir al alemán Probablemente también hay muchas otras fuentes.

Así que solo daré algunos ejemplos aquí para comenzar:

Utilizando aplicaciones

La aplicación probablemente más conocida en este contexto es aLogcat , disponible de forma gratuita en la tienda de juegos (y el desarrollador aceptará con gusto su donación para la otra variante de la misma aplicación). Encontrarás una captura de pantalla debajo de 1 . La aplicación le permite filtrar los registros, iniciar / detener la grabación de mensajes de registro e incluso almacenar los fragmentos grabados en su tarjeta SD, por supuesto, en texto plano, como lo solicitó.

Otra aplicación en esta sección es Log Collector , que simplemente intenta tomar todo el registro disponible y enviarlo a través del menú compartido 2 .

aLogCat Log Collector

El puente de depuración de Android (ADB)

El Kit de desarrollo de software de Android (SDK) incluye el adbcomando para diversas tareas. Entre muchos otros, ofrece adb shellejecutar comandos en el dispositivo. Con esto, también puede recopilar la información de registro deseada: solo prefija los comandos a continuación con adb shell.

Símbolo del sistema en el dispositivo

Usando una aplicación de terminal (por ejemplo, Android Terminal Emulator o Terminal IDE ) puede acceder a los registros directamente en el símbolo del sistema, localmente en su dispositivo. Un poco más cómodo, esto se puede hacer ejecutando un servidor ssh (por ejemplo, DroidSSHd o DropBear SSH Server ) en su dispositivo, y acceder a él desde su computadora. De esta manera, puede trabajar en una pantalla grande, mientras investiga sus registros.

Comandos para acceder a su información de registro

Hay muchos comandos poderosos que puede usar para acceder a su información de registro desde la línea de comandos, y solo daré algunos ejemplos aquí.

dmesg

El dmesgcomando extrae el registro del núcleo:

$ dmesg
<6>[82839.126586] PM: Syncing filesystems ... done.
<7>[82839.189056] PM: Preparing system for mem sleep
<4>[82839.189361] Freezing user space processes ... (elapsed 0.05 seconds) done.
<4>[82839.240661] Freezing remaining freezable tasks ... (elapsed 0.00 seconds) done.
<7>[82839.242279] PM: Entering mem sleep
<4>[82839.242889] Suspending console(s) (use no_console_suspend to debug)
<7>[82839.252410] vfp_pm_save_context: saving vfp state
<6>[82839.252716] PM: Resume timer in 26 secs (864747 ticks at 32768 ticks/sec.)
<6>[82842.091369] Successfully put all powerdomains to target state
<6>[82842.092468] wakeup wake lock: wifi_wake

logcat

Con logcat, puede acceder a mucha información de registro, pero la mayoría de las veces, esto requerirá root. Tiene algunos parámetros para filtrar la información, por ejemplo, seleccionando el búfer de registro para leer -b. Lea la información proporcionada en la página de desarrolladores en logcat para obtener más detalles. Para darle dos ejemplos: logcat -b eventsenumeraría eventos o logcat -b radioinformación sobre el módulo de radio de su dispositivo.

dumpsys y dumpstate

Los dos comandos dumpsysy le dumpstatedan información detallada del sistema:

$ dumpsys
Currently running services:
    LocationProxyService
    SurfaceFlinger
    accessibility
    account
    activity
<snip>
DUMP OF SERVICE account:
Accounts: 1
    Account {[email protected], type=com.google}
<snip>
DUMP OF SERVICE alarm:

$ dumpstate
========================================================
== dumpstate: 2012-08-18 23:39:53
========================================================
Build: Gingerbread GWK74 - CyanogenMilestone2
Bootloader: 0x0000
Radio: unknown
<snip>
------ MEMORY INFO (/proc/meminfo) ------
MemTotal: 487344 kB
MemFree:   10436 kB
Buffers:   14136 kB
Cached:    145460 kB
<snip>

informe de error

Y si eres demasiado vago para recordarlos a todos, simplemente usa el bugreportcomando, que llama a todo lo anterior y lo agrupa para un buen informe de error al desarrollador ...

Por supuesto, puede redirigir la salida de todos esos comandos a un archivo para copiarla en su computadora, y en la mayoría de los casos debe hacerlo, ya que su búfer de pantalla sería demasiado pequeño para manejarlo todo: bugreport > /mnt/sdcard/bugreport.txtsería un ejemplo para esa parte.

Izzy
fuente
$ dmesgo dmsg? Debe haber un error tipográfico en uno de estos :)
jadkik94
@ jadkik94 ese es mi favorito para verificar si alguien se da cuenta ... No, olvide la segunda parte, y gracias por notarlo :) Corregido.
Izzy
Siempre olvido cuál es el correcto :) y siempre
soy
3
Todos saludan a bash-auto-complete :) Además: copié y pegué los ejemplos de mi libro, donde los copié y pegué de un ejemplo de la vida real, así que supe cuál tenía que ser la versión correcta. ..
Izzy
2
El cambio tuvo que ver con un nuevo permiso requerido para leer registros de otras aplicaciones. Actualmente aLogcat solo puede leer sus propios registros. Para que pueda leer registros de otras aplicaciones, debe otorgarle manualmente estos nuevos permisos de la siguiente manera:adb shell pm grant com.nolanlawson.logcat android.permission.READ_LOGS
Chahk
4

Para los desarrolladores (u otras partes interesadas) que necesitan analizar este archivo sin procesar, aquí hay algunos recursos:

El formato real del formato de registro se detalla en:

Una copia de las partes relevantes, ligeramente anotada y reordenada para su conveniencia:

#define LOGGER_ENTRY_MAX_LEN (5*1024)

struct log_msg {
    union {
        /* Maximum size of entry: 5121 bytes */
        unsigned char buf[LOGGER_ENTRY_MAX_LEN + 1];

        struct logger_entry_v3 entry;
        struct logger_entry_v3 entry_v3;
        struct logger_entry_v2 entry_v2;
        struct logger_entry entry_v1;
    } __attribute__((aligned(4)));
}
/*
 * The userspace structure for version 1 of the logger_entry ABI.
 * This structure is returned to userspace by the kernel logger
 * driver unless an upgrade to a newer ABI version is requested.
 */
struct logger_entry {
    uint16_t    len;    /* length of the payload */
    uint16_t    __pad;  /* no matter what, we get 2 bytes of padding */
    int32_t     pid;    /* generating process's pid */
    int32_t     tid;    /* generating process's tid */
    int32_t     sec;    /* seconds since Epoch */
    int32_t     nsec;   /* nanoseconds */
    char        msg[0]; /* the entry's payload */
} __attribute__((__packed__));

/*
 * The userspace structure for version 2 of the logger_entry ABI.
 * This structure is returned to userspace if ioctl(LOGGER_SET_VERSION)
 * is called with version==2; or used with the user space log daemon.
 */
struct logger_entry_v2 {
    uint16_t    len;    /* length of the payload */
    uint16_t    hdr_size; /* sizeof(struct logger_entry_v2) */
    int32_t     pid;    /* generating process's pid */
    int32_t     tid;    /* generating process's tid */
    int32_t     sec;    /* seconds since Epoch */
    int32_t     nsec;   /* nanoseconds */
    uint32_t    euid;   /* effective UID of logger */
    char        msg[0]; /* the entry's payload */
} __attribute__((__packed__));

struct logger_entry_v3 {
    uint16_t    len;    /* length of the payload */
    uint16_t    hdr_size; /* sizeof(struct logger_entry_v3) */
    int32_t     pid;    /* generating process's pid */
    int32_t     tid;    /* generating process's tid */
    int32_t     sec;    /* seconds since Epoch */
    int32_t     nsec;   /* nanoseconds */
    uint32_t    lid;    /* log id of the payload */
    char        msg[0]; /* the entry's payload */
} __attribute__((__packed__));

Puede distinguir las versiones de diferencias observando el tercer y cuatro bytes. Aparentemente, el formato también depende de la endianness de su plataforma. Para mensajes v1, __pades igual a 0. Los mensajes v2 (y v3) usan 24 ( 0x18).

Para main, radioy systemlos registros de msgcampo se interpreta como sigue ( fuente ):

  • prioridad: 1 byte
  • etiqueta: 0 o más bytes
  • literal \0como separador
  • mensaje: 0 o más bytes
  • literal \0como terminador

Si este mensaje se trunca, \0puede faltar el final .

eventsSin embargo, para el registro, el msgcampo contiene los siguientes datos binarios:

  • Etiqueta: clave entera de 4 bytes del archivo "/ system / etc / event-log-tags".
  • Mensaje: árbol serializado a partir del nodo raíz. Cada nodo de árbol comienza con un valor de 1 byte de la enumeración AndroidEventLogType:
    • EVENT_TYPE_INT - el valor del nodo es un entero de 4 bytes
    • EVENT_TYPE_LONG: el valor del nodo es un entero de 8 bytes
    • EVENT_TYPE_STRING: el valor del nodo es un entero de 4 bytes length, seguido de los lengthbytes que contienen una cadena codificada en UTF8
    • EVENT_TYPE_LIST: el valor del nodo es un byte único length, seguido de los lengthnodos del árbol, cada uno de ellos AndroidEventLogType.
Lekensteyn
fuente