Click here to Skip to main content
15,892,199 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
C++
#include "Header.h"

// Global Variables
unsigned char gkey[65537];
unsigned char* gptrKey = gkey;			// used for inline assembly routines, need to access this way for Visual Studio
char gPassword[256] = "SECRET";
unsigned char gPasswordHash[32];
unsigned char* gptrPasswordHash = gPasswordHash;	// used for inline assembly routines, need to access this way for Visual Studio
unsigned char gdebug1, gdebug2;

FILE* gfptrIn = NULL;
FILE* gfptrOut = NULL;
FILE* gfptrKey = NULL;
char gInFileName[256];
char gOutFileName[256];
char gKeyFileName[256];
int gOp = 0;			// 1 = encrypt, 2 = decrypt
int gNumRounds = 1;

//////////////////////////////////////////////////////////////////////////////////////////////////
// code to encrypt the data as specified by the project assignment
int encryptData(char* data, int dataLength)
{
	int resulti = 0;

	gdebug1 = 0;					// a couple of global variables that could be used for debugging
	gdebug2 = 0;					// also can have a breakpoint in C code

	// You can not declare any local variables in C, but should use resulti to indicate any errors
	// Set up the stack frame and assign variables in assembly if you need to do so
	// access the parameters BEFORE setting up your own stack frame
	// Also, you cannot use a lot of global variables - work with registers

	__asm {
		// you will need to reference some of these global variables
		// (gptrPasswordHash or gPasswordHash), (gptrKey or gkey), gNumRounds

		// simple example that xors 2nd byte of data with 14th byte in the key file

		mov esi, gptrKey;						// put the ADDRESS of gkey into esi (since *gptrKey = gkey)
		mov esi, gptrPasswordHash				// put ADDRESS of gPasswordHash into esi (since unsigned char *gptrPasswordHash = gPasswordHash)
		xor eax, eax
		mov al, byte ptr[esi]
		shl ax, 8
		xor ecx, ecx
		mov cl, byte ptr[esi + 1]
		add ax, cx

		xor ebx, ebx
		xor ecx, ecx
//		mov al, byte ptr[esi]					// get first byte of password hash
//		mov al, byte ptr[esi + 1]
//		mov al, byte ptr[esi + 2]
//		mov al, byte ptr[esi + 3]
//		mov al, byte ptr[esi + 4]				// get 5th byte of password hash
//		mov al, byte ptr[esi + 5]

		mov ecx, dataLength
		mov edi, data

	LOOP1 :
		mov dl, byte ptr[edi + ebx]
		xor dl, byte ptr[esi + eax]
		mov byte ptr[edi + ebx], dl

		add ebx, 1
		cmp ebx, ecx
		mov ebx, 2
		ja EXIT_END
		jmp LOOP1

	EXIT_END :
		xor ebx, ebx

		mov resulti, ebx
//		mov al, byte ptr[esi + ebx]				// get 3rd byte of password hash
//		mov al, byte ptr[esi + ebx * 2]			// get 5th byte of password hash

//		mov ax, word ptr[esi + ebx * 2]			// gets 5th and 6th bytes of password hash ( gPasswordHash[4] and gPasswordHash[5] ) into ax
//		mov eax, dword ptr[esi + ebx * 2]		// gets 4 bytes, as in:  unsigned int X = *( (unsigned int*) &gPasswordHash[4] );

//		mov al, byte ptr[gkey]
//		mov al, byte ptr[gkey + 1]
//		mov al, byte ptr[gkey + ebx]			// get's 3rd byte of gkey[] data
//		mov al, byte ptr[gkey + ebx + 1]
//		mov al, byte ptr[gkey + ebx + 2]
//		mov al, byte ptr[gkey + ebx + 3]

//		mov al, byte ptr[gptrKey + ebx]			// THIS IS INCORRECT - will add the address of the gptrKey global variable (NOT the value that gptrKey holds)

//		mov al, byte ptr[esi + 0xd];			// access 14th byte in gkey[]: 0, 1, 2 ... d is the 14th byte
															// Put ADDRESS of first data element into edi

//		xor byte ptr[edi + 1], al				// Exclusive-or the 2nd byte of data with the 14th element of the keyfile
												// NOTE: Keyfile[14] = 0x21, that value changes the case of a letter and flips the LSB
												// Capital "B" = 0x42 becomes lowercase "c" since 0x42 xor 0x21 = 0x63
	}

	return resulti;

} // encryptData

// code to read the file to encrypt
int encryptFile(FILE* fptrIn, FILE* fptrOut)
{
	char* buffer;
	unsigned int filesize;

	fseek(fptrIn, 0, SEEK_END);
	filesize = ftell(fptrIn);
	fseek(fptrIn, 0, SEEK_SET);

	if (filesize > 0x1000000)					// 16 MB, file too large
	{
		fprintf(stderr, "Error - Input file to encrypt is too large.\n\n");
		return -1;
	}

	// use the password hash to encrypt
	buffer = (char*)malloc(filesize);
	if (buffer == NULL)
	{
		fprintf(stderr, "Error - Could not allocate %d bytes of memory on the heap.\n\n", filesize);
		return -1;
	}

	fread(buffer, 1, filesize, fptrIn);	// read entire file
	encryptData(buffer, filesize);
	fwrite(buffer, 1, filesize, fptrOut);
	free(buffer);

	return 0;

} // encryptFile



I already have functions to open the input file and output file:

C++
FILE* openInputFile(char* filename)
{
	FILE* fptr;
	long sz;

	fptr = fopen(filename, "rb");
	if (fptr == NULL)
	{
		fprintf(stderr, "\n\nError - Could not open input file %s!\n\n", filename);
		exit(-1);
	}

	fseek(fptr, 0, SEEK_END);
	sz = ftell(fptr);
	fseek(fptr, 0, SEEK_SET);

	if (sz == 0)
	{
		fprintf(stderr, "Error - File size is zero for \"%s\".\n\n", filename);
		fprintf(stderr, "Aborting operation - try again!\n\n");
		fclose(fptr);
		exit(0);
	}

	return fptr;

} // openInputFile

FILE* openOutputFile(char* filename)
{
	FILE* fptr;

	fptr = fopen(filename, "wb+");
	if (fptr == NULL)
	{
		fprintf(stderr, "\n\nError - Could not open output file %s!\n\n", filename);
		exit(-1);
	}
	return fptr;

} // openOutputFile



C++
void usage(char* argv[])	//   cryptor.exe -e -i <input file> –k <keyfile> -p <password> [–r <#rounds>]
{
	printf("\n\nUsage:\n\n");

	printf("To Encrypt:\n");
	printf("%s -e <message_filename> -k <keyfile> -p <password> [-r <#rounds>]\n\n", argv[0]);

	printf("To Decrypt:\n");
	printf("%s -d <message_filename> -k <keyfile> -p <password> [-r <#rounds>]\n\n", argv[0]);

	printf("-e filename		:encrypt the specified file\n");
	printf("-d filename		:decrypt the specified file\n");
	printf("-p password		:the password to be used for encryption [default='password']\n");
	printf("-r <#rounds>		:number of encryption rounds (1 - 3)  [default = 1]\n");
	printf("-o filename		:name of the output file [default='encrypted.txt' or 'decrypted.txt'\n\n");
	printf("The order of the options is irrelevant.\n\n");
	exit(0);
} // usage

void parseCommandLine(int argc, char* argv[])
{
	int cnt;
	char ch;
	bool i_flag, o_flag, k_flag, p_flag, err_flag;

	i_flag = k_flag = false;				// these must be true in order to exit this function
	err_flag = p_flag = o_flag = false;		// these will generate different actions

	cnt = 1;	// skip program name
	while (cnt < argc)
	{
		ch = *argv[cnt];
		if (ch != '-')
		{
			fprintf(stderr, "All options must be preceeded by a dash '-'\n\n");
			usage(argv);
		}

		ch = *(argv[cnt] + 1);
		if (0)
		{
		}

		else if (ch == 'e' || ch == 'E')
		{
			if (i_flag == true || gOp != 0)
			{
				fprintf(stderr, "Error! Already specifed an input file - can't encrypt/decrypt multiple files.\n\n");
				usage(argv);
			}

			i_flag = true;
			cnt++;
			if (cnt >= argc)
			{
				fprintf(stderr, "Error! Must specify a filename after '-e'\n\n");
				usage(argv);
			}

			strncpy(gInFileName, argv[cnt], 256);
			gOp = 1;	// encrypt
		}

		else if (ch == 'd' || ch == 'D')
		{
			if (i_flag == true || gOp != 0)
			{
				fprintf(stderr, "Error! Already specifed an input file - can't decrypt/encrypt multiple files.\n\n");
				usage(argv);
			}

			i_flag = true;
			cnt++;
			if (cnt >= argc)
			{
				fprintf(stderr, "Error! Must specify a filename after '-d'\n\n");
				usage(argv);
			}

			strncpy(gInFileName, argv[cnt], 256);
			gOp = 2;	// decrypt
		}

		else if (ch == 'o' || ch == 'O')
		{
			if (o_flag == true)
			{
				fprintf(stderr, "Error! Already specifed an output file.\n\n");
				usage(argv);
			}
			o_flag = true;
			cnt++;
			if (cnt >= argc)
			{
				fprintf(stderr, "Error! Must specify a filename after '-o'\n\n");
				usage(argv);
			}
			strncpy(gOutFileName, argv[cnt], 256);
		}

		else if (ch == 'k' || ch == 'K')
		{
			if (k_flag == true)
			{
				fprintf(stderr, "Error! Already specifed a key file.\n\n");
				usage(argv);
			}
			k_flag = true;
			cnt++;
			if (cnt >= argc)
			{
				fprintf(stderr, "Error! Must specify a filename after '-k'\n\n");
				usage(argv);
			}
			strncpy(gKeyFileName, argv[cnt], 256);
		}

		else if (ch == 'p' || ch == 'P')
		{
			if (p_flag == true)
			{
				fprintf(stderr, "Error! Already specifed a password.\n\n");
				usage(argv);
			}
			p_flag = true;
			cnt++;
			if (cnt >= argc)
			{
				fprintf(stderr, "Error! Must enter a password after '-p'\n\n");
				usage(argv);
			}
			strncpy(gPassword, argv[cnt], 256);
		}

		else if (ch == 'r' || ch == 'R')
		{
			int x;

			cnt++;
			if (cnt >= argc)
			{
				fprintf(stderr, "Error! Must enter number between 1 and 3 after '-r'\n\n");
				usage(argv);
			}
			x = atoi(argv[cnt]);
			if (x < 1 || x > 3)
			{
				fprintf(stderr, "Warning! Entered bad value for number of rounds. Setting it to one.\n\n");
				x = 1;
			}
			gNumRounds = x;
		}

		else
		{
			fprintf(stderr, "Error! Illegal option in argument. %s\n\n", argv[cnt]);
			usage(argv);
		}

		cnt++;
	} // end while

	if (gOp == 0)
	{
		fprintf(stderr, "Error! Encrypt or Decrypt must be specified.\n\n)");
		err_flag = true;
	}

	if (i_flag == false)
	{
		fprintf(stderr, "Error! No input file specified.\n\n");
		err_flag = true;
	}

	if (k_flag == false)
	{
		fprintf(stderr, "Error! No key file specified.\n\n");
		err_flag = true;
	}

	if (p_flag == false)
	{
		fprintf(stderr, "Warning! Using default 'password'.\n\n");
	}

	if (o_flag == false && err_flag == false)	// no need to do this if we have errors
	{
		strcpy(gOutFileName, gInFileName);
		if (gOp == 1)	// encrypt
		{
			strcat(gOutFileName, ".enc");
		}
		if (gOp == 2)	// decrypt
		{
			strcat(gOutFileName, ".dec");
		}
	}

	if (err_flag)
	{
		usage(argv);
	}
	return;
} // parseCommandLine



And here's the main function:
C++
int main(int argc, char* argv[])
{
	int length; // resulti;

//	fprintf(stdout, "\n\nCrypto Order:%s\n\n", CRYPTO_ORDER);

	// parse command line parameters
	parseCommandLine(argc, argv);		// sets global variables, checks input options for errors

	// open the input and output files
	gfptrIn = openInputFile(gInFileName);	 // reading the file
	gfptrKey = openInputFile(gKeyFileName);	 // reading the keyfile data
	gfptrOut = openOutputFile(gOutFileName); // writing the file


	length = fread(gkey, 1, 65537, gfptrKey);
	if (length != 65537)
	{
		fprintf(stderr, "Error! Length of key file is not at least 65537.\n\n");
		exit(-1);

	}

	fclose(gfptrKey);
	gfptrKey = NULL;

	if (gOp == 1)	// encrypt
	{
		encryptFile(gfptrIn, gfptrOut);
	}
	/*else
	{
		decryptFile(gfptrIn, gfptrOut);
	}*/

	fclose(gfptrIn);
	fclose(gfptrOut);

	return 0;
} // main


What I have tried:

I was thinking of using this code instead:

C++
void fileStart(){
    FILE *mainFile;
    char name[] = "file.txt";
    fileOpen(mainFile, name);
}


but my teacher sent me the codes to use it, and I don't know which way to put the file name ("Key.data") for gfptKey variable.
Posted
Updated 21-Apr-20 1:15am
v5

C++
gfptrIn = openInputFile(gInFileName);    // reading the file
gfptrKey = openInputFile(gKeyFileName);  // reading the keyfile data
gfptrOut = openOutputFile(gOutFileName); // writing the file

You have three pointer variables and three file name variables that are not declared anywhere. Assuming that the pointers are all declared somewhere as FILE* types, you probably need something like:
C++
gfptrKey = openInputFile("key.data");
// read the key information
//
// call encrypt using the other two names
 
Share this answer
 
v2
Comments
BuildDrive 20-Apr-20 5:42am    
Sorry, I forgot to post global variables and other functions. Please let me know when you find out how.
Richard MacCutchan 20-Apr-20 6:21am    
So what is the problem?
You must provide a full path to the files, because the app may have a different working directory. So add the path to the files. (HAck: copy them in the folder of the app)
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900