En la entrada anterior, @nicky69es realizó una introducción a la recuperación de datos en SQLite. En esta entrada, hablará de como encontrar datos borrados y sobre los formatos de la cabecera de las BBDD.
DONDE ENCONTRAR DATOS BORRADOS
Freelist. Como mencioné en la introducción, la base de datos sqlite se guarda en el archivo en bloques llamados hojas de un tamaño fijo. Cuando los datos de una hoja se borran de la base de datos, esta pasa a marcarse como disponible y los datos que contiene se sobre-escribirán cuando se necesiten. La primera de las hojas se denomina “página tronco” que contiene las direcciones de otras páginas tronco (si las hubiera) y las direcciones de las hojas marcadas como disponibles a modo de lista.
Celdas en hojas. Cada hoja está compuesta por celdas de tamaño variable que se van insertando desde el final de la hoja hasta el principio. Cuando los datos de una celda son eliminados de la base de datos, esta se marca como disponible en la misma hoja, pero al borrarse una celda no pasa a ser una “freelist”, pasa a ser un bloque de datos disponible “freeblock”. Normalmente la base de datos desfragmenta la hoja, así que podemos encontrar trozos sin sentido. Podemos ver en la cabecera de la hoja las celdas activas y las que están disponibles y por tanto no han sido sobre-escritas aún.
Páginas overflow. Se generan cuando se queda corto el espacio en la celda. Ya sea porque se ha utilizado una celda borrada anteriormente con unos datos superiores al espacio que ocupaba o por la misma falta de espacio en la última celda de la página. Esto genera una hoja del tamaño
definido en la cabecera con el resto del contenido de la celda, o se reutiliza una de las hojas “disponibles”. Comienzan por el grupo de bytes (00 00 00 00).
Espacio no asignado en la hoja. Como las celdas se graban en las hojas desde el final hacia el inicio de la mismas, el espacio no asignado «unallocated” estará al principio de la hoja.
FORMATO DE LA CABECERA DE LA BBDD
Descripción de la cabecera y cuales son las opciones más interesantes para conseguir nuestro objetivo. Los datos están almacenados en Big-endian¹.
- Los primeros 16 bytes de la cabecera son la firma del archivo «SQLite format 3\000”.
- Los bytes del offset 16-17 indican el tamaño de las páginas en bytes.
- Los bytes de los offset 18(write) y 19(read) indican si está disponible la opción WAL (2=si, 1=no), whatsapp=1.
- Los 4 bytes de los offset 24-27 indican el número de veces que ha cambiado el archivo.
- Los 4 bytes de los offset 28-31 indican la cantidad de páginas que hay en el archivo. Si lo multiplicamos por el tamaño (offset 16-17) no dará el tamaño total del archivo.
- Los 4 bytes de los offset 32-35 indican el número de hoja de la primera “página tronco”. Si hubiera más, irían indicados en esta primera su número. [(número-1)*tamaño] nos da el offset.
Si es “cero” no hay páginas tronco. - Los 4 bytes de los offset 36-39 indican la cantidad de “freelist”.
- Los 4 bytes de los offset 56-59 indican la codificación de la BBDD (1=UTF8, 2=UTF16le,
3=UTFbe)
Esta información se puede ver en la consulta de terminal >sqlite3 archivo.sqlite «.dbinfo»
Autor: @nicky69es
Fuentes: sqlite.org; arumeinformatica.es