BuildDrive Ответов: 2

Как открыть файл с именем "key.data" с помощью переменной 'gfptrkey'?


#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



У меня уже есть функции для открытия входного файла и выходного файла:

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



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



А вот и основная функция:
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


Что я уже пробовал:

Я думал использовать этот код вместо этого:

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


но мой учитель прислал мне коды для его использования, и я не знаю, в какую сторону поместить имя файла ("Key.data") для переменной gfptKey.

2 Ответов

Рейтинг:
0

Richard MacCutchan

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

У вас есть три переменные указателя и три переменные имени файла, которые нигде не объявлены. Предполагая, что все указатели объявлены где-то как FILE* типы, вам, вероятно, нужно что-то вроде:
gfptrKey = openInputFile("key.data");
// read the key information
//
// call encrypt using the other two names


BuildDrive

Извините, я забыл опубликовать глобальные переменные и другие функции. Пожалуйста, дайте мне знать, когда узнаете, как это сделать.

Richard MacCutchan

Так в чем же проблема?

Рейтинг:
0

KarstenK

Вы должны указать полный путь к файлам, так как приложение может иметь другой рабочий каталог. Поэтому добавьте путь к файлам. (Хак: скопируйте их в папку приложения)