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

typedef char* string;
typedef uint8_t BYTE;

int main(int argc, char *argv[])
{
if (argc != 2)
{
    printf("Usage: ./recover image\n");
    return 1;
}

if (strcmp(argv[1], "card.raw") != 0)
{
    printf("Usage: ./recover image\n");
    return 2;
}

string infile = argv[1];
char outfile[7];

FILE* inptr = fopen(infile, "r");
if (inptr == NULL)
{
    fprintf(stderr, "Could not open %s.\n", infile);
    return 3;
}

int i = 0;

unsigned char block[512] = {0};
while (!feof(inptr))
{
    fread(block, sizeof(BYTE), 512, inptr);

    if (block[0] == 0xff && block[1] == 0xd8 && block[2] == 0xff && (block[3] & 0xf0) == 0xe0)
    {
        if (i == 0)
        {
            sprintf(outfile, "%03i.jpg", i);

            FILE *outptr = fopen(outfile, "w");
            if (outptr == NULL)
            {
                fclose(inptr);
                fprintf(stderr, "Could not create %s.\n", outfile);
                return 4;
            }
            fwrite(block, sizeof(BYTE), 512, outptr);
            fclose(outptr);

            i++;
        }
        else
        {
            sprintf(outfile, "%03i.jpg", i);

            FILE *outptr = fopen(outfile, "w");
            if (outptr == NULL)
            {
                fclose(inptr);
                fprintf(stderr, "Could not create %s.\n", outfile);
                return 4;
            }
            fwrite(block, sizeof(BYTE), 512, outptr);
            fclose(outptr);

            i++;
        }
    }
    else if (i != 0)
    {
        FILE *outptr = fopen(outfile, "a");
        fwrite(block, sizeof(BYTE), 512, outptr);
        fclose(outptr);
    }
}
return 0;
}

I'm getting the following error even though I'm able to view every single one of the images correctly:

:) recover.c exists.

:) recover.c compiles.

:) handles lack of forensic image

:) recovers 000.jpg correctly

:) recovers middle images correctly

:( recovers 049.jpg correctly

recovered image does not match

2

It's a problem with processing the EOF condition on the input file. The code is structured so that it reads in 512 bytes, copies them out to the output file, and then checks for EOF. In other words, "Ready, Fire, Aim!"

Note that the EOF flag is not set until an attempt is made to read beyond the end of the file. When the last byte in the input file is read, but no further, EOF is not set yet. Only when an attempt is made to read one more byte will the EOF flag be set.

In practical terms, that means the following. This code is reading the last 512 bytes and writing it out to the last file, then attempting to read one more time from the input file. This read actually fails. (See the docs for return codes for fread.) When this happens, the buffer remains unchanged. The dat from the previous read will then be written to the last output file, so the output file now has an extra 512 bytes. The file size doesn't match. Now, the while loop goes back to the top and tests for EOF. At this point, it actually fails and the loop terminates.

You should consider whether there's a way to incorporate the fread call into the while statement.

If this answers your question, please click on the check mark to accept. Let's keep up on forum maintenance. ;-)

| improve this answer | |
  • Thanks a lot that was very helpful! – human-tech Oct 3 at 19:33

You must log in to answer this question.

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