0

What it has to do: Iterate through each block of 512 bytes in input file. When found JPEG header, assuming that it is start of JPEG write it to a separate file, continue until new header is found, then close the JPEG fileand repeat to the end of the input file. Free all allocated memory and close input file.

What it actually does: Everything written above. It actually recovers all JPEG files (I am able to see and open all of them) and leaks no memory (checked with Valgrind) but still doesn't pass 'check50'.

:) recover.c exists  
:) recover.c compiles  
:) handles lack of forensic image  
:) recovers 000.jpg correctly  
:( recovers middle files correctly  
:( recovers last file correctly  

I've read lots of posts regarding this but still have no clue.

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

int main(int argc, char *argv[])
{
    //ensure proper usage
     if (argc != 2){
        fprintf(stderr, "Usage: ./recover imagefile.raw\n");
        return 1;
    }
    // open input file
    FILE *card = fopen(argv[1], "r");
    if (card == NULL){
        fprintf(stderr, "Could not open %s.\n", argv[1]);
        return 2;
    }
    //create a buffer of 512 bytes
    //pomenat'
    uint8_t *buffer = malloc(sizeof(uint8_t)*512);
    if ( buffer == NULL){
        fprintf(stderr, "Could not create buffer.\n");
        return 3;
    }    
    //temp jpg found counter
    int jpgfnd = 0;    
    // Counter of JPEGs
    int jpg = 0;
    char filename[10];    
    FILE *img = NULL;    
    while( fread(buffer, sizeof(buffer), 1, card) == 1)
    {
        if (buffer[0] == 0xff &&
            buffer[1] == 0xd8 &&
            buffer[2] == 0xff &&
            (buffer[3] & 0xf0) == 0xe0)
        {
            if (jpgfnd == 1){
                //close prev file
                fclose(img);
            }
            //create a new file
            sprintf(filename, "%03i.jpg", jpg);
            img = fopen(filename, "w");
            //write buffer to a new file
            fwrite(buffer, sizeof(buffer), 1, img);
            // change jpeg found value to 1
            jpgfnd = 1;
            //change jpg conter value by 1
            jpg++;
        }
        else if (jpgfnd == 1){
            //write buffer to an opened file
            fwrite(buffer, sizeof(buffer), 1, img);
        }
    }
    // close all opened files
    fclose(img);
    fclose(card);
    // free malloced array
    free(buffer);
    // success
    return 0;
}
1
  • else if (jpgfnd == 1) this only works for the first jpeg because once jpeg is above 1 this condition will no longer be used. change to if (jpgfnd != 0) Mar 17, 2017 at 3:40

1 Answer 1

2

The program is reading (and writing) 8 bytes at a time. while( fread(buffer, sizeof(buffer), 1, card) == 1). buffer is a pointer, sizeof a pointer is 8. This runs the risk of detecting a jpg that is not on a block boundary. check50 does not use the same raw file as supplied in the distro code and exposes this problem.

2
  • Thanks, you are absolutely right. I was using sizeof() function wrong. After I've changed that to 512 check50 passed. Mar 17, 2017 at 15:25
  • Thank you so much! I thought I was going mad... in my case, I had to add the condition, segment_index == 3 && to the start of my if statement: if((latest_dword & 0xF0FFFFFF) == 0xE0FFD8FF) Jun 30, 2017 at 10:14

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .