Hi all, I'm still new to C and memory leaks are the bane of my existence as I create them often
I know I have leaks in this small program, but can't reason where/why. I tried using valgrind but found the output to be extremely complicated and over my head. I'm hoping someone could help point out my mem leaks and would LOVE if you added a quick note on why/how and better practices. Running 'top' while this program runs shows it pretty quickly chewing up all the memory until it freezes if not stopped. I'm sure I'm not following best practices in many places, so feel free to point those out if you want since I'm trying to improve (aren't we all?)
Code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/time.h>
#include <unistd.h>
#include <openssl/crypto.h>
#include <openssl/sha.h>
//Prototypes
char * hash(char * str);
void brute(char * PW, int index, int depth, char * pass, char * alphabet);
//recursive brute force algo
void brute(char * PW, int index, int depth, char * pass, char * alphabet){
int alphSize = strlen(alphabet);
int i;
for(i=0; i < alphSize; ++i){
PW[index] = alphabet[i];
char * curr_hash = hash(PW);
if(index == depth){
// test the current combination agienst the password
// if they are the same the program reports and ends.
if(strcmp(curr_hash,pass) == 0){
//shouldnt need any free's since the program exits and OS frees
struct timeval tv;
gettimeofday(&tv, NULL);
fprintf(stdout, "%s %ld\n", PW, tv.tv_sec); //print time ended and plain text password
exit(0);
// if they arent it just prints the current combonation
}else{
free(curr_hash); //hash no longer needed so free it
}
// if its not the max depth it calls itself again
}else{
free(curr_hash); //hash no longer needed so free it
brute(PW,index+1,depth, pass, alphabet);
}
}
}
//Generate and return the sha256 hash of the given string
char * hash(char * str){
char * hash = malloc(64 + 1);
hash[strlen(hash)] = '\0';
unsigned char out_buf[SHA256_DIGEST_LENGTH];
SHA256(str, strlen(str), out_buf);
int i;
for (i = 0; i < SHA256_DIGEST_LENGTH; i++) {
unsigned char * b = malloc(3);
b[2] = '\0';
//must be %02x or filler zeros aren't added
sprintf(b, "%02x", out_buf[i]); //out_buf[i] is int but needs to be stored as hex
hash = strcat(hash, b);
free(b); //shouldnt need since stack mem will be dealloc'd?
}
return hash;
}
int main(int argc, char * argv[])
{
if(argc != 4){
fprintf(stderr, "Cracker takes a password hash to crack, and a password length, and an alphabet\n");
exit(1);
}
struct timeval tv;
gettimeofday(&tv, NULL);
fprintf(stdout, "%ld ", tv.tv_sec); // print time started
free(&tv); //free struct
int len = atoi(argv[2]) - 1; // -1, so 'hello' is len 5 but start at aaaa (4)
char * posPW = malloc(len + 1);
brute(posPW, 0 , len, argv[1], argv[3]);
printf("NULL -1\n"); //only gets here if brute didn't crack the pass, so report failure here
}