Com as vantagens óbvias das câmeras digitais, incluindo as dos smartphones, mais e mais pessoas tiram fotos todos os dias, em todos os lugares, fazendo as mais variadas “tripulias”. O que pouca gente sabe é que esses arquivos de fotos podem conter dados um tanto quanto comprometedores, como data, condições em que a foto foi tirada e até mesmo onde você estava!
Se você olhar as propriedades de uma foto em .jpg tirada com uma câmera digital, poderá se surpreender com as informações que estão nela.
No GNU/Linux:
No Windows XP:
Percebeu a marca e modelo da câmera, além da data quando a foto foi tirada? Por alguma razão o Windows não mostrou, mas o Linux sim, então este tipo de informação está em algum lugar no arquivo. Vamos ver…
Eu não lembro de ter visto câmera digital que não salvasse os arquivos no formato JPEG. Por um lado é bom: padronização e compressão, já que o formato tem uma boa compressão e perde pouca qualidade, se bem ajustado.
O formato JPEG, assim como qualquer outro formato de arquivo que se preze, define campos que serão interpretados pelos aplicativos que vão trabalhar com ele. Ou seja, poderia dizer que do primeiro byte de um arquivo .jpg até o enésimo byte, está a informação X. Deste em diante até um outro byte, está a informação Y e assim por diante.
Claro que a imagem em si (leia-se o que é renderizável) ocupa um campo geralmente grande e de tamanho variável. Sem problemas se estudarmos o formato JPEG um pouquinho…
No cabeçalho do formato JPEG, cada campo (chamado de “marker”) é iniciado por um byte 0xff e o próximo byte define que tipo de campo é.
De acordo com a especificação [1], o campo “0xff 0xd8” é o SOI (Start Of Image) e marca o início da imagem. Então se olharmos o conteúdo com um visualizador hexa, podemos observar:
$ hd -n 64 tracking.jpg 00000000 ff d8 ff e1 48 88 45 78 69 66 00 00 4d 4d 00 2a |….H.Exif..MM.*| 00000010 00 00 00 08 00 0a 01 0f 00 02 00 00 00 08 00 00 |…………….| 00000020 00 86 01 10 00 02 00 00 00 0a 00 00 00 8e 01 12 |…………….| 00000030 00 03 00 00 00 01 00 01 00 00 01 1a 00 05 00 00 |…………….|
A documentação prevê campos para abrigar as dimensões da imagem, compressão utililizada, cores etc. Inclusive há um campo para comentários definido por “0xff 0xfe”, de tamanho variável. Vamos procurá-lo? Pode ser que nossa informação esteja lá:
Nada encontrado. O arquivo tem várias informações mas nem consta o campo de comentários previsto na especificação JPEG. Neste caso, vamos dar uma olhada com mais carinho nos bytes:
$ hd -n 512 tracking.jpg 00000000 ff d8 ff e1 48 88 45 78 69 66 00 00 4d 4d 00 2a |….H.Exif..MM.*| 00000010 00 00 00 08 00 0a 01 0f 00 02 00 00 00 08 00 00 |…………….| 00000020 00 86 01 10 00 02 00 00 00 0a 00 00 00 8e 01 12 |…………….| 00000030 00 03 00 00 00 01 00 01 00 00 01 1a 00 05 00 00 |…………….| 00000040 00 01 00 00 00 98 01 1b 00 05 00 00 00 01 00 00 |…………….| 00000050 00 a0 01 28 00 03 00 00 00 01 00 02 00 00 01 32 |…(………..2| 00000060 00 02 00 00 00 32 00 00 00 a8 02 13 00 03 00 00 |…..2……….| 00000070 00 01 00 01 00 00 87 69 00 04 00 00 00 01 00 00 |…….i……..| 00000080 00 da 88 25 00 04 00 00 00 01 00 00 02 56 00 00 |…%………V..| 00000090 02 c4 53 41 4d 53 55 4e 47 00 47 54 2d 49 35 35 |..SAMSUNG.GT-I55| 000000a0 30 30 42 00 00 00 00 48 00 00 00 01 00 00 00 48 |00B….H…….H| 000000b0 00 00 00 01 32 30 31 30 2d 31 31 2d 31 38 20 30 |….2010-11-18 0| 000000c0 30 3a 34 36 3a 32 33 20 00 00 00 00 00 00 00 00 |0:46:23 ……..| 000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |…………….| 000000e0 00 00 00 00 00 00 00 11 82 9a 00 05 00 00 00 01 |…………….| 000000f0 00 00 01 ac 82 9d 00 05 00 00 00 01 00 00 01 b4 |…………….| 00000100 88 22 00 03 00 00 00 01 00 03 00 00 88 27 00 03 |.”………..’..| 00000110 00 00 00 01 00 c8 00 00 90 00 00 02 00 00 00 0f |…………….| 00000120 00 00 01 bc 90 03 00 02 00 00 00 32 00 00 01 cc |………..2….| 00000130 90 04 00 02 00 00 00 32 00 00 01 fe 91 01 00 07 |…….2……..| 00000140 00 00 00 04 01 02 03 00 92 07 00 03 00 00 00 01 |…………….| 00000150 00 02 00 00 92 0a 00 05 00 00 00 01 00 00 02 30 |……………0| 00000160 a0 00 00 07 00 00 00 04 30 31 30 30 a0 01 00 03 |……..0100….| 00000170 00 00 00 01 00 01 00 00 a0 02 00 04 00 00 00 01 |…………….| 00000180 00 00 06 40 a0 03 00 04 00 00 00 01 00 00 04 b0 |…@…………| 00000190 a0 05 00 04 00 00 00 01 00 00 02 38 a4 03 00 03 |………..8….| 000001a0 00 00 00 01 00 00 00 00 a4 06 00 03 00 00 00 01 |…………….| 000001b0 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 08 |…………….| 000001c0 00 00 00 87 00 00 00 32 56 65 72 73 69 6f 6e 20 |…….2Version | 000001d0 32 2e 32 00 00 00 00 00 32 30 31 30 2d 31 31 2d |2.2…..2010-11-| 000001e0 31 38 20 30 30 3a 34 36 3a 32 33 20 00 00 00 00 |18 00:46:23 ….|
Opa, começamos a achar as informações que queremos, mas em qual campo estamos?
Veja que começou o “0xff 0xe1” e até o fim deste dump de 512 bytes não começou outro campo, ou seja, ainda estamos nele. A documentação do formato JPEG diz que os campos “0xff 0xeN”, onde “N” pode variar, representa um campo chamado APPN (no nosso caso, N=1, entao nosso campo é APP1). Este campo é usado para gravar metadados no formato EXIF, usado por vários tipos de arquivo para abrigar informações adicionais.
O objetivo agora é destrinchar o EXIF e ver como ele está estruturado. O primeiro passo é olhar a documentação [2] em busca da especificação de seus campos. O EXIF é usado “dentro” de outros formatos. Não vou comentar sobre a estrutura do EXIF aqui, pois demandaria um longo texto. Por hora, basta otimizarmos procurando um software que seja capaz de ler os metadados EXIF em um JPG, certo?
O software que mais me atendeu foi o jhead [3]. Além de ser livre, é cheio de recursos interessantes, inclusive pode apagar todas as informações EXIF de um arquivo .jpg, a fim de evitar rastros.
$ jhead tracking.jpg File name : tracking.jpg File size : 314085 bytes File date : 2011:03:30 02:13:53 Camera make : SAMSUNG Camera model : GT-I5500B Date/Time : 2010-11-18 00:46:23 Resolution : 1600 x 1200 Focal length : 2.7mm Exposure time: 0.125 s (1/8) Aperture : f/2.7 ISO equiv. : 200 Whitebalance : Auto Metering Mode: center weight Exposure : aperture priority (semi-auto) GPS Latitude : ? 12d 23m 28.937s GPS Longitude: ? 13d 20m 33.702s
Epa! Latitude e longitude? Por que isso não apareceu no Windows, nem no Linux, no ambiente gráfico? Sério que dá pra saber onde eu estou? Sério…
Qualquer pessoa que tiver sua foto (Facebook?) pode pegar essas informações e converter para coordenadas de GPS, existem até conversores na internet. Depois é só usar alguma API de “Reverse Geocoding”, que é a técnica de obter um mapa de um lugar a partir de suas coordenadas GPS.
Moral da história: muito cuidado onde coloca suas fotos. Se quiser um pouquinho menos de exposição, você pode remover todas as informações EXIF com a opção -purejpg do jhead:
$ jhead -purejpg tracking.jpg Modified: tracking.jpg $ jhead tracking.jpg File name : tracking.jpg File size : 295533 bytes File date : 2011:03:30 02:13:53 Resolution : 1600 x 1200
Veja que agora só ficam informações básicas como resolução e data de modificação do arquivo (o mesmo usado pelo SO). É, a vida digital tem um preço…
[1] http://en.wikipedia.org/wiki/JPEG#Syntax_and_structure
[2] http://www.exif.org/Exif2-2.PDF
[3] http://www.sentex.net/~mwandel/jhead/