Stack around the variable 'ch' was corrupted - c

I am in the process of writing a decipher algorithm for Vegenere Variant Cipher and ran into some C specific issues(I am not too familiar with C).
I get
"Run-Time Check Failure #2 - Stack around the variable 'ch' was corrupted" error.
If I understand the error right, ch is not available when I try to read/write to it(ch in this case represents a HEX value read from the text file, I have posted the code of the function below).
But, for the life of me, I can't figure out where it happens. I close the file way before the I exit the function(exception is thrown at the time I leave the function).
Can you take a look an let me know where I have it wrong? Thanks in advance.
P.S. I am tagging the question with C++ as well as it should pretty much be the same except, maybe, how we read the file in.
Anyways, my code below:
int getKeyLength(char *cipherTxtF){
int potKeyL = 1;
float maxFreq = 0.00;
int winKL = 1;
for (potKeyL = 1; potKeyL <= 13; potKeyL++)// loop that is going through each key size startig at 1 and ending at 13
{
unsigned char ch;
FILE *cipherTxtFi;
cipherTxtFi = fopen(cipherTxtF, "r");
int fileCharCount = 0;
int freqCounter[256] = { 0 };
int nThCharCount = 0;
while (fscanf(cipherTxtFi, "%02X", &ch) != EOF) {
if (ch != '\n') {
if (fileCharCount % potKeyL == 0){
int asciiInd = (int)ch;
freqCounter[asciiInd] += 1;
nThCharCount++;
}
}
fileCharCount++;
}
fclose(cipherTxtFi);
float frequenciesArray[256] = { 0 };
float sumq_iSq = 0;
int k;
for (k = 0; k < 256; k++){
frequenciesArray[k] = freqCounter[k] / (float)nThCharCount;
}
for (k = 0; k < 256; k++){
sumq_iSq += frequenciesArray[k] * frequenciesArray[k];
printf("%f \n", sumq_iSq);
}
if (maxFreq < sumq_iSq) {
maxFreq = sumq_iSq;
winKL = potKeyL;
}
}
return winKL;
}

You are trying to read an hexadecimal integer with fscanf() (format "%02X", where X means "integer in hex format") and store it into a char.
Unfortuantely fscanf() just receives the address of the char and doesn't know that you've not provided the address of an int. As int is larger than a char, the memory gets corrupted.
A solution could be:
int myhex;
while (fscanf(cipherTxtFi, "%02X", &myhex) != EOF) {
ch = myhex;
...

Related

Taking the crypt of a password is adding some weird foobar thing so that it doesn't equal

#include <stdio.h>
#include <cs50.h>
#include <string.h>
#include <ctype.h>
#include <crypt.h>
int main(int argc, string argv[])
{
if(argc > 2){ printf("too many arguments\n"); return 51; }
if(argc < 2){ printf("too few arguments\n"); return 50; }
//if(strlen(argv[1]) > 4){ printf("Password is greater than 4 characters\n"); return 52; }
if(argc == 2) //make sure there are enough args
{
char hash_guess[] = "rofk";
//long long counter = 0;
//while(guess != argv[1]) //crypt(hash_guess, "50") != argv[1]) //while answer not correct
//{
for(int a = 65; a < 91; a++)
{
for(int b = 65; b < 91; b++)
{
for(int c = 65; c < 91; c++)
{
for(int d = 65; d < 91; d++)
{
for(int A = 0; A < 9; A = A + 5) //control if first is caps or not
{
for(int B = 1 ; B < 9 ; B = B + 5)//control if second is caps or not
{
for(int C = 2; C < 9; C = C + 5) //control if third is caps or not
{
for(int D = 3; D < 9; D = D + 5) //control if fourth is caps or not
{
hash_guess[0] = a;
hash_guess[1] = b;
hash_guess[2] = c;
hash_guess[3] = d;
hash_guess[A] = tolower(hash_guess[A]);
hash_guess[B] = tolower(hash_guess[B]);
hash_guess[C] = tolower(hash_guess[C]);
hash_guess[D] = tolower(hash_guess[D]);
printf("%s\n", hash_guess);
string cryptoguess = (crypt(hash_guess, "50"));
string input = argv[1];
if( cryptoguess == input ) { return 0; }
}
}
}
}
}
}
}
//}
//}
//string guess = crypt(hash_guess, "50");
//printf("%lli", counter);
}
}
}
I'm trying to make a program that goes through every 4 letter word, starting on aaaa and going to ZZZZ. I got that part done.
Part of the assignment is to encrypt that, and if the encryption matches an encrypted password, then you know you "hacked" their password. When I compare the encrypted password that I manually enter and the one that comes up by using the crypt function, they are the same, but in the debugger I see this for when it is encrypted by the computer:
"0x7ffff7dd9200 <_ufc_foobar+131200> "50k72iioeOiJU""
and the normal one that I enter shows
"0x7fffffffe34f "50k72iioeOiJU""
the same thing without the _ufc_foobar. Does anyone know why that is there and how I can get rid of it?
The weird junk you are seeing is visualization of offsets of memory addresses in your code which can be ignored.
In your code you are using string when GNU specifies char * is the result of the crypt function.
Therefore, you cannot compare the pointers to the char array using == but instead need to use strcmp C comparing pointers (with chars)
For crypt see: http://www.gnu.org/software/libc/manual/html_node/crypt.html
<_ufc_foobar+131200> isn't part of the string. It's your debugger attempting to figure out where the string came from, and assign a name to it. In this case, it's come up with a bogus result -- _ufc_foobar is the name of a function or variable somewhere else in the program, and your string happens to be stored 131,200 bytes (about 128 KB) after that in memory.
You can safely ignore this. Your strings are equal. They just happen to be stored in different parts of memory (which is normal).

How to store a number string in a file as a seperate integer in an array in C

I have 32 bits as a text file in Sender.txt like
00100100101110001111111100000001
I want to store each individual number as an integer in the array. I have tried the following code but not working.
#include <stdio.h>
#include<stdlib.h>
void main()
{
FILE *myfile;
myfile = fopen("Sender.txt" , "r");
char data[32];
int i,con, data1[32];
for(i=0;i<32;i++)
{
fscanf(myfile, "%1s", &data[i]);
}
for(i=0;i<32;i++)
{
con = atoi(data[i]);
data1[i]=con;
}
for(i=0;i<32;i++)
{
printf("%d \n", &data1[i]);
}
}
Still without fully understanding the purpose of your endeavor, I suggest to rewrite the first two loops:
for(i = 0; i < 32; i++)
{
int next = fgetc(myfile);
data1[i] = (next == '0') : 0 ? 1;
}
This code assumes that the file has 32 1's or 0's, all on the same line, and nothing else.
This could be further compressed, possibly at the expense of clarity:
for(i = 0; i < 32; i++)
{
data1[i] = fgetc(myfile) - '0';
}
Why don't you use fgetc ? This function reads only one Charakter and returns it.
Your code should then look like this:This one got errors see EDIT
FILE *file;
char c[32];
for(int i = 0; i < 32; i++){
if((c[i] = fgetc(file)) == NULL)
//then Error
}
fclose(file);
EDIT: As rightly pointed out by "alk" (what a name mate xD) The if clause makes no sense at all. It was to early in the morning i apologize. The right code should of course look like this:
FILE *file;
int data[32]; //The Question was to store the Data in an int not char like i did...
for(int i = 0; i < 32; i++)
data[i] = fgetc(file) - '0';
fclose(file);
Best regards

Why does my conversion method in C continue to fail?

I am trying to convert from a popen pass, to a float as the final result. I have tried converting to a char, and then into a float in every possible way I can find, however the output I have seen using printf seems to be wrong every time. I have tried using a tostring function, as well as using a %s like in the printf function that returns the correct function, however it all seems to give me the wrong output as soon as I try to convert the output. Should I be trying a different conversion method?
Here is the code.
FILE * uname;
char os[80];
int lastchar;
char n;
uname = popen("sudo python ./return63.py", "r");
lastchar = fread(os, 1, 80, uname);
os[lastchar] = "\0";
n = toString(("%s", os));
printf("THE DIRECT OUTPUT FROM PY IS %s", os);
printf("THE DIRECT OUTPUT For n IS %c", n);
float ia = n - 0;
long p = ia - 0;
float dd = p - 0;
printf("Your OS is %f", dd);
Output from the PY is 'THE DIRECT OUTPUT FROM PY IS 63.0' , which is the correct value,
output from the n is 'THE DIRECT OUTPUT For n IS �'
output from the dd is 'Your OS is Your OS is 236.000000'
The function tostring was pulled from an answered question about how to get the output from another answered question. I have tried with and without this code.
int toString(char a[]) {
int c, sign, offset, n;
if (a[0] == '-') { // Handle negative integers
sign = -1;
}
if (sign == -1) { // Set starting position to convert
offset = 1;
}
else {
offset = 0;
}
n = 0;
for (c = offset; a[c] != '\0'; c++) {
n = n * 10 + a[c] - '0';
}
if (sign == -1) {
n = -n;
}
return n;
}
toString returns an int, so store an int and output an int.
int n = toString(os); // Also removed the obfuscating '("%s", ..)'
printf("THE DIRECT OUTPUT For n IS %d", n);
Also your toString function has undefined behavior because sign might be read without being initialized.
if (a[0] == '-') { // Handle negative integers
sign = -1;
offset = 1;
}
else {
sign = 1;
offset = 0;
}
You have a potential os buffer overflow and you are not doing the null termination of os correctly:
lastchar = fread(os, 1, sizeof(os) - 1, uname); // Only read one byte less
os[lastchar] = '\0'; // changed from string "\0" to char '\0'
And finally you are not checking the input string for digits, you are accepting every input (also the '.' in "63.0"). You might want to stop at the first non-digit character:
for (c = offset; !isdigit((unsigned char)a[c]); c++) {

C - reading multiple file streams

Im writing my own simplified version of the classic UNIX program 'wc' (word count). It counts number of lines, words, and characters. All these features work fine. But where i run into trouble is when im trying to read multiple files from *argv[x]. I need to make every variable into an array, and run the whole process through loops to achieve what im looking for.
My program returns a segmentation fault. Something is not being assigned into the arrays at some point in the code, and i can't seem to figure out exactly where that is.
Any help is much appreciated :)
/*
* [PROGRAM] wc (word count)
* [AUTHOR] Jesper M. Olsen # jm0.codes
* [DATE] September 9th 2015
* [PURPOSE] Returns number of lines, words, and characters in a file
*
* [DESCRIPTION] This program is meant to be utilized as a handy little browsing tool.
* For instance, while moving through the filesystem of a programming archive,
* just type 'wc <filename>' and you will get number of lines, words and characters returned promptly.
*/
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
if (argc == 1)
return -1;
int numL[argc]; /* initialize array value placeholders */
int numW[argc];
int numC[argc];
int getC[argc];
int getW[argc];
int setNull;
for (setNull = 1; setNull <= argc-1; setNull++) { /* assign ZERO to value placeholders */
numL[setNull] = 0;
numW[setNull] = 0;
numC[setNull] = 0;
getW[setNull] = 0;
}
int x;
FILE *fOp[argc-1];
for (x = 1; x <= argc-1; x++) { /* open file stream for each file */
fOp[x] = fopen(argv[x], "r");
if (fOp[x] == NULL)
return -1;
}
int y;
for (y = 1; (getC[y] = getc(fOp[y])) != EOF; y++) {
if (getC[y] == '\n') numL[y]++;
if (getC[y] == ' ' || getC[y] == '\n' || getC[y] == '\t') getW[y] = 0;
else if (getW[y] == 0) {
getW[y] = 1;
numW[y]++;
} numC[y]++;
}
int z;
for (z = 1; z <= argc-1; z++) { /* close files */
fclose(fOp[z]);
}
int c;
for (c = 1; c <= argc-1; c++) {
printf("[%s] %dL %dW %dC\n", argv[c], numL[c], numW[c], numC[c]);
}
return 0;
}
This will cause a segfault when you reach the last file
FILE *fOp[argc-1];
for (x = 1; x <= argc-1; x++) { /* open file stream for each file */
fOp[x] = fopen(argv[x], "r");
if (fOp[x] == NULL)
return -1;
}
because the array is not large enough. It should be
FILE *fOp[argc];
The mistake would be easier to see if you used
< argc
instead of
<= argc-1
in your loops.
I think problem may be
here -
for (y = 1; (getC[y] = getc(fOp[y])) != EOF; y++) {
if (getC[y] == '\n') numL[y]++;
if (getC[y] == ' ' || getC[y] == '\n' || getC[y] == '\t') getW[y] = 0;
else if (getW[y] == 0) {
getW[y] = 1;
numW[y]++;
} numC[y]++;
}
As arrays can argc number of elements but with this loop you may have read and stored integers more than argc in getC . Thus getting Seg Fault .
But we don't know what it inside files we can't be sure.
Try increasing size of arrays .
Note - It is better to initialize array starting with index 0. In this code you haven't use index 0.

realloc() seems to affect already allocated memory

I am experiencing an issue where the invocation of realloc seems to modify the contents of another string, keyfile.
It's supposed to run through a null-terminated char* (keyfile), which contains just above 500 characters. The problem, however, is that the reallocation I perform in the while-loop seems to modify the contents of the keyfile.
I tried removing the dynamic reallocation with realloc and instead initialize the pointers in the for-loop with a size of 200*sizeof(int) instead. The problem remains, the keyfile string is modified during the (re)allocation of memory, and I have no idea why. I have confirmed this by printing the keyfile-string before and after both the malloc and realloc statements.
Note: The keyfile only contains the characters a-z, no digits, spaces, linebreaks or uppercase. Only a text of 26, lowercase letters.
int **getCharMap(const char *keyfile) {
char *alphabet = "abcdefghijklmnopqrstuvwxyz";
int **charmap = malloc(26*sizeof(int));
for (int i = 0; i < 26; i++) {
charmap[(int) alphabet[i]] = malloc(sizeof(int));
charmap[(int) alphabet[i]][0] = 0; // place a counter at index 0
}
int letter;
int count = 0;
unsigned char c = keyfile[count];
while (c != '\0') {
int arr_count = charmap[c][0];
arr_count++;
charmap[c] = realloc(charmap[c], (arr_count+1)*sizeof(int));
charmap[c][0] = arr_count;
charmap[c][arr_count] = count;
c = keyfile[++count];
}
// Just inspecting the results for debugging
printf("\nCHARMAP\n");
for (int i = 0; i < 26; i++) {
letter = (int) alphabet[i];
printf("%c: ", (char) letter);
int count = charmap[letter][0];
printf("%d", charmap[letter][0]);
if (count > 0) {
for (int j = 1; j < count+1; j++) {
printf(",%d", charmap[letter][j]);
}
}
printf("\n");
}
exit(0);
return charmap;
}
charmap[(int) alphabet[i]] = malloc(sizeof(int));
charmap[(int) alphabet[i]][0] = 0; // place a counter at index 0
You are writing beyond the end of your charmap array. So, you are invoking undefined behaviour and it's not surprising that you are seeing weird effects.
You are using the character codes as an index into the array, but they do not start at 0! They start at whatever the ASCII code for a is.
You should use alphabet[i] - 'a' as your array index.
The following piece of code is a source of troubles:
int **charmap = malloc(26*sizeof(int));
for (int i = 0; i < 26; i++)
charmap[...] = ...;
If sizeof(int) < sizeof(int*), then it will be performing illegal memory access operations.
For example, on 64-bit platforms, the case is usually sizeof(int) == 4 < 8 == sizeof(int*).
Under that scenario, by writing into charmap[13...25], you will be accessing unallocated memory.
Change this:
int **charmap = malloc(26*sizeof(int));
To this:
int **charmap = malloc(26*sizeof(int*));

Resources