CPUMD5Cracker/cpu_md5.cpp

281 lines
4.9 KiB
C++

#include "cpu_md5.h"
#include "md5.h"
#include <iostream>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <cstring>
#include <vector>
#include <sys/time.h>
using namespace std;
CPU_MD5::CPU_MD5(int passLen){
this->numOfTests = 0;
this->timeSpent = 0.0;
this->generatorDone = false;
this->found = false;
this->maxPassLen = passLen;
}
int CPU_MD5::getNumberOfCores(){
int cores = sysconf(_SC_NPROCESSORS_ONLN);
this->num_cores = cores;
return cores;
}
string CPU_MD5::crackMD5(const string& md5){
this->target_md5 = md5;
int cores = getNumberOfCores();
cout<<"Number of Cores :" << cores << endl;
pthread_t* workThreads = new pthread_t[cores];
pthread_t generatorThread;
//create generator thread
int rc = pthread_create(&generatorThread,NULL,CPU_MD5::generatorThreadFunc,(void*)this);
if( -1 == rc ){
cout<<"Can't create thread"<<endl;
exit(1);
}
//create crack threads
for(int i=0; i<cores; i++){
usleep(100);
int rc= pthread_create(&workThreads[i],NULL,CPU_MD5::crackThreadFunc,(void*)this);
if( -1 == rc){
cout<<"Can't create thread"<<endl;
exit(1);
}
}
/*
for(int i=0; i< cores; i++){
pthread_join( workThreads[i], NULL);
}
pthread_join(generatorThread, NULL);
*/
struct timeval start, end;
gettimeofday(&start,NULL);
while(1){
usleep(200);
if( found || !isThereMore() ){
break;
}
}
gettimeofday(&end,NULL);
double span = end.tv_sec - start.tv_sec + (end.tv_usec - start.tv_usec)/1000000.0;
this->timeSpent = span;
/*
//stop
pthread_cancel(generatorThread);
for(int i=0; i< cores; i++)
pthread_cancel(workThreads[i]);
//join
for(int i=0; i< cores; i++){
pthread_join( workThreads[i], NULL);
}
pthread_join(generatorThread, NULL);
*/
delete[] workThreads;
usleep(200);
if(!found){
cout<<endl<<"Can't find password!"<<endl;
return "";
}
cout<<endl<<"Good news, we found the password!"<<endl;
return this->password;
}
/*
*Assume Password only contains
A-Z
a-z
0-9
* */
void* CPU_MD5::generatorThreadFunc(void* arg){
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE,NULL);
CPU_MD5* cpu_md5 = (CPU_MD5*)arg;
int maxPassLen = cpu_md5->maxPassLen;
cout<<"Generator Thread is working...... Max password length is "<<maxPassLen<<endl;
//init character array
vector<char> charArr;
for(char c = 'A'; c <= 'Z'; c++)
charArr.push_back(c);
for(char c = 'a'; c <= 'z'; c++)
charArr.push_back(c);
for(char c = '0'; c <= '9'; c++)
charArr.push_back(c);
for(int len = 1; len <= maxPassLen; len++){
generatePassword(cpu_md5,len,charArr);
}
//teminator
if(! cpu_md5->found)
cpu_md5->buf.addNewPassword(string("$"));
cout<<"Generator thread Done!"<<endl;
cpu_md5->generatorDone = true;
return (void*)1;
}
void CPU_MD5::_generatePassword(CPU_MD5* cpu_md5, int len, vector<char>& charArr, string& newPass, int level){
//if already found, no need to cal anymore!
if( cpu_md5->found )
return;
//new pass is generated!
if( level == len ){
//cout<<"New generated password is "<<newPass<<endl;
cpu_md5->buf.addNewPassword(newPass);
return;
}
for(int i = 0; i < charArr.size(); i++ ){
newPass.push_back( charArr[i] );
_generatePassword(cpu_md5, len,charArr,newPass,level+1);
newPass.erase(level,1);
}
return;
}
void CPU_MD5::generatePassword(CPU_MD5* cpu_md5, int len, vector<char>& charArr){
if( cpu_md5->found )
return;
string newPass;
newPass.reserve(len);
_generatePassword(cpu_md5, len, charArr, newPass, 0);
}
bool CPU_MD5::isThereMore(){
if( generatorDone && buf.getBufSize() == 0)
return false;
return true;
}
void* CPU_MD5::crackThreadFunc(void* arg){
pthread_setcancelstate( PTHREAD_CANCEL_ENABLE,NULL);
CPU_MD5* cpu_md5 = (CPU_MD5*)arg;
cout<<"A new CrackThread is working......"<<endl;
while( 1 ){
if( cpu_md5->found )
break;
if( ! cpu_md5->isThereMore() )
break;
vector<string> passwords = cpu_md5->buf.consume();
for(int i=0; i< passwords.size(); i++){
string pass = passwords[i];
//cout<<"No."<<cpu_md5->numOfTests++<<" Test password :"<<pass<<endl;
cpu_md5->numOfTests++;
MD5 md5_engine;
char* powSalt = "1322bcab5eaa2ada7719647d24a4e17cd2b78dbb8c985a6ffa59eb6f3dbc51c2";
string str = md5_engine.calMD5FromString(pass, powSalt);
//found
/* cout << cpu_md5->target_md5[0] << '\n'; */
/* if( !str.compare(cpu_md5->target_md5) ){ // TODO: modify this line to enable partial hash cracking */
if ( !strncmp(str.c_str(), cpu_md5->target_md5.c_str(), 6) ) {
/* if ( !strncmp(str.c_str(), cpu_md5->target_md5.c_str(), 6) ) { */
/* cout << "## compare matches ##" << endl; */
/* } */
cout << "##########################" << endl;
cout << str << endl;
cout << "##########################" << endl;
cout<<endl<<"Found the password for this md5"<<endl;
cpu_md5->found = true;
cpu_md5->password = pass;
break;
}
}
}
cout<<"One cracking thread is done!"<<endl;
return (void*)0;
}