Alright. This is a pretty simple program. The program simply reads a simulated DRM (basically an encrypted plain text file) file that was encrypted using RC4. It then reads a plain text file that contains the exact same plain text that the DRM file would decrypt too.

(This is assuming, however, that the key of the DRM file is long enough so that it creates a key stream long enough such that it has an equal or greater number of bytes than the plain text.

Anyhow. We want to be able to recover the key stream of this .DRM file. To do so, we need to XOR it with the known plain text. This is where we are having issues. We are trying to grab each individual byte of the plain text and then XOR it with the next byte of the cipher text. We then use Strncat to concatenate all of the XORed bytes together and then print them all. For some reason we are not able to print all of the words. Can anyone help us out. I think that the implementation of strncat is the issue.

Thank you in advance.

The relevant text is bolded.

/*
 * getc(f): returns a byte of data from file f (EOF means end of file)
 * putchar(c): displays a byte (char) onto the screen
 * fopen("filename", "r"): opens "filename" for reading
 * fclose(f): closes file f
 */

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

int main(int argc, char **argv)
{
  char K[256][256];
  char temp[2];
  int c, i, j, k, t, N, x;
  FILE *f, *p;

  if(argc!= 3)
     printf("Usage: %s <drm file> <plaintext>\n", argv[0]);

  // drm file
  if((f = fopen(argv[1], "r")) == NULL)
  {
    printf("Error opening %s\n", argv[1]);
    return 1;
  }

  // plain text
  if((p = fopen(argv[2], "r")) == NULL){
     printf("Error opening %s\n", argv[2]);
     return 1;
  }

[B]  k=0;
  while(((c = getc(f)) != EOF) && (t = getc(p)) != EOF){
     K[k][0] = '\0';
     temp[0] = c ^ t & 0xFF;
     temp[1] = '\0';
     strncat(K[k], temp, 1);
     if(t == ' '||  t == '\n')
	k++;
  }
  
  for(j=0; j < k; j++){
     printf("K[%d]: %s\n\n", j, K[j]);
  }[/B]

  fclose(p);
  fclose(f);
}

why bother using strncat() just to concantinate a single character? Seems such a waste of time. And in that loop K[k][0] = '\0'; is always deleting the previous entry in the array.

A much easier, and IMO, better approach to the problem is just keep another counter where the new character should go

k=0;
   int n = 0;
   memset(K, 0, sizeof(K)); // clear the array
  while(((c = getc(f)) != EOF) && (t = getc(p)) != EOF){
     K[k][n++] = c ^ t & 0xFF;
     if(t == ' '||  t == '\n')
     {
	k++;
        n = 0;
     } 

  }

You could also save a lot of memory by making array K an array of pointers or a linked list, then allocating the space needed for each word, so that a word that is only one character doesn't occupy 256 bytes of memory.

strncat is doing exactly what you're telling it to: concatenating your temp string (of one character) onto the K[k] string.

the fact that you've just previously cleared that K[k] string to be empty, has nothing to do with strncat.

This article has been dead for over six months. Start a new discussion instead.