Search code examples
cfileencryptionxor

Error whilst making a simple XOR crypter in c


There are no compile errors just functionality

I was attempting to make a simple XOR crypter in c. I found out that the crypting part is not a problem because when the XOR function is used twice on the same string it returns the the exact string I sent back. The problem I believe is therefore not with the crypting part, I believe that the problem occurs when writing the file.

Function the error is within

int xorFile (char *infile, char *outfile) {
    FILE *in,
         *out;
    long lSize;
    char *buffer;

    in = fopen ( infile , "rb" );
    out = fopen(outfile, "wb");

    if( !in ) perror(infile),exit(1);

    fseek( in , 0L , SEEK_END);
    lSize = ftell( in );
    rewind( in );

    /* allocate memory for entire content */
    buffer = (char*)calloc( 1, lSize+1 );
    if( !buffer ) fclose(in),fputs("memory alloc fails",stderr),exit(1);

    /* copy the file into the buffer */
    if( 1!=fread( buffer , lSize, 1 , in) )
      fclose(in),free(buffer),fputs("entire read fails",stderr),exit(1);

    /* do your work here, buffer is a string contains the whole text */
    int i;
    for(i=0;buffer[i]!='\0';i++) {
        fputc(buffer[i] ^ XOR_KEY,out);
    }
    fclose(in);
    free(buffer);
    fclose(out);
    return 0;

}

What I believe causes the error

int i;
for(i=0;buffer[i]!='\0';i++) {
    fputc(buffer[i] ^ XOR_KEY,out);
}

Full Program

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>

#define XOR_KEY 0x6F

int xorFile (char *infile, char *outfile) {
    FILE *in,
         *out;
    long lSize;
    char *buffer;

    in = fopen ( infile , "rb" );
    out = fopen(outfile, "wb");

    if( !in ) perror("blah.txt"),exit(1);

    fseek( in , 0L , SEEK_END);
    lSize = ftell( in );
    rewind( in );

    /* allocate memory for entire content */
    buffer = (char*)calloc( 1, lSize+1 );
    if( !buffer ) fclose(in),fputs("memory alloc fails",stderr),exit(1);

    /* copy the file into the buffer */
    if( 1!=fread( buffer , lSize, 1 , in) )
      fclose(in),free(buffer),fputs("entire read fails",stderr),exit(1);

    /* do your work here, buffer is a string contains the whole text */
    int i;
    for(i=0;buffer[i]!='\0';i++) {
        fputc(buffer[i] ^ XOR_KEY,out);
    }
    fclose(in);
    free(buffer);
    fclose(out);
    return 0;

}

int main (int argc, char *argv[]) {
    if (argc <= 2) {

      fprintf (stderr, "Usage: %s [IN FILE] [OUT FILE]\n" , argv[0]) ;

      exit (1);
    }

    xorFile (argv[1], argv[2]) ;
}

Tested causes

  • Checked on multiple OS's
  • Checked on different file formats
  • Checked on different privileges
  • Checked on different compilers as well(ran out of things to test)

Additional infomation When I encrypted a copy of the source file and decrypted it, all that remained was #include <std


Solution

  • The problem you're experiencing is caused by your loop exiting prematurely. The following test will stop as soon as it encounters a null byte:

    for(i=0;buffer[i]!='\0';i++)
    

    To encrypt the entire file, this needs to be changed to:

    for(i=0;i<lSize;i++)
    

    This will be a problem not only for non-text files, but also for decrypting, since the encryption process will introduce zero bytes for any characters that match your XOR_KEY. For instance, if your XOR_KEY is 0x69, which is an ascii 'i', your encrypted file will contain a zero byte in place of each 'i'. When decrypting it, it will cut the file off at the first such character, which explains what you've been seeing. This will correct that.