0
/**
 * recover.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 * Recovers JPEGs from a forensic image.
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
typedef uint8_t BYTE;

int main(void)
{
    FILE* file = fopen("card.raw", "r");
    if (file == NULL)
    {
        return 1;
    }

    char title[50];
    BYTE buffer[512];
    int counter = 0;

    while (!feof(file))
    {
        if (counter < 10)
        {

            fread(&buffer, sizeof(buffer), 1, file);
            if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] > 0xDF && buffer[3] < 0xF0)
            {    
                sprintf(title, "00%d.jpg", counter);
                FILE* img = fopen(title, "w");
                if (img == NULL)
                {
                    return 2;
                }     

                fread(&buffer, sizeof(buffer), 1, file);                    
                fwrite(&buffer, sizeof(buffer), 1, img);
                fread(&buffer, sizeof(buffer), 1, file);

                if(!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] > 0xDF && buffer[3] < 0xF0)))
                    {
                        fwrite(&buffer, sizeof(buffer), 1, img);
                        fread(&buffer, sizeof(buffer), 1, file);

                        while(!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] > 0xDF && buffer[3] < 0xF0)))
                        {
                            fwrite(&buffer, sizeof(buffer), 1, img);
                            fread(&buffer, sizeof(buffer), 1, file);
                        }
                        fseek(file, -sizeof(buffer),SEEK_CUR);
                        counter++;
                        fclose(img);
                    }
                else
                {
                    fwrite(&buffer, sizeof(buffer), 1, img);
                    counter++;
                    fclose(img);
                }    
            }
        }

        else if(counter == 50)
        {
            fclose(file);
            return 0;                
        }

        else 
        {

            fread(&buffer, sizeof(buffer), 1, file);
            if(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && buffer[3] > 0xDF && buffer[3] < 0xF0)
            {    
                sprintf(title, "0%d.jpg", counter);
                FILE* img = fopen(title, "w");
                if (img == NULL)
                {
                    return 2;
                }     


                fwrite(&buffer, sizeof(buffer), 1, img);
                fread(&buffer, sizeof(buffer), 1, file);

                if(!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] > 0xDF && buffer[3] < 0xF0)))
                    {
                        fwrite(&buffer, sizeof(buffer), 1, img);
                        fread(&buffer, sizeof(buffer), 1, file);

                        while(!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] > 0xDF && buffer[3] < 0xF0)))
                        {
                            fwrite(&buffer, sizeof(buffer), 1, img);
                            fread(&buffer, sizeof(buffer), 1, file);
                            if(feof(file)) 
                            {
                                break;
                            }
                        }
                        fseek(file, -sizeof(buffer),SEEK_CUR);
                        counter++;
                        fclose(img);
                    }
                else
                {
                    fwrite(&buffer, sizeof(buffer), 1, img);
                    counter++;
                    fclose(img);
                    if(feof(file))
                    {
                        break;
                    }
                }    
            }
        }
    }
    fclose(file);
    return 0;
}

1 Answer 1

1

I won't review all the code for now, just give you a critical information so that maybe you can solve the problem yourself.

It's not my place to teach boolean logic, so you'll have to study it by yourself, but the negation of a == b && c == d ISN'T a != b && c != d

The AND operator changes to OR when negated... so the correct negation would be a != b || c != d or even !(a == b && c == d)

This condition in your code buffer[0] != 0xff && buffer[1] != 0xd8 && buffer[2] != 0xff && (buffer[3] < 0xe0 || buffer[3] > 0xef) is doing that first kind of (incorrect) negation.

You should be using OR there (and anywhere else this pattern repeats).

The negation operator ! would also work, as I've pointed out above.


The second critical mistake is here:

while(!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] < 0xe0 || buffer[3] > 0xef)))
{
    fwrite(&buffer, sizeof(buffer), 1, img);
    len = ftell(file);
    //printf("Total size of file = %d bytes\n", len);
    fread(&buffer, sizeof(buffer), 1, file);
    len = ftell(file);
    //printf("Total size of file = %d bytes\n", len);
}
    fwrite(&buffer, sizeof(buffer), 1, img);

This last fwrite() is writing the first block of the new found jpg to the old jpg that was open.

What you should do here is fseek() back sizeof(buffer) bytes instead of fwrite()

12
  • Is then (!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff) && (buffer[3] < 0xe0 || buffer[3] > 0xef)) correct? The while loop still stops at the same place.
    – Cristian
    Commented Nov 23, 2016 at 18:12
  • The negation with the ! operator would be, for the if condition: if(!(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] > 0xDF && buffer[3] < 0xF0))) Commented Nov 23, 2016 at 18:22
  • That solved it but now I'm getting Process exited with code: 1
    – Cristian
    Commented Nov 23, 2016 at 18:37
  • Or I'm getting a file that's 512.00MB and I'm getting File size limit exceeded.
    – Cristian
    Commented Nov 23, 2016 at 18:47
  • I'm getting the same thing. The second while loop executes a few times, and then, the program stops and I get a 512.00MB jpg file.
    – Cristian
    Commented Nov 23, 2016 at 18:57

You must log in to answer this question.

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