0

pset4 recover.c is driving me nuts! My code did recover 50 jpg images with correct names and also the file sizes seemed to make sense, however I couldn't open them (Invalid or Unsupported Image Format). When I checked with xxd, I found out, that all my jpg files started with 00d8ffe instead of ffd8ffe (even though my If-condition checked for ffd8ffe#!).

I couldn't come up with a solution, but with a somewhat weird workaround. I introduced the line

    temp[0] = 0xff;

to just overwrite the first byte of my jpgs with 0xff and it works fine! I can open all 50 jpg files and they look good to me. However, check50 doesn't agree and claims, that middle files and the last file are not correctly recovered.

So here's my code with the workaround. Any hints as to why I get 0x00 as first byte or why check50 doesn't accept my workaround are appreciated.

Thanks in advance, Karin

int main(int argc, char* argv[])
{
    // check for correct usage
    if (argc != 1)
    {
        printf("Correct usage: %s\n", argv[1]);
        return 1;
    }

    // open input file
    FILE* infile = fopen("card.raw", "r");
    if (infile == NULL)
    {
        printf("Something went wrong. Couldn't open file.\n");
        return 2;
    }

    // read input file block by block
    int jpg_count = 0;
    int block_count = 0;
    BYTE temp[BLOCK];
    char title[7];
    FILE* outfile;

    // read blocks from file until eof
    while (fread(&temp, sizeof(BLOCK), 1, infile) == 1)
    {
        block_count = block_count + 1;

        // procedure for blocks with start of jpg file
        if (temp[0] == 0xff && temp[1] == 0xd8 && temp[2] == 0xff && 
            (temp[3] == 0xe0 || temp[3] == 0xe1 || temp[3] == 0xe2 || temp[3] == 0xe3 || temp[3] == 0xe4 || 
            temp[3] == 0xe5 || temp[3] == 0xe6 || temp[3] == 0xe7 || temp[3] == 0xe8 || temp[3] == 0xe9 || temp[3] == 0xea || 
            temp[3] == 0xeb ||  temp[3] == 0xec || temp[3] == 0xed || temp[3] == 0xee || temp[3] == 0xef))
        {
            // create title for output file
            sprintf(title, "%03i.jpg", jpg_count);

            jpg_count = jpg_count + 1;

            if (jpg_count == 1)
            {
                // open first output file
                outfile = fopen(title, "w");
                if (outfile == NULL)
                {
                    printf("Something went wrong. Couldn't create output file %s.\n", title);
                    fclose(infile);
                    return 3;
                }
                temp[0] = 0xff;
                fwrite(&temp, sizeof(BLOCK), 1, outfile);

            }
            else if (jpg_count > 1)
            {
                // close previous output file
                fclose(outfile);

                // open next output file
                outfile = fopen(title, "w");
                if (outfile == NULL)
                {
                    printf("Something went wrong. Couldn't create output file %s.\n", title);
                    return 3;
                }
                temp[0] = 0xff;
                fwrite(&temp, sizeof(BLOCK), 1, outfile);

            }
            else
            {
                printf("Something went wrong.\n");
            }
        }

        // procedure for all other blocks
        else
        {
            if (jpg_count > 0)
            {
                fwrite(&temp, sizeof(BLOCK), 1, outfile);
            }
        }
    }

    // close input file
    fclose(infile);

    // close last output file
    fclose(outfile);

    return 0;
}
1

I can't see the value of the constant BLOCK, but I imagine it's 512. What happens when you do sizeof(512)? Remember that 512 is an integer. It's a different result than what you're expecting. I think you meant just BLOCK instead when you wrote fread(&temp, sizeof(BLOCK), 1, infile) etc

Second thing: char title[7]; Think hard about how many characters you need to store 000.jpg... don't forget the null terminator or you'll be overwriting things.

2
  • 1
    The workaround is a bad solution. It doesn't fix the problem and could lead to other problems down the road. However, it is related to the real problem, which Yuri hit upon. When the code creates the file name and copies it into the char array title[], it's also writing the end of string marker, \0. That EOS marker is overwriting the first byte of the buffer! So, fix the problem and get rid of the workaround. ;-) – Cliff B Oct 11 '16 at 21:58
  • 1
    Thanks a lot guys! Changing to char title[8] and using sizeof(temp) instead of sizeof(BLOCK) fixed the code! – kafe Oct 11 '16 at 22:15

You must log in to answer this question.

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