0

Looking for some help with my recover.c. I have been pouring over the other StackExchange questions regarding recover.c, but can't seem to narrow down my problem.

/**
 * recover.c
 *
 * Computer Science 50
 * Problem Set 4
 *
 * Recovers JPEGs from a forensic image.
 */

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

//use uint8_t BYTE datatype because it is 8-bits.
typedef uint8_t BYTE;

//int argc and argv are not needed because nothing is passed to this         program
int main(void)
{
    //initialize counter variable
    int counter = 0; 

    BYTE buffer[512];

    char filename[8];

    // Open memory card file
    FILE* inptr = fopen("card.raw", "r");
    if(inptr == NULL)
{
    fclose(inptr);
    printf("Could not open card.raw\n");
    return 2;
}


//create pointer in memory to store output files
FILE* outptr = NULL;

while(fread(&buffer, sizeof(BYTE), 512, inptr) != 0)
{
    // Find beginning of JPG
    // 0xff 0xd8 0xff 0xe0 or 0xff 0xd8 0xff 0xe1
    while(buffer[0] == 0xff && buffer[1] == 0xd8 && buffer[2] == 0xff && (buffer[3] == 0xe1 || buffer[3] == 0xe0))
    {

        //close outptr if there is stuff in it (the last pieces of the previous JPEG perhaps)
      if(outptr != NULL)
        {
            fclose(outptr);
        }

        sprintf(filename, "%03i.jpg", counter);

        // Open a new jpg

        outptr = fopen(filename, "w");

        if(outptr == NULL)
        {
            printf("could not create file!\n"); 
            return 1;
        }    

        //incriment counter for next JPEG cycle
        counter++;

        //write contents of buffer to outptr
        fwrite(buffer, sizeof(BYTE), 512, outptr);

    }

    //continue writing contents of buffer to outptr until next JPEG or EOF
    fwrite(&buffer, sizeof(BYTE), 512, outptr);

    //break at card.raw EOF
    if(fread(buffer, sizeof(BYTE), 512, inptr) == 0)
    {
        //break program, entire card.raw file has been processed
        break;
    }


    fclose(outptr);
}

fclose(inptr);
}

I tried to use GDB to narrow down the problem area, but I don't know for sure if I am interpreting the results correctly.

GDB:

(gdb) run
Starting program: /home/jharvard/Dropbox/CS50/pset4/jpg/recover 

Program received signal SIGSEGV, Segmentation fault.
__GI__IO_fwrite (buf=0xbfffee18, size=1, count=512, fp=0x0) at     iofwrite.c:41
41    _IO_acquire_lock (fp);
(gdb) backtrace
#0  __GI__IO_fwrite (buf=0xbfffee18, size=1, count=512, fp=0x0)
at iofwrite.c:41
#1  0x0804885d in main () at recover.c:75    
(gdb) frame 0
#0  __GI__IO_fwrite (buf=0xbfffee18, size=1, count=512, fp=0x0)
at iofwrite.c:41
41    _IO_acquire_lock (fp);
(gdb) frame 1    
#1  0x0804885d in main () at recover.c:75
75          fwrite(&buffer, sizeof(BYTE), 512, outptr); 
(gdb) print buffer
$1 = "bit.ly/8v94Kw ;)", '\000' <repeats 495 times>
(gdb) 

The bit.ly link is just a rick roll, and this post confirmed that this is just the beginning of the file.

So if my 'buffer' contains the correct information (from card.raw), then the problem must be somehow related the output pointer (outptr). I don't know what else to try.

Thanks (in advance) for any help or clues!

1
  • Hi Jimmy. I think you are right, the problem is your output pointer. The segfault shows __GI__IO_fwrite (buf=0xbfffee18, size=1, count=512, fp=0x0) at and I think fp=0x0 is a 0 address. Not good. Since you have a couple of fwrite statements, you might want to set break points so you can inspect values &tc before code is executed. Commented Oct 31, 2015 at 17:25

1 Answer 1

1

For starters, your inner (second) while statement is a serious problem. One of two things will happen. If the test condition in the while loop isn't met, it will skip over the inner while loop, which is what you want. BUT, as soon as you detect the signature bytes, the while loop will start an infinite loop because the buffer never changes inside the loop.

Maybe an IF statement instead of a while loop?

Next, you have effectively two consecutive fread statements - the one at the end of the outer while loop and the one in the while loop definition statement, so you're going to throw away half the data. I don't understand why you have the second read in the if statement at the end anyways. The while loop setup statement does the same exact check for EOF.

There may be other issues, but these are probably the biggest issues you have.

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

You must log in to answer this question.

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