what you don't know can hurt you
Home Files News &[SERVICES_TAB]About Contact Add New

jpegrescue.c

jpegrescue.c
Posted Apr 20, 2004
Authored by Tobin Fricke | Site splorg.org

JPEG Rescue is a small program used to search a formatted/wiped filesystem for JPEG files and extracts them. Designed to work with Compact Flash cards.

tags | tool
systems | unix
SHA-256 | 802d96933d5b0b04de56f8b7429a033f7d15c6374370b066c22ead634e9f1de1

jpegrescue.c

Change Mirror Download
#include <unistd.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <assert.h>

/*

Once upon a time, a Compact Flash card containing a bunch of pictures
(jpeg images) was accidentally formatted. I wanted the pictures back,
so I rescued them.

This is a small program that I wrote to do this. It searches a
filesystem for what appear to be JPEG files, and then it extracts these
JPEG files.

The workings of JpegRescue are described in this journal entry:

https://www.livejournal.com/users/nibot_lab/12304.html

This program is pretty bare-bones at the moment -- you'll have to follow
the directions in the journal entry (linked above) and modify the program
appropriately.

Tobin Fricke

Berkeley, California - April 2004

https://splorg.org/people/tobin/projects/jpegrescue <tobin@splorg.org>

*/


char *pattern = "Exif";
int pattern_len = 4;
int pattern_ofs = 10;

void extract(int src, int offset, int length) {
char filename[13];
static int serial = 0;

sprintf(filename,"%d.jpg",serial++);
printf("\n extracting from offset 0x%x to \"%s\"\n",offset,filename);
char *buffer = (char *)calloc(1, length);
assert(buffer);

int dst = open(filename, O_WRONLY | O_NOCTTY | O_CREAT, S_IRUSR | S_IWUSR);
if (dst == -1) { perror("fopen failed"); exit(0); }
off_t old_spot = lseek(src, 0, SEEK_CUR);

lseek(src, offset, SEEK_SET);
read(src, buffer, length);
write(dst, buffer, length);
close(dst);
lseek(src, old_spot, SEEK_SET);
}

/*
JPEG files are stored using big-endian byte order (eg, "the way God
intended"), so we have to swap the high and low bytes of a word if we're
working on an Intel machine.
*/

void wordswap(unsigned short int *word) {
*word = (*word >> 8) + ((*word & 0xFF) << 8);
}

/*
These are the offests at which I found the string "Exif" in the filesytem.
The actual JPEG files begin 6 bytes before these offsets. I used the
unix command "strings -t x" piped through "grep Exif" to produce these
numbers.
*/

int search(int fd, char *string, int n, int offset, int actually_search, int file_len) {
int i = 0;
char achar;

/* a very primitive pattern finder */

lseek(fd, offset, SEEK_SET);

while (i < n) {
read(fd, &achar, 1);
if (achar == string[i])
i++;
else {
offset = lseek(fd, n - i, SEEK_CUR);
i = 0;
if ((offset >= file_len) || (!actually_search)) return -1;
}
}
return lseek(fd, 0, SEEK_CUR);
}

int main(int argc, char **argv) {

int fd;
int success = 0, failure = 0;

if (argc != 2) {
printf("Jpeg Rescue -- please see https://splorg.org/people/tobin/projects/jpegrescue/ for documentation\n");
printf("Usage: %s filename\n",argv[0]);
exit(1);
}

fd = open(argv[1], O_RDONLY | O_NOCTTY);

if (fd == -1) {
perror("fopen failed");
exit(0);
}

int file_len = lseek(fd, 0, SEEK_END);
printf("The source file contains %d bytes (%d MB)\n",
file_len, file_len / (1024*1024));

unsigned char byte;
unsigned short int word;

assert(sizeof(word) == 2);

int offset = 0; /* Where we start looking */

printf("Searching...\n");

while ((offset = search(fd, pattern, pattern_len, offset, 1, file_len)) != -1) {

printf("Found pattern at offset 0x%x\n", offset);

int ofs_start = lseek(fd, offset - pattern_ofs, SEEK_SET);
int ofs_end = 0;

while(1) {
read(fd, &byte, 1);

if (byte != 0xFF) {
printf(" ** JPEG Marker not found -- Aborting \n");
failure ++;
break;
}

read(fd, &byte, 1);

if (byte == 0xD8) { printf("START OF IMAGE\n"); continue; }
else if(byte == 0xD9) { printf("END OF IMAGE\n"); break; }

read(fd, &word, 2);
wordswap(&word);

printf("Found Marker %02x with %d bytes data -- ",byte, word);
int newpos = lseek(fd, word -2, SEEK_CUR);
printf("advancing to position 0x%x\n",newpos);

if (byte == 0xDA) {
printf("That was START OF SCAN -- scanning for 0xFFD9\n");
while (1) {
read(fd, &word, 2);
ofs_end = lseek(fd,0,SEEK_CUR);
wordswap(&word);
if (word == 0xFFD9) {
printf("Found END OF SCAN at offset 0x%x\n",lseek(fd,-2,SEEK_CUR));
extract(fd,ofs_start,ofs_end - ofs_start + 1);
success ++;
break;
}
}
}
}

}
printf("%d images extracted successfully, %d failures\n",success,failure);
return 0;
}






Login or Register to add favorites

File Archive:

November 2024

  • Su
  • Mo
  • Tu
  • We
  • Th
  • Fr
  • Sa
  • 1
    Nov 1st
    30 Files
  • 2
    Nov 2nd
    0 Files
  • 3
    Nov 3rd
    0 Files
  • 4
    Nov 4th
    12 Files
  • 5
    Nov 5th
    44 Files
  • 6
    Nov 6th
    18 Files
  • 7
    Nov 7th
    9 Files
  • 8
    Nov 8th
    8 Files
  • 9
    Nov 9th
    3 Files
  • 10
    Nov 10th
    0 Files
  • 11
    Nov 11th
    14 Files
  • 12
    Nov 12th
    0 Files
  • 13
    Nov 13th
    0 Files
  • 14
    Nov 14th
    0 Files
  • 15
    Nov 15th
    0 Files
  • 16
    Nov 16th
    0 Files
  • 17
    Nov 17th
    0 Files
  • 18
    Nov 18th
    0 Files
  • 19
    Nov 19th
    0 Files
  • 20
    Nov 20th
    0 Files
  • 21
    Nov 21st
    0 Files
  • 22
    Nov 22nd
    0 Files
  • 23
    Nov 23rd
    0 Files
  • 24
    Nov 24th
    0 Files
  • 25
    Nov 25th
    0 Files
  • 26
    Nov 26th
    0 Files
  • 27
    Nov 27th
    0 Files
  • 28
    Nov 28th
    0 Files
  • 29
    Nov 29th
    0 Files
  • 30
    Nov 30th
    0 Files

Top Authors In Last 30 Days

File Tags

Systems

packet storm

© 2024 Packet Storm. All rights reserved.

Services
Security Services
Hosting By
Rokasec
close