-/*
- * rcracki_mt is a multithreaded implementation and fork of the original
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- * Copyright 2010 uroskn
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
- #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "CrackEngine.h"
-#include "RTI2Reader.h"
-
-#ifndef _WIN32
- #include <sys/resource.h>
-#endif
-
-CCrackEngine::CCrackEngine()
-{
- ResetStatistics();
- writeOutput = false;
- resumeSession = false;
- debug = false;
- keepPrecalcFiles = false;
-
- sSessionPathName = "";
- sProgressPathName = "";
-}
-
-CCrackEngine::~CCrackEngine()
-{
-}
-
-//////////////////////////////////////////////////////////////////////
-
-void CCrackEngine::ResetStatistics()
-{
- m_fTotalDiskAccessTime = 0.0f;
- m_fTotalCryptanalysisTime = 0.0f;
- m_fTotalPrecalculationTime = 0.0f;
- m_nTotalChainWalkStep = 0;
- m_nTotalFalseAlarm = 0;
- m_nTotalChainWalkStepDueToFalseAlarm = 0;
-// m_nTotalFalseAlarmSkipped = 0;
-}
-
-int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)
-{
- int nLow = 0;
- int nHigh = nRainbowChainCount - 1;
- while (nLow <= nHigh)
- {
- int nMid = (nLow + nHigh) / 2;
- if (nIndex == pChain[nMid].nIndexE)
- return nMid;
- else if (nIndex < pChain[nMid].nIndexE)
- nHigh = nMid - 1;
- else
- nLow = nMid + 1;
- }
-
- return -1;
-}
-
-RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)
-{
- uint64 nPrefix = nIndex >> 16;
- int nLow, nHigh;
- bool found = false;
- //int nChains = 0;
-
- if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file
- {
- return NULL;
- }
-
- int nBLow = 0;
- int nBHigh = nIndexSize - 1;
- while (nBLow <= nBHigh)
- {
- int nBMid = (nBLow + nBHigh) / 2;
- if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
- {
- //nLow = nChains;
- //int nChains = 0;
-
- nLow = pIndex[nBMid].nFirstChain;
- nHigh = nLow + pIndex[nBMid].nChainCount;
- if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead)
- {
- if(nHigh > nIndexStart + nChainCountRead)
- nHigh = nIndexStart + nChainCountRead;
- }
- else if(nLow < nIndexStart && nHigh >= nIndexStart)
- {
- nLow = nIndexStart;
- }
- else break;
- found = true;
- break;
- }
- else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
- nBHigh = nBMid - 1;
- else
- nBLow = nBMid + 1;
- }
- if(found == true)
- {
- for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)
- {
- int nSIndex = ((int)nIndex) & 0x0000FFFF;
-
- if (nSIndex == pChain[i].nIndexE)
- {
- return &pChain[i];
- }
- else if(pChain[i].nIndexE > nSIndex)
- break;
- }
- }
- return NULL;
-}
-
-// not used currently, leaving code for future checkpoints
-//bool CCrackEngine::CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
-//{
-// CChainWalkContext cwc;
-// //uint64 nIndexS = pChain->nIndexS >> 16;
-// uint64 nIndexS = pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
-// cwc.SetIndex(nIndexS);
-// int nPos;
-// for (nPos = 0; nPos < nGuessedPos; nPos++)
-// {
-// cwc.IndexToPlain();
-// cwc.PlainToHash();
-// cwc.HashToIndex(nPos);
-// // Not using checkpoints atm
-// /*
-// switch(nPos)
-// {
-// case 5000:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)
-// {
-// m_nTotalFalseAlarmSkipped += 10000 - 5000;
-//// printf("CheckPoint caught false alarm at position 7600\n");
-// return false;
-// }
-// break;
-// case 6000:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)
-// {
-//// printf("CheckPoint caught false alarm at position 8200\n");
-// m_nTotalFalseAlarmSkipped += 10000 - 6000;
-// return false;
-// }
-// break;
-//
-// case 7600:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)
-// {
-//// printf("CheckPoint caught false alarm at position 8700\n");
-// m_nTotalFalseAlarmSkipped += 10000 - 7600;
-// return false;
-// }
-// break;
-//
-// case 8200:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)
-// {
-//// printf("CheckPoint caught false alarm at position 9000\n");
-// m_nTotalFalseAlarmSkipped += 10000 - 8200;
-// return false;
-// }
-// break;
-//
-// case 8700:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)
-// {
-//// printf("CheckPoint caught false alarm at position 9300\n");
-// m_nTotalFalseAlarmSkipped += 10000 - 8700;
-// return false;
-// }
-//
-// break;
-// case 9000:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)
-// {
-//// printf("CheckPoint caught false alarm at position 9600\n");
-// m_nTotalFalseAlarmSkipped += 10000 - 9000;
-// return false;
-// }
-//
-// break;
-// case 9300:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)
-// {
-//// printf("CheckPoint caught false alarm at position 9600\n");
-// m_nTotalFalseAlarmSkipped += 10000 - 9300;
-// return false;
-// }
-// break;
-// case 9600:
-// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))
-// {
-//// printf("CheckPoint caught false alarm at position 9600\n");
-// m_nTotalFalseAlarmSkipped += 10000 - 9600;
-// return false;
-// }
-// break;
-//
-// }*/
-// }
-// cwc.IndexToPlain();
-// cwc.PlainToHash();
-// if (cwc.CheckHash(pHash))
-// {
-// printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
-// hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
-// return true;
-// }
-//
-// return false;
-//}
-
-//bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
-//{
-// CChainWalkContext cwc;
-// cwc.SetIndex(pChain->nIndexS);
-// int nPos;
-// for (nPos = 0; nPos < nGuessedPos; nPos++)
-// {
-// cwc.IndexToPlain();
-// cwc.PlainToHash();
-// cwc.HashToIndex(nPos);
-// }
-// cwc.IndexToPlain();
-// cwc.PlainToHash();
-// if (cwc.CheckHash(pHash))
-// {
-// printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
-// hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
-// return true;
-// }
-//
-// return false;
-//}
-
-void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,
- int nRainbowChainCount,
- int nMatchingIndexE,
- int& nMatchingIndexEFrom,
- int& nMatchingIndexETo)
-{
- nMatchingIndexEFrom = nMatchingIndexE;
- nMatchingIndexETo = nMatchingIndexE;
- while (nMatchingIndexEFrom > 0)
- {
- if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
- nMatchingIndexEFrom--;
- else
- break;
- }
- while (nMatchingIndexETo < nRainbowChainCount - 1)
- {
- if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
- nMatchingIndexETo++;
- else
- break;
- }
-}
-
-void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)
-{
- vector<string> vHash;
- hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
- printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
- vHash.size() > 1 ? "es" : "");
-
- int nChainWalkStep = 0;
- int nFalseAlarm = 0;
- int nChainWalkStepDueToFalseAlarm = 0;
-
- vector<rcrackiThread*> threadPool;
- vector<pthread_t> pThreads;
-
- #ifndef _WIN32
- /*
- * On linux you cannot set the priority of a thread in the non real time
- * scheduling groups. You can set the priority of the process. In
- * windows BELOW_NORMAL represents a 1/8th drop in priority and this would
- * be 20 * 1/8 on linux or about 2.5
- */
- setpriority( PRIO_PROCESS, 0, 2 );
- #endif
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- #ifdef _WIN32
- sched_param param;
- /*
- * windows scheduling is 0 to 32 (low to high) with 8 as normal and 7 as
- * BELOW_NORMAL
- */
- param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
- pthread_attr_setschedparam (&attr, ¶m);
- #endif
-
- bool pausing = false;
-
- UINT4 nHashIndex;
- for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
- {
- #ifdef _WIN32
- if (_kbhit())
- {
- int ch = _getch();
- ch = toupper(ch);
- if (ch == 'P')
- {
- pausing = true;
- printf( "\nPausing, press P again to continue... ");
-
- timeval tv;
- timeval tv2;
- timeval final;
- gettimeofday( &tv, NULL );
-
- while (pausing)
- {
- if (_kbhit())
- {
- ch = _getch();
- ch = toupper(ch);
- if (ch == 'P')
- {
- printf( " [Continuing]\n");
- pausing = false;
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- m_fTotalCryptanalysisTime -= fTime;
- }
- }
- Sleep(500);
- }
- }
- else
- {
- printf( "\nPress 'P' to pause...\n");
- }
- }
- #else
- int c = tty_getchar();
- if (c >= 0) {
- tty_flush();
- if (c==112) { // = p
- pausing = true;
- printf( "\nPausing, press 'p' again to continue... ");
-
- timeval tv;
- timeval tv2;
- timeval final;
- gettimeofday( &tv, NULL );
-
- while (pausing)
- {
- if ((c = tty_getchar()) >= 0)
- {
- tty_flush();
- if (c == 112)
- {
- printf( " [Continuing]\n");
- pausing = false;
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- m_fTotalCryptanalysisTime -= fTime;
- }
- }
- usleep(500*1000);
- }
- }
- else {
- printf( "\nPress 'p' to pause...\n");
- }
- }
- #endif
- unsigned char TargetHash[MAX_HASH_LEN];
- int nHashLen;
- ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
- if (nHashLen != CChainWalkContext::GetHashLen())
- printf("debug: nHashLen mismatch\n");
-
- // Rqeuest ChainWalk
- bool fNewlyGenerated;
- uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
- nHashLen,
- CChainWalkContext::GetHashRoutineName(),
- CChainWalkContext::GetPlainCharsetName(),
- CChainWalkContext::GetPlainLenMin(),
- CChainWalkContext::GetPlainLenMax(),
- CChainWalkContext::GetRainbowTableIndex(),
- nRainbowChainLen,
- fNewlyGenerated,
- debug,
- sPrecalcPathName);
- //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
- // vHash[nHashIndex].c_str());
-
- // Walk
- if (fNewlyGenerated)
- {
- timeval tv;
- timeval tv2;
- timeval final;
-
- gettimeofday( &tv, NULL );
-
- printf("Pre-calculating hash %lu of %lu.%-20s\r",
- (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
- threadPool.clear();
- pThreads.clear();
-
- UINT4 thread_ID;
- for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
- {
- rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
- if (r_Thread)
- {
- pthread_t pThread;
- int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
- if( returnValue != 0 )
- {
- printf("pThread creation failed, returnValue: %d\n", returnValue);
- }
- else
- {
- pThreads.push_back(pThread);
- }
-
- threadPool.push_back(r_Thread);
- }
- else
- {
- printf("r_Thread creation failed!\n");
- }
- }
-
- //printf("%d r_Threads created\t\t\n", threadPool.size());
-
- for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
- {
- pthread_t pThread = pThreads[thread_ID];
- int returnValue = pthread_join(pThread, NULL);
- if( returnValue != 0 )
- {
- printf("pThread join failed, returnValue: %d\n", returnValue);
- }
-
- rcrackiThread* rThread = threadPool[thread_ID];
- nChainWalkStep += rThread->GetChainWalkStep();
- }
-
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
-
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-
- m_fTotalPrecalculationTime += fTime;
- m_fTotalCryptanalysisTime -= fTime;
-
- printf("%-50s\r", "");
-
- if ( debug )
- printf("pre-calculation time: %.2f s\n", fTime);
- }
-
- //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
- printf("Checking false alarms for hash %lu of %lu.%-20s\r",
- (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
-
- threadPool.clear();
- pThreads.clear();
-
- int i;
- for (i = 0; i < maxThreads; i++)
- {
- rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);
- threadPool.push_back(r_Thread);
- }
-
- UINT4 thread_ID = 0;
- int nPos;
- for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
- {
- uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
-
- // Search matching nIndexE
- int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);
- if (nMatchingIndexE != -1)
- {
- int nMatchingIndexEFrom, nMatchingIndexETo;
- GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,
- nMatchingIndexE,
- nMatchingIndexEFrom, nMatchingIndexETo);
- int i;
- for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)
- {
- rcrackiThread* rThread = threadPool[thread_ID];
- rThread->AddAlarmCheckO(pChain + i, nPos);
- if (thread_ID < (unsigned long)maxThreads - 1 ) {
- thread_ID++;
- } else {
- thread_ID = 0;
- }
- }
- }
- }
-
- for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
- {
- rcrackiThread* r_Thread = threadPool[thread_ID];
- pthread_t pThread;
-
- int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
- if( returnValue != 0 )
- {
- printf("pThread creation failed, returnValue: %d\n", returnValue);
- }
- else
- {
- pThreads.push_back(pThread);
- }
- }
-
- //printf("%d r_Threads created\t\t\n", threadPool.size());
-
- bool foundHashInThread = false;
- for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
- {
- rcrackiThread* rThread = threadPool[thread_ID];
- pthread_t pThread = pThreads[thread_ID];
-
- int returnValue = pthread_join(pThread, NULL);
- if( returnValue != 0 )
- {
- printf("pThread join failed, returnValue: %d\n", returnValue);
- }
-
- nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
- nFalseAlarm += rThread->GetnFalseAlarm();
-
- if (rThread->FoundHash() && !foundHashInThread) {
- //printf("\t\t\t\t\t\t\r");
- printf("%-50s\r", "");
-
- printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
- if (writeOutput)
- {
- if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
- printf("Couldn't write this result to file!\n");
- }
- hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
-
- FILE* file = fopen(sSessionPathName.c_str(), "a");
- if (file!=NULL)
- {
- string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
- fputs (buffer.c_str(), file);
- fclose (file);
- }
-
- m_cws.DiscardWalk(pStartPosIndexE);
- foundHashInThread = true;
- }
- }
-
- pThreads.clear();
- threadPool.clear();
- }
-
- //printf("\t\t\t\t\t\t\t\r");
- printf("%-50s\r", "");
- pThreads.clear();
- threadPool.clear();
- pthread_attr_destroy(&attr);
-
- //printf("debug: chain walk step: %d\n", nChainWalkStep);
- //printf("debug: false alarm: %d\n", nFalseAlarm);
- //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
-
- m_nTotalChainWalkStep += nChainWalkStep;
- m_nTotalFalseAlarm += nFalseAlarm;
- m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
-}
-
-void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)
-{
- vector<string> vHash;
- //vector<uint64 *> vIndices;
- //vector<RainbowChain *> vChains;
- hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
- printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
- vHash.size() > 1 ? "es" : "");
-
- int nChainWalkStep = 0;
- int nFalseAlarm = 0;
- int nChainWalkStepDueToFalseAlarm = 0;
-
- vector<rcrackiThread*> threadPool;
- vector<pthread_t> pThreads;
-
- #ifndef _WIN32
- /*
- * On linux you cannot set the priority of a thread in the non real time
- * scheduling groups. You can set the priority of the process. In
- * windows BELOW_NORMAL represents a 1/8th drop in priority and this would
- * be 20 * 1/8 on linux or about 2.5
- */
- setpriority( PRIO_PROCESS, 0, 2 );
- #endif
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
- #ifdef _WIN32
- sched_param param;
- param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
- pthread_attr_setschedparam (&attr, ¶m);
- #endif
- // else set it to 5 or something (for linux)?
-
- bool pausing = false;
-
- UINT4 nHashIndex;
- for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
- {
- #ifdef _WIN32
- if (_kbhit())
- {
- int ch = _getch();
- ch = toupper(ch);
- if (ch == 'P')
- {
- pausing = true;
- printf( "\nPausing, press P again to continue... ");
-
- timeval tv;
- timeval tv2;
- timeval final;
- gettimeofday( &tv, NULL );
-
- while (pausing)
- {
- if (_kbhit())
- {
- ch = _getch();
- ch = toupper(ch);
- if (ch == 'P')
- {
- printf( " [Continuing]\n");
- pausing = false;
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- m_fTotalCryptanalysisTime -= fTime;
- }
- }
- Sleep(500);
- }
- }
- else
- {
- printf( "\nPress 'P' to pause...\n");
- }
- }
- #else
- int c = tty_getchar();
- if (c >= 0) {
- tty_flush();
- if (c==112) { // = p
- pausing = true;
- printf( "\nPausing, press 'p' again to continue... ");
-
- timeval tv;
- timeval tv2;
- timeval final;
- gettimeofday( &tv, NULL );
-
- while (pausing)
- {
- if ((c = tty_getchar()) >= 0)
- {
- tty_flush();
- if (c == 112)
- {
- printf( " [Continuing]\n");
- pausing = false;
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- m_fTotalCryptanalysisTime -= fTime;
- }
- }
- usleep(500*1000);
- }
- }
- else {
- printf( "\nPress 'p' to pause...\n");
- }
- }
- #endif
- unsigned char TargetHash[MAX_HASH_LEN];
- int nHashLen;
- ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
- if (nHashLen != CChainWalkContext::GetHashLen())
- printf("debug: nHashLen mismatch\n");
-
- // Request ChainWalk
- bool fNewlyGenerated;
-// printf("Requesting walk...");
-
-
- uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
- nHashLen,
- CChainWalkContext::GetHashRoutineName(),
- CChainWalkContext::GetPlainCharsetName(),
- CChainWalkContext::GetPlainLenMin(),
- CChainWalkContext::GetPlainLenMax(),
- CChainWalkContext::GetRainbowTableIndex(),
- nRainbowChainLen,
- fNewlyGenerated,
- debug,
- sPrecalcPathName);
-// printf("done!\n");
-// printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
-// vHash[nHashIndex].c_str());
-
- if (fNewlyGenerated)
- {
- timeval tv;
- timeval tv2;
- timeval final;
-
- gettimeofday( &tv, NULL );
-
- printf("Pre-calculating hash %lu of %lu.%-20s\r",
- (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
- threadPool.clear();
- pThreads.clear();
-
- UINT4 thread_ID;
- for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
- {
- rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
- if (r_Thread)
- {
- pthread_t pThread;
- int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
- if( returnValue != 0 )
- {
- printf("pThread creation failed, returnValue: %d\n", returnValue);
- }
- else
- {
- pThreads.push_back(pThread);
- }
-
- threadPool.push_back(r_Thread);
- }
- else
- {
- printf("r_Thread creation failed!\n");
- }
- }
-
- //printf("%d r_Threads created\t\t\n", threadPool.size());
-
- for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
- {
- pthread_t pThread = pThreads[thread_ID];
- int returnValue = pthread_join(pThread, NULL);
- if( returnValue != 0 )
- {
- printf("pThread join failed, returnValue: %d\n", returnValue);
- }
-
- rcrackiThread* rThread = threadPool[thread_ID];
- nChainWalkStep += rThread->GetChainWalkStep();
- delete rThread;
- }
-
- m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
-
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-
- m_fTotalPrecalculationTime += fTime;
- m_fTotalCryptanalysisTime -= fTime;
-
- //printf("\npStartPosIndexE[0]: %s\n", uint64tostr(pStartPosIndexE[0]).c_str());
- //printf("\npStartPosIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pStartPosIndexE[nRainbowChainLen-2]).c_str());
-
- printf("%-50s\r", "");
-
- if ( debug )
- printf("pre-calculation time: %.2f s\n", fTime);
- }
-
- threadPool.clear();
- pThreads.clear();
-
- //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
- printf("Checking false alarms for hash %lu of %lu.%-20s\r",
- (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
-
- int i;
- for (i = 0; i < maxThreads; i++)
- {
- rcrackiThread* r_Thread = new rcrackiThread(TargetHash);
- threadPool.push_back(r_Thread);
- }
-
- UINT4 thread_ID = 0;
- int nPos;
- for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
- {
- uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
-
- // Search matching nIndexE
- RainbowChain *pChainFound = BinarySearch(pChain, nRainbowChainCount, nIndexEOfCurPos, pIndex, nIndexSize, nChainStart);
- if (pChainFound != NULL) // For perfected indexed tables we only recieve 1 result (huge speed increase!)
- {
- rcrackiThread* rThread = threadPool[thread_ID];
- rThread->AddAlarmCheck(pChainFound, nPos);
- if (thread_ID < (unsigned long)maxThreads - 1 ) {
- thread_ID++;
- } else {
- thread_ID = 0;
- }
- }
- }
-
- for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
- {
- rcrackiThread* r_Thread = threadPool[thread_ID];
- pthread_t pThread;
-
- int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
- if( returnValue != 0 )
- {
- printf("pThread creation failed, returnValue: %d\n", returnValue);
- }
- else
- {
- pThreads.push_back(pThread);
- }
- }
-
- //printf("%d r_Threads created\t\t\n", threadPool.size());
-
- bool foundHashInThread = false;
- for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
- {
- rcrackiThread* rThread = threadPool[thread_ID];
- pthread_t pThread = pThreads[thread_ID];
-
- int returnValue = pthread_join(pThread, NULL);
- if( returnValue != 0 )
- {
- printf("pThread join failed, returnValue: %d\n", returnValue);
- }
-
- nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
- nFalseAlarm += rThread->GetnFalseAlarm();
-
- if (rThread->FoundHash() && !foundHashInThread) {
- //printf("\t\t\t\t\t\t\r");
- printf("%-50s\r", "");
- printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
- if (writeOutput)
- {
- if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
- printf("Couldn't write this result to file!\n");
- }
- hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
-
- FILE* file = fopen(sSessionPathName.c_str(), "a");
- if (file!=NULL)
- {
- string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
- fputs (buffer.c_str(), file);
- fclose (file);
- }
-
- m_cws.DiscardWalk(pStartPosIndexE);
- foundHashInThread = true;
- }
- //pthread
- delete rThread;
- }
-
- pThreads.clear();
- threadPool.clear();
-
- //printf("\t\t\t\t\r");
- //printf("pChainFounds: %d\n", pChainsFound.size());
-//NEXT_HASH:;
- }
- //printf("\t\t\t\t\t\t\t\r");
- printf("%-50s\r", "");
- pThreads.clear();
- threadPool.clear();
- pthread_attr_destroy(&attr);
-
- //printf("debug: chain walk step: %d\n", nChainWalkStep);
- //printf("debug: false alarm: %d\n", nFalseAlarm);
- //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
-
- m_nTotalChainWalkStep += nChainWalkStep;
- m_nTotalFalseAlarm += nFalseAlarm;
- m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
-}
-
-void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)
-{
- // Did we already go through this file in this session?
- if (resumeSession)
- {
- vector<string> sessionFinishedPathNames;
- if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))
- {
- UINT4 i;
- for (i = 0; i < sessionFinishedPathNames.size(); i++)
- {
- if (sessionFinishedPathNames[i] == sPathName)
- {
- printf("Skipping %s\n", sPathName.c_str());
- return;
- }
- }
- }
- }
-
- // FileName
-#ifdef _WIN32
- string::size_type nIndex = sPathName.find_last_of('\\');
-#else
- string::size_type nIndex = sPathName.find_last_of('/');
-#endif
- string sFileName;
- if (nIndex != string::npos)
- sFileName = sPathName.substr(nIndex + 1);
- else
- sFileName = sPathName;
-
- // Info
- printf("%s:\n", sFileName.c_str());
-
- // Setup
- int nRainbowChainLen, nRainbowChainCount;
- if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))
- return;
- //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());
- // Already finished?
- if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
- {
- printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());
- return;
- }
-
- // Open
- FILE* file = fopen(sPathName.c_str(), "rb");
- if (file != NULL)
- {
- // File length check
- bool doOldFormat = CChainWalkContext::isOldFormat();
- bool doRti2Format = CChainWalkContext::isRti2Format();
- UINT4 sizeOfChain;
- bool fVerified = false;
- UINT4 nFileLen = GetFileLen(file);
-
- if (doOldFormat)
- sizeOfChain = 16;
- else
- sizeOfChain = 8;
-
- //if (nFileLen % 8 != 0 || nRainbowChainCount * 8 != nFileLen)
- if ( (nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != nFileLen) && doRti2Format == false )
- printf("file length mismatch\n");
- else
- {
- fseek(file, 0, SEEK_SET);
- timeval tv;
- timeval tv2;
- timeval final;
-
- unsigned int bytesForChainWalkSet = hs.GetStatHashTotal() * (nRainbowChainLen-1) * 8;
- if (debug) printf("Debug: Saving %u bytes of memory for chainwalkset.\n", bytesForChainWalkSet);
-
- uint64 nAllocatedSize;
-
- if (doRti2Format || doOldFormat)
- {
- RTI2Reader *pReader = NULL;
-
- if(doRti2Format) {
- pReader = new RTI2Reader(sPathName);
-
- }
-
- if (debug)
- {
- if ( doOldFormat )
- printf("Debug: This is a table in the old .rt format.\n");
- else if ( doRti2Format )
- printf("Debug: This is a table in the .rti2 format.\n");
- }
-
- static CMemoryPool mp(bytesForChainWalkSet, debug, maxMem);
- RainbowChainO* pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);
- #ifdef _WIN32
- if (debug) printf("Allocated %I64u bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);
- #else
- if (debug) printf("Allocated %llu bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);
- #endif
-
- if (pChain != NULL)
- {
- nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
-
- //fseek(file, 0, SEEK_SET);
- //bool fVerified = false;
- while (true) // Chunk read loop
- {
- if ((unsigned long)ftell(file) == nFileLen)
- break;
-
- // Load table chunk
- if (debug) printf("reading...\n");
- unsigned int nDataRead = 0, nDataToRead = 0;
- gettimeofday( &tv, NULL );
- if ( doRti2Format )
- {
- nDataToRead = nAllocatedSize / 16;
- nDataRead = nDataToRead;
- pReader->ReadChains(nDataRead, pChain);
- nDataRead *= 8; // Convert from chains read to bytes
- }
- else
- {
- nDataRead = fread(pChain, 1, nAllocatedSize, file);
- }
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
-
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
- m_fTotalDiskAccessTime += fTime;
-
- int nRainbowChainCountRead = nDataRead / 16;
-
- // Verify table chunk
- if (!fVerified)
- {
- printf("verifying the file...\n");
-
- // Chain length test
- int nIndexToVerify = nRainbowChainCountRead / 2;
- CChainWalkContext cwc;
- cwc.SetIndex(pChain[nIndexToVerify].nIndexS);
- int nPos;
- for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
- {
- cwc.IndexToPlain();
- cwc.PlainToHash();
- cwc.HashToIndex(nPos);
- }
- if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)
- {
- printf("rainbow chain length verify fail\n");
- break;
- }
-
- // Chain sort test
- int i;
- for (i = 0; i < nRainbowChainCountRead - 1; i++)
- {
- if (pChain[i].nIndexE > pChain[i + 1].nIndexE)
- break;
- }
- if (i != nRainbowChainCountRead - 1)
- {
- printf("this file is not sorted\n");
- break;
- }
-
- fVerified = true;
- }
-
- // Search table chunk
- gettimeofday( &tv, NULL );
- SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
- fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- printf("cryptanalysis time: %.2f s\n", fTime);
- m_fTotalCryptanalysisTime += fTime;
-
- // Already finished?
- if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
- break;
-
- // finished the current table
- if( doRti2Format && nDataToRead > (nDataRead / 8) )
- {
- delete pReader;
- break;
- }
- }
- }
- else
- printf("memory allocation fail\n");
-
- //delete pChain;
- }
- else
- {
- static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);
- uint64 nAllocatedSizeIndex;
-
- //int nIndexSize = 0;
- //IndexChain *pIndex = NULL;
-
- FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");
- if(fIndex != NULL)
- {
- // File length check
- unsigned int nFileLenIndex = GetFileLen(fIndex);
- //unsigned int nRows = nFileLenIndex / 11;
- //unsigned int nSize = nRows * sizeof(IndexChain);
- //printf("Debug: 8\n");
- if (nFileLenIndex % 11 != 0)
- printf("index file length mismatch (%u bytes)\n", nFileLenIndex);
- else
- {
- //printf("index nSize: %d\n", nSize);
- //pIndex = (IndexChain*)new unsigned char[nSize];
- IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);
- #ifdef _WIN32
- if (debug) printf("Debug: Allocated %I64u bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
- #else
- if (debug) printf("Debug: Allocated %llu bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
- #endif
-
- static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);
-
- if (pIndex != NULL && nAllocatedSizeIndex > 0)
- {
- nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain); // Round to sizeOfIndexChain boundary
-
- fseek(fIndex, 0, SEEK_SET);
-
- while ( (unsigned long)ftell(fIndex) != nFileLenIndex ) // Index chunk read loop
- {
- // Load index chunk
-#ifdef _WIN32
- if (debug) printf("Debug: Setting index to 0x00 in memory, %I64u bytes\n", nAllocatedSizeIndex);
-#else
- if (debug) printf("Debug: Setting index to 0x00 in memory, %llu bytes\n", nAllocatedSizeIndex);
-#endif
- memset(pIndex, 0x00, nAllocatedSizeIndex);
- printf("reading index... ");
- gettimeofday( &tv, NULL );
- unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
-
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
- m_fTotalDiskAccessTime += fTime;
-
- //nIndexSize = nFileLenIndex / 11;
- int nIndexChainCountRead = nDataRead / sizeof(IndexChain);
- //fclose(fIndex);
- unsigned int nCoveredRainbowTableChains = 0;
- for(int i = 0; i < nIndexChainCountRead; i++)
- {
- nCoveredRainbowTableChains += pIndex[i].nChainCount;
- }
-
- //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);
- RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);
- #ifdef _WIN32
- if (debug) printf("Debug: Allocated %I64u bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);
- #else
- if (debug) printf("Debug: Allocated %llu bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);
- #endif
-
- if (pChain != NULL && nAllocatedSize > 0)
- {
- nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
-
- //fseek(file, 0, SEEK_SET);
- //bool fVerified = false;
- UINT4 nProcessedChains = 0;
- while ( (unsigned long)ftell(file) != nFileLen
- && nProcessedChains < nCoveredRainbowTableChains ) // Chunk read loop
- {
- // Load table chunk
- if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");
- memset(pChain, 0x00, nAllocatedSize);
- printf("reading table... ");
- gettimeofday( &tv, NULL );
- unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
-
- float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
- m_fTotalDiskAccessTime += fTime;
- int nRainbowChainCountRead = nDataRead / sizeOfChain;
- // Verify table chunk (Too lazy to implement this)
-
- if (!fVerified)
- {
- printf("verifying the file... ");
-
- // Chain length test
- int nIndexToVerify = nRainbowChainCountRead / 2;
- CChainWalkContext cwc;
- uint64 nIndexS;
- nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
-
- //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());
- cwc.SetIndex(nIndexS);
-
- int nPos;
- for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
- {
- cwc.IndexToPlain();
- cwc.PlainToHash();
- cwc.HashToIndex(nPos);
- }
-
- uint64 nEndPoint = 0;
-
- //for(int i = 0; i < nIndexSize; i++)
- for(int i = 0; i < nIndexChainCountRead; i++)
- {
- if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index
- { // Now we need to seek nIndexToVerify into the chains
- nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes
- //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());
- //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);
- //printf("nChainCount: %d\n", pIndex[i].nChainCount);
- nEndPoint += pChain[nIndexToVerify].nIndexE;
- break;
- }
- }
-
- if (cwc.GetIndex() != nEndPoint)
- {
- printf("rainbow chain length verify fail\n");
- break;
- }
-
- fVerified = true;
- printf("ok\n");
- }
-
- // Search table chunk
- gettimeofday( &tv, NULL );
- float preTime = m_fTotalCryptanalysisTime;
-
- SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);
- float postTime = m_fTotalCryptanalysisTime;
- gettimeofday( &tv2, NULL );
- final = sub_timeofday( tv2, tv );
-
- fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
- printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);
- m_fTotalCryptanalysisTime += fTime;
- nProcessedChains += nRainbowChainCountRead;
- // Already finished?
- if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
- break;
- }
- }
- else printf("memory allocation failed for rainbow table\n");
-
- //delete pChain;
- }
- }
- else printf("memory allocation failed for index\n");
- }
- }
- else
- {
- printf("Can't load index\n");
- return;
- }
- fclose(fIndex);
-
- //delete pIndex;
- }
- }
- fclose(file);
-
- if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());
- FILE* file = fopen(sProgressPathName.c_str(), "a");
- if (file!=NULL)
- {
- string buffer = sPathName + "\n";
- fputs (buffer.c_str(), file);
- fclose (file);
- }
- }
- else
- printf("can't open file\n");
-}
-
-void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)
-{
-#ifndef _WIN32
- tty_init();
-#endif
- resumeSession = resume;
- debug = bDebug;
-
- maxThreads = i_maxThreads;
- maxMem = i_maxMem;
- // Reset statistics
- ResetStatistics();
-
- // Sort vPathName (CChainWalkSet need it)
- UINT4 i, j;
- for (i = 0; i < vPathName.size() - 1; i++)
- for (j = 0; j < vPathName.size() - i - 1; j++)
- {
- if (vPathName[j] > vPathName[j + 1])
- {
- string sTemp;
- sTemp = vPathName[j];
- vPathName[j] = vPathName[j + 1];
- vPathName[j + 1] = sTemp;
- }
- }
-
- // Run
- for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)
- {
- SearchRainbowTable(vPathName[i], hs);
- printf("\n");
- }
-
- // delete precalc files
- if (!keepPrecalcFiles)
- m_cws.removePrecalcFiles();
-
-#ifndef _WIN32
- tty_done();
-#endif
-}
-
-void CCrackEngine::setOutputFile(string sPathName)
-{
- writeOutput = true;
- outputFile = sPathName;
-}
-
-void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)
-{
- sSessionPathName = sSession;
- sProgressPathName = sProgress;
- sPrecalcPathName = sPrecalc;
- keepPrecalcFiles = keepPrecalc;
-}
-
-float CCrackEngine::GetStatTotalDiskAccessTime()
-{
- return m_fTotalDiskAccessTime;
-}
-/*float CCrackEngine::GetWastedTime()
-{
- return m_fIndexTime;
-}*/
-float CCrackEngine::GetStatTotalCryptanalysisTime()
-{
- return m_fTotalCryptanalysisTime;
-}
-
-float CCrackEngine::GetStatTotalPrecalculationTime()
-{
- return m_fTotalPrecalculationTime;
-}
-
-int CCrackEngine::GetStatTotalChainWalkStep()
-{
- return m_nTotalChainWalkStep;
-}
-
-int CCrackEngine::GetStatTotalFalseAlarm()
-{
- return m_nTotalFalseAlarm;
-}
-
-int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()
-{
- return m_nTotalChainWalkStepDueToFalseAlarm;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright 2009, 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010, 2011 James Nobis <frt@quelrod.net>\r
+ * Copyright 2010 uroskn\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt. If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+ #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "CrackEngine.h"\r
+#include "RTI2Reader.h"\r
+\r
+#ifndef _WIN32\r
+ #include <sys/resource.h>\r
+#endif\r
+\r
+CCrackEngine::CCrackEngine()\r
+{\r
+ ResetStatistics();\r
+ writeOutput = false;\r
+ resumeSession = false;\r
+ debug = false;\r
+ keepPrecalcFiles = false;\r
+\r
+ sSessionPathName = "";\r
+ sProgressPathName = "";\r
+}\r
+\r
+CCrackEngine::~CCrackEngine()\r
+{\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+void CCrackEngine::ResetStatistics()\r
+{\r
+ m_fTotalDiskAccessTime = 0.0f;\r
+ m_fTotalCryptanalysisTime = 0.0f;\r
+ m_fTotalPrecalculationTime = 0.0f;\r
+ m_nTotalChainWalkStep = 0;\r
+ m_nTotalFalseAlarm = 0;\r
+ m_nTotalChainWalkStepDueToFalseAlarm = 0;\r
+// m_nTotalFalseAlarmSkipped = 0;\r
+}\r
+\r
+int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)\r
+{\r
+ int nLow = 0;\r
+ int nHigh = nRainbowChainCount - 1;\r
+ while (nLow <= nHigh)\r
+ {\r
+ int nMid = (nLow + nHigh) / 2;\r
+ if (nIndex == pChain[nMid].nIndexE)\r
+ return nMid;\r
+ else if (nIndex < pChain[nMid].nIndexE)\r
+ nHigh = nMid - 1;\r
+ else\r
+ nLow = nMid + 1;\r
+ }\r
+\r
+ return -1;\r
+}\r
+\r
+RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)\r
+{\r
+ uint64 nPrefix = nIndex >> 16;\r
+ int nLow, nHigh; \r
+ bool found = false;\r
+ //int nChains = 0;\r
+ \r
+ if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file\r
+ {\r
+ return NULL;\r
+ }\r
+\r
+ int nBLow = 0;\r
+ int nBHigh = nIndexSize - 1;\r
+ while (nBLow <= nBHigh)\r
+ {\r
+ int nBMid = (nBLow + nBHigh) / 2;\r
+ if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
+ {\r
+ //nLow = nChains;\r
+ //int nChains = 0;\r
+\r
+ nLow = pIndex[nBMid].nFirstChain;\r
+ nHigh = nLow + pIndex[nBMid].nChainCount;\r
+ if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead) \r
+ { \r
+ if(nHigh > nIndexStart + nChainCountRead)\r
+ nHigh = nIndexStart + nChainCountRead;\r
+ }\r
+ else if(nLow < nIndexStart && nHigh >= nIndexStart)\r
+ {\r
+ nLow = nIndexStart;\r
+ }\r
+ else break; \r
+ found = true;\r
+ break;\r
+ }\r
+ else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
+ nBHigh = nBMid - 1;\r
+ else\r
+ nBLow = nBMid + 1;\r
+ }\r
+ if(found == true)\r
+ {\r
+ for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)\r
+ {\r
+ int nSIndex = ((int)nIndex) & 0x0000FFFF;\r
+\r
+ if (nSIndex == pChain[i].nIndexE)\r
+ {\r
+ return &pChain[i];\r
+ } \r
+ else if(pChain[i].nIndexE > nSIndex)\r
+ break;\r
+ }\r
+ } \r
+ return NULL;\r
+}\r
+\r
+// not used currently, leaving code for future checkpoints\r
+//bool CCrackEngine::CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)\r
+//{\r
+// CChainWalkContext cwc;\r
+// //uint64 nIndexS = pChain->nIndexS >> 16;\r
+// uint64 nIndexS = pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes\r
+// cwc.SetIndex(nIndexS);\r
+// int nPos;\r
+// for (nPos = 0; nPos < nGuessedPos; nPos++)\r
+// {\r
+// cwc.IndexToPlain();\r
+// cwc.PlainToHash();\r
+// cwc.HashToIndex(nPos);\r
+// // Not using checkpoints atm\r
+// /*\r
+// switch(nPos)\r
+// {\r
+// case 5000:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)\r
+// {\r
+// m_nTotalFalseAlarmSkipped += 10000 - 5000;\r
+//// printf("CheckPoint caught false alarm at position 7600\n");\r
+// return false;\r
+// }\r
+// break;\r
+// case 6000:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)\r
+// {\r
+//// printf("CheckPoint caught false alarm at position 8200\n");\r
+// m_nTotalFalseAlarmSkipped += 10000 - 6000;\r
+// return false;\r
+// }\r
+// break;\r
+//\r
+// case 7600:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)\r
+// {\r
+//// printf("CheckPoint caught false alarm at position 8700\n");\r
+// m_nTotalFalseAlarmSkipped += 10000 - 7600;\r
+// return false;\r
+// }\r
+// break;\r
+//\r
+// case 8200:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)\r
+// {\r
+//// printf("CheckPoint caught false alarm at position 9000\n");\r
+// m_nTotalFalseAlarmSkipped += 10000 - 8200;\r
+// return false;\r
+// }\r
+// break;\r
+//\r
+// case 8700:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)\r
+// {\r
+//// printf("CheckPoint caught false alarm at position 9300\n");\r
+// m_nTotalFalseAlarmSkipped += 10000 - 8700;\r
+// return false;\r
+// }\r
+//\r
+// break;\r
+// case 9000:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)\r
+// {\r
+//// printf("CheckPoint caught false alarm at position 9600\n");\r
+// m_nTotalFalseAlarmSkipped += 10000 - 9000;\r
+// return false;\r
+// }\r
+//\r
+// break;\r
+// case 9300:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)\r
+// {\r
+//// printf("CheckPoint caught false alarm at position 9600\n");\r
+// m_nTotalFalseAlarmSkipped += 10000 - 9300;\r
+// return false;\r
+// }\r
+// break;\r
+// case 9600:\r
+// if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))\r
+// {\r
+//// printf("CheckPoint caught false alarm at position 9600\n");\r
+// m_nTotalFalseAlarmSkipped += 10000 - 9600;\r
+// return false;\r
+// }\r
+// break;\r
+//\r
+// }*/\r
+// }\r
+// cwc.IndexToPlain();\r
+// cwc.PlainToHash();\r
+// if (cwc.CheckHash(pHash))\r
+// {\r
+// printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());\r
+// hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());\r
+// return true;\r
+// }\r
+//\r
+// return false;\r
+//}\r
+\r
+//bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)\r
+//{\r
+// CChainWalkContext cwc;\r
+// cwc.SetIndex(pChain->nIndexS);\r
+// int nPos;\r
+// for (nPos = 0; nPos < nGuessedPos; nPos++)\r
+// {\r
+// cwc.IndexToPlain();\r
+// cwc.PlainToHash();\r
+// cwc.HashToIndex(nPos);\r
+// }\r
+// cwc.IndexToPlain();\r
+// cwc.PlainToHash();\r
+// if (cwc.CheckHash(pHash))\r
+// {\r
+// printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());\r
+// hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());\r
+// return true;\r
+// }\r
+//\r
+// return false;\r
+//}\r
+\r
+void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,\r
+ int nRainbowChainCount,\r
+ int nMatchingIndexE,\r
+ int& nMatchingIndexEFrom,\r
+ int& nMatchingIndexETo)\r
+{\r
+ nMatchingIndexEFrom = nMatchingIndexE;\r
+ nMatchingIndexETo = nMatchingIndexE;\r
+ while (nMatchingIndexEFrom > 0)\r
+ {\r
+ if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
+ nMatchingIndexEFrom--;\r
+ else\r
+ break;\r
+ }\r
+ while (nMatchingIndexETo < nRainbowChainCount - 1)\r
+ {\r
+ if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
+ nMatchingIndexETo++;\r
+ else\r
+ break;\r
+ }\r
+}\r
+\r
+void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)\r
+{\r
+ vector<string> vHash;\r
+ hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());\r
+ printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),\r
+ vHash.size() > 1 ? "es" : "");\r
+\r
+ int nChainWalkStep = 0;\r
+ int nFalseAlarm = 0;\r
+ int nChainWalkStepDueToFalseAlarm = 0;\r
+\r
+ vector<rcrackiThread*> threadPool;\r
+ vector<pthread_t> pThreads;\r
+\r
+ #ifndef _WIN32\r
+ /*\r
+ * On linux you cannot set the priority of a thread in the non real time\r
+ * scheduling groups. You can set the priority of the process. In\r
+ * windows BELOW_NORMAL represents a 1/8th drop in priority and this would\r
+ * be 20 * 1/8 on linux or about 2.5\r
+ */\r
+ setpriority( PRIO_PROCESS, 0, 2 );\r
+ #endif\r
+\r
+ pthread_attr_t attr;\r
+ pthread_attr_init(&attr);\r
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
+ #ifdef _WIN32\r
+ sched_param param;\r
+ /*\r
+ * windows scheduling is 0 to 32 (low to high) with 8 as normal and 7 as\r
+ * BELOW_NORMAL\r
+ */\r
+ param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
+ pthread_attr_setschedparam (&attr, ¶m);\r
+ #endif\r
+\r
+ bool pausing = false;\r
+\r
+ uint32 nHashIndex;\r
+ for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
+ {\r
+ #ifdef _WIN32\r
+ if (_kbhit())\r
+ {\r
+ int ch = _getch();\r
+ ch = toupper(ch);\r
+ if (ch == 'P')\r
+ {\r
+ pausing = true;\r
+ printf( "\nPausing, press P again to continue... ");\r
+\r
+ timeval tv;\r
+ timeval tv2;\r
+ timeval final;\r
+ gettimeofday( &tv, NULL );\r
+\r
+ while (pausing)\r
+ {\r
+ if (_kbhit())\r
+ {\r
+ ch = _getch();\r
+ ch = toupper(ch);\r
+ if (ch == 'P')\r
+ {\r
+ printf( " [Continuing]\n");\r
+ pausing = false;\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ m_fTotalCryptanalysisTime -= fTime;\r
+ }\r
+ }\r
+ Sleep(500);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ printf( "\nPress 'P' to pause...\n");\r
+ }\r
+ }\r
+ #else\r
+ int c = tty_getchar();\r
+ if (c >= 0) {\r
+ tty_flush();\r
+ if (c==112) { // = p\r
+ pausing = true;\r
+ printf( "\nPausing, press 'p' again to continue... ");\r
+ \r
+ timeval tv;\r
+ timeval tv2;\r
+ timeval final;\r
+ gettimeofday( &tv, NULL );\r
+ \r
+ while (pausing)\r
+ {\r
+ if ((c = tty_getchar()) >= 0)\r
+ {\r
+ tty_flush();\r
+ if (c == 112)\r
+ {\r
+ printf( " [Continuing]\n");\r
+ pausing = false;\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ m_fTotalCryptanalysisTime -= fTime;\r
+ }\r
+ }\r
+ usleep(500*1000);\r
+ }\r
+ }\r
+ else {\r
+ printf( "\nPress 'p' to pause...\n");\r
+ }\r
+ }\r
+ #endif\r
+ unsigned char TargetHash[MAX_HASH_LEN];\r
+ int nHashLen;\r
+ ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
+ if (nHashLen != CChainWalkContext::GetHashLen())\r
+ printf("debug: nHashLen mismatch\n");\r
+\r
+ // Rqeuest ChainWalk\r
+ bool fNewlyGenerated;\r
+ uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
+ nHashLen,\r
+ CChainWalkContext::GetHashRoutineName(),\r
+ CChainWalkContext::GetPlainCharsetName(),\r
+ CChainWalkContext::GetPlainLenMin(),\r
+ CChainWalkContext::GetPlainLenMax(),\r
+ CChainWalkContext::GetRainbowTableIndex(),\r
+ nRainbowChainLen,\r
+ fNewlyGenerated,\r
+ debug,\r
+ sPrecalcPathName);\r
+ //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",\r
+ // vHash[nHashIndex].c_str());\r
+\r
+ // Walk\r
+ if (fNewlyGenerated)\r
+ {\r
+ timeval tv;\r
+ timeval tv2;\r
+ timeval final;\r
+\r
+ gettimeofday( &tv, NULL );\r
+\r
+ printf("Pre-calculating hash %lu of %lu.%-20s\r",\r
+ (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+ threadPool.clear();\r
+ pThreads.clear();\r
+ \r
+ uint32 thread_ID;\r
+ for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+ {\r
+ rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
+ if (r_Thread)\r
+ {\r
+ pthread_t pThread;\r
+ int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+ }\r
+ else\r
+ {\r
+ pThreads.push_back(pThread);\r
+ }\r
+\r
+ threadPool.push_back(r_Thread);\r
+ }\r
+ else \r
+ {\r
+ printf("r_Thread creation failed!\n");\r
+ }\r
+ }\r
+ \r
+ //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+ \r
+ for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+ {\r
+ pthread_t pThread = pThreads[thread_ID];\r
+ int returnValue = pthread_join(pThread, NULL);\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread join failed, returnValue: %d\n", returnValue);\r
+ }\r
+ \r
+ rcrackiThread* rThread = threadPool[thread_ID];\r
+ nChainWalkStep += rThread->GetChainWalkStep();\r
+ }\r
+\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+ \r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+\r
+ m_fTotalPrecalculationTime += fTime;\r
+ m_fTotalCryptanalysisTime -= fTime;\r
+\r
+ printf("%-50s\r", "");\r
+\r
+ if ( debug )\r
+ printf("pre-calculation time: %.2f s\n", fTime);\r
+ }\r
+\r
+ //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());\r
+ printf("Checking false alarms for hash %lu of %lu.%-20s\r", \r
+ (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+\r
+ threadPool.clear();\r
+ pThreads.clear();\r
+\r
+ int i;\r
+ for (i = 0; i < maxThreads; i++)\r
+ {\r
+ rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);\r
+ threadPool.push_back(r_Thread);\r
+ }\r
+\r
+ uint32 thread_ID = 0;\r
+ int nPos;\r
+ for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
+ {\r
+ uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
+ \r
+ // Search matching nIndexE\r
+ int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);\r
+ if (nMatchingIndexE != -1)\r
+ {\r
+ int nMatchingIndexEFrom, nMatchingIndexETo;\r
+ GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,\r
+ nMatchingIndexE,\r
+ nMatchingIndexEFrom, nMatchingIndexETo);\r
+ int i;\r
+ for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)\r
+ {\r
+ rcrackiThread* rThread = threadPool[thread_ID];\r
+ rThread->AddAlarmCheckO(pChain + i, nPos);\r
+ if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
+ thread_ID++;\r
+ } else {\r
+ thread_ID = 0;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+ {\r
+ rcrackiThread* r_Thread = threadPool[thread_ID];\r
+ pthread_t pThread;\r
+\r
+ int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+ }\r
+ else\r
+ {\r
+ pThreads.push_back(pThread);\r
+ }\r
+ }\r
+ \r
+ //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+\r
+ bool foundHashInThread = false;\r
+ for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+ {\r
+ rcrackiThread* rThread = threadPool[thread_ID];\r
+ pthread_t pThread = pThreads[thread_ID];\r
+\r
+ int returnValue = pthread_join(pThread, NULL);\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread join failed, returnValue: %d\n", returnValue);\r
+ }\r
+\r
+ nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
+ nFalseAlarm += rThread->GetnFalseAlarm();\r
+\r
+ if (rThread->FoundHash() && !foundHashInThread) {\r
+ //printf("\t\t\t\t\t\t\r");\r
+ printf("%-50s\r", "");\r
+\r
+ printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());\r
+ if (writeOutput)\r
+ {\r
+ if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
+ printf("Couldn't write this result to file!\n");\r
+ }\r
+ hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
+\r
+ FILE* file = fopen(sSessionPathName.c_str(), "a");\r
+ if (file!=NULL)\r
+ {\r
+ string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
+ fputs (buffer.c_str(), file);\r
+ fclose (file);\r
+ }\r
+\r
+ m_cws.DiscardWalk(pStartPosIndexE);\r
+ foundHashInThread = true;\r
+ }\r
+ }\r
+\r
+ pThreads.clear();\r
+ threadPool.clear();\r
+ }\r
+\r
+ //printf("\t\t\t\t\t\t\t\r");\r
+ printf("%-50s\r", "");\r
+ pThreads.clear();\r
+ threadPool.clear();\r
+ pthread_attr_destroy(&attr);\r
+\r
+ //printf("debug: chain walk step: %d\n", nChainWalkStep);\r
+ //printf("debug: false alarm: %d\n", nFalseAlarm);\r
+ //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);\r
+\r
+ m_nTotalChainWalkStep += nChainWalkStep;\r
+ m_nTotalFalseAlarm += nFalseAlarm;\r
+ m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
+}\r
+\r
+void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)\r
+{\r
+ vector<string> vHash;\r
+ //vector<uint64 *> vIndices;\r
+ //vector<RainbowChain *> vChains;\r
+ hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());\r
+ printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),\r
+ vHash.size() > 1 ? "es" : "");\r
+\r
+ int nChainWalkStep = 0;\r
+ int nFalseAlarm = 0;\r
+ int nChainWalkStepDueToFalseAlarm = 0;\r
+\r
+ vector<rcrackiThread*> threadPool;\r
+ vector<pthread_t> pThreads;\r
+ \r
+ #ifndef _WIN32\r
+ /*\r
+ * On linux you cannot set the priority of a thread in the non real time\r
+ * scheduling groups. You can set the priority of the process. In\r
+ * windows BELOW_NORMAL represents a 1/8th drop in priority and this would\r
+ * be 20 * 1/8 on linux or about 2.5\r
+ */\r
+ setpriority( PRIO_PROCESS, 0, 2 );\r
+ #endif\r
+\r
+ pthread_attr_t attr;\r
+ pthread_attr_init(&attr);\r
+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
+ #ifdef _WIN32\r
+ sched_param param;\r
+ param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
+ pthread_attr_setschedparam (&attr, ¶m);\r
+ #endif\r
+ // else set it to 5 or something (for linux)?\r
+\r
+ bool pausing = false;\r
+\r
+ uint32 nHashIndex;\r
+ for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
+ {\r
+ #ifdef _WIN32\r
+ if (_kbhit())\r
+ {\r
+ int ch = _getch();\r
+ ch = toupper(ch);\r
+ if (ch == 'P')\r
+ {\r
+ pausing = true;\r
+ printf( "\nPausing, press P again to continue... ");\r
+ \r
+ timeval tv;\r
+ timeval tv2;\r
+ timeval final;\r
+ gettimeofday( &tv, NULL );\r
+\r
+ while (pausing)\r
+ {\r
+ if (_kbhit())\r
+ {\r
+ ch = _getch();\r
+ ch = toupper(ch);\r
+ if (ch == 'P')\r
+ {\r
+ printf( " [Continuing]\n");\r
+ pausing = false;\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ m_fTotalCryptanalysisTime -= fTime;\r
+ }\r
+ }\r
+ Sleep(500);\r
+ }\r
+ }\r
+ else\r
+ {\r
+ printf( "\nPress 'P' to pause...\n");\r
+ }\r
+ }\r
+ #else\r
+ int c = tty_getchar();\r
+ if (c >= 0) {\r
+ tty_flush();\r
+ if (c==112) { // = p\r
+ pausing = true;\r
+ printf( "\nPausing, press 'p' again to continue... ");\r
+\r
+ timeval tv;\r
+ timeval tv2;\r
+ timeval final;\r
+ gettimeofday( &tv, NULL );\r
+\r
+ while (pausing)\r
+ {\r
+ if ((c = tty_getchar()) >= 0)\r
+ {\r
+ tty_flush();\r
+ if (c == 112)\r
+ {\r
+ printf( " [Continuing]\n");\r
+ pausing = false;\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ m_fTotalCryptanalysisTime -= fTime;\r
+ }\r
+ }\r
+ usleep(500*1000);\r
+ }\r
+ }\r
+ else {\r
+ printf( "\nPress 'p' to pause...\n");\r
+ }\r
+ }\r
+ #endif\r
+ unsigned char TargetHash[MAX_HASH_LEN];\r
+ int nHashLen;\r
+ ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
+ if (nHashLen != CChainWalkContext::GetHashLen())\r
+ printf("debug: nHashLen mismatch\n");\r
+\r
+ // Request ChainWalk\r
+ bool fNewlyGenerated;\r
+// printf("Requesting walk...");\r
+ \r
+\r
+ uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
+ nHashLen,\r
+ CChainWalkContext::GetHashRoutineName(),\r
+ CChainWalkContext::GetPlainCharsetName(),\r
+ CChainWalkContext::GetPlainLenMin(),\r
+ CChainWalkContext::GetPlainLenMax(),\r
+ CChainWalkContext::GetRainbowTableIndex(),\r
+ nRainbowChainLen,\r
+ fNewlyGenerated,\r
+ debug,\r
+ sPrecalcPathName);\r
+// printf("done!\n");\r
+// printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",\r
+// vHash[nHashIndex].c_str());\r
+\r
+ if (fNewlyGenerated)\r
+ {\r
+ timeval tv;\r
+ timeval tv2;\r
+ timeval final;\r
+\r
+ gettimeofday( &tv, NULL );\r
+\r
+ printf("Pre-calculating hash %lu of %lu.%-20s\r", \r
+ (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+ threadPool.clear();\r
+ pThreads.clear();\r
+ \r
+ uint32 thread_ID;\r
+ for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+ {\r
+ rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
+ if (r_Thread)\r
+ {\r
+ pthread_t pThread;\r
+ int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+ }\r
+ else\r
+ {\r
+ pThreads.push_back(pThread);\r
+ }\r
+\r
+ threadPool.push_back(r_Thread);\r
+ }\r
+ else \r
+ {\r
+ printf("r_Thread creation failed!\n");\r
+ }\r
+ }\r
+ \r
+ //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+ \r
+ for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+ {\r
+ pthread_t pThread = pThreads[thread_ID];\r
+ int returnValue = pthread_join(pThread, NULL);\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread join failed, returnValue: %d\n", returnValue);\r
+ }\r
+ \r
+ rcrackiThread* rThread = threadPool[thread_ID];\r
+ nChainWalkStep += rThread->GetChainWalkStep();\r
+ delete rThread;\r
+ }\r
+\r
+ m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+ \r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+\r
+ m_fTotalPrecalculationTime += fTime;\r
+ m_fTotalCryptanalysisTime -= fTime;\r
+\r
+ //printf("\npStartPosIndexE[0]: %s\n", uint64tostr(pStartPosIndexE[0]).c_str());\r
+ //printf("\npStartPosIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pStartPosIndexE[nRainbowChainLen-2]).c_str());\r
+\r
+ printf("%-50s\r", "");\r
+\r
+ if ( debug )\r
+ printf("pre-calculation time: %.2f s\n", fTime);\r
+ }\r
+\r
+ threadPool.clear();\r
+ pThreads.clear();\r
+\r
+ //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());\r
+ printf("Checking false alarms for hash %lu of %lu.%-20s\r",\r
+ (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+\r
+ int i;\r
+ for (i = 0; i < maxThreads; i++)\r
+ {\r
+ rcrackiThread* r_Thread = new rcrackiThread(TargetHash);\r
+ threadPool.push_back(r_Thread);\r
+ }\r
+\r
+ uint32 thread_ID = 0;\r
+ int nPos;\r
+ for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
+ {\r
+ uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
+ \r
+ // Search matching nIndexE\r
+ RainbowChain *pChainFound = BinarySearch(pChain, nRainbowChainCount, nIndexEOfCurPos, pIndex, nIndexSize, nChainStart);\r
+ if (pChainFound != NULL) // For perfected indexed tables we only recieve 1 result (huge speed increase!)\r
+ {\r
+ rcrackiThread* rThread = threadPool[thread_ID];\r
+ rThread->AddAlarmCheck(pChainFound, nPos);\r
+ if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
+ thread_ID++;\r
+ } else {\r
+ thread_ID = 0;\r
+ }\r
+ }\r
+ }\r
+\r
+ for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+ {\r
+ rcrackiThread* r_Thread = threadPool[thread_ID];\r
+ pthread_t pThread;\r
+\r
+ int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+ }\r
+ else\r
+ {\r
+ pThreads.push_back(pThread);\r
+ }\r
+ }\r
+ \r
+ //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+\r
+ bool foundHashInThread = false;\r
+ for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+ {\r
+ rcrackiThread* rThread = threadPool[thread_ID];\r
+ pthread_t pThread = pThreads[thread_ID];\r
+\r
+ int returnValue = pthread_join(pThread, NULL);\r
+ if( returnValue != 0 )\r
+ {\r
+ printf("pThread join failed, returnValue: %d\n", returnValue);\r
+ }\r
+\r
+ nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
+ nFalseAlarm += rThread->GetnFalseAlarm();\r
+\r
+ if (rThread->FoundHash() && !foundHashInThread) {\r
+ //printf("\t\t\t\t\t\t\r");\r
+ printf("%-50s\r", "");\r
+ printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());\r
+ if (writeOutput)\r
+ {\r
+ if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
+ printf("Couldn't write this result to file!\n");\r
+ }\r
+ hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
+ \r
+ FILE* file = fopen(sSessionPathName.c_str(), "a");\r
+ if (file!=NULL)\r
+ {\r
+ string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
+ fputs (buffer.c_str(), file);\r
+ fclose (file);\r
+ }\r
+\r
+ m_cws.DiscardWalk(pStartPosIndexE);\r
+ foundHashInThread = true;\r
+ }\r
+ //pthread\r
+ delete rThread;\r
+ }\r
+\r
+ pThreads.clear();\r
+ threadPool.clear();\r
+\r
+ //printf("\t\t\t\t\r");\r
+ //printf("pChainFounds: %d\n", pChainsFound.size());\r
+//NEXT_HASH:;\r
+ }\r
+ //printf("\t\t\t\t\t\t\t\r");\r
+ printf("%-50s\r", "");\r
+ pThreads.clear();\r
+ threadPool.clear();\r
+ pthread_attr_destroy(&attr);\r
+\r
+ //printf("debug: chain walk step: %d\n", nChainWalkStep);\r
+ //printf("debug: false alarm: %d\n", nFalseAlarm);\r
+ //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);\r
+\r
+ m_nTotalChainWalkStep += nChainWalkStep;\r
+ m_nTotalFalseAlarm += nFalseAlarm;\r
+ m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
+}\r
+\r
+void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)\r
+{\r
+ // Did we already go through this file in this session?\r
+ if (resumeSession)\r
+ {\r
+ vector<string> sessionFinishedPathNames;\r
+ if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))\r
+ {\r
+ uint32 i;\r
+ for (i = 0; i < sessionFinishedPathNames.size(); i++)\r
+ {\r
+ if (sessionFinishedPathNames[i] == sPathName)\r
+ {\r
+ printf("Skipping %s\n", sPathName.c_str());\r
+ return;\r
+ }\r
+ }\r
+ }\r
+ }\r
+\r
+ // FileName\r
+#ifdef _WIN32\r
+ string::size_type nIndex = sPathName.find_last_of('\\');\r
+#else\r
+ string::size_type nIndex = sPathName.find_last_of('/');\r
+#endif\r
+ string sFileName;\r
+ if (nIndex != string::npos)\r
+ sFileName = sPathName.substr(nIndex + 1);\r
+ else\r
+ sFileName = sPathName;\r
+\r
+ // Info\r
+ printf("%s:\n", sFileName.c_str());\r
+\r
+ // Setup\r
+ int nRainbowChainLen, nRainbowChainCount;\r
+ if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))\r
+ return;\r
+ //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());\r
+ // Already finished?\r
+ if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
+ {\r
+ printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());\r
+ return;\r
+ }\r
+\r
+ // Open\r
+ FILE* file = fopen(sPathName.c_str(), "rb");\r
+ if (file != NULL)\r
+ {\r
+ // XXX file type detection code needs a serious overhaul\r
+ // File length check\r
+ bool doOldFormat = CChainWalkContext::isOldFormat();\r
+ bool doRti2Format = CChainWalkContext::isRti2Format();\r
+ uint32 sizeOfChain;\r
+ bool fVerified = false;\r
+ long nFileLen = GetFileLen(file);\r
+\r
+ if (doOldFormat)\r
+ sizeOfChain = 16;\r
+ else\r
+ sizeOfChain = 8;\r
+\r
+ if ( ( (unsigned long)nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != (unsigned long)nFileLen) && doRti2Format == false )\r
+ printf("file length mismatch\n");\r
+ else\r
+ {\r
+ fseek(file, 0, SEEK_SET);\r
+ timeval tv;\r
+ timeval tv2;\r
+ timeval final;\r
+\r
+ unsigned int bytesForChainWalkSet = hs.GetStatHashTotal() * (nRainbowChainLen-1) * 8;\r
+ if (debug) printf("Debug: Saving %u bytes of memory for chainwalkset.\n", bytesForChainWalkSet);\r
+\r
+ uint64 nAllocatedSize;\r
+\r
+ if (doRti2Format || doOldFormat)\r
+ {\r
+ RTI2Reader *pReader = NULL;\r
+\r
+ if(doRti2Format)\r
+\r
+ if (debug)\r
+ {\r
+ if ( doOldFormat )\r
+ printf("Debug: This is a table in the old .rt format.\n");\r
+ else if ( doRti2Format )\r
+ printf("Debug: This is a table in the .rti2 format.\n");\r
+ }\r
+\r
+ static CMemoryPool mp(bytesForChainWalkSet, debug, maxMem);\r
+ RainbowChainO* pChain = NULL;\r
+ if(doRti2Format)\r
+ pChain = (RainbowChainO*)mp.Allocate(pReader->GetChainsLeft() * 16, nAllocatedSize);\r
+ else\r
+ pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);\r
+\r
+ #if defined(_WIN32) && !defined(__GNUC__)\r
+ if (debug) printf("Allocated %I64 bytes, filelen %ld\n", nAllocatedSize, nFileLen);\r
+ #else\r
+ if (debug) printf("Allocated %llu bytes, filelen %ld\n", nAllocatedSize, nFileLen);\r
+ #endif\r
+\r
+ if (pChain != NULL)\r
+ {\r
+ nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary\r
+\r
+ //fseek(file, 0, SEEK_SET);\r
+ //bool fVerified = false;\r
+ while (true) // Chunk read loop\r
+ {\r
+ if (ftell(file) == nFileLen)\r
+ break;\r
+\r
+ // Load table chunk\r
+ if (debug) printf("reading...\n");\r
+ unsigned int nDataRead = 0;\r
+ gettimeofday( &tv, NULL );\r
+ if ( doRti2Format )\r
+ {\r
+ nDataRead = nAllocatedSize / 16;\r
+ if(pReader->GetChainsLeft() <= 0) // No more data\r
+ break; \r
+ pReader->ReadChains(nDataRead, pChain);\r
+\r
+ nDataRead *= 8; // Convert from chains read to bytes\r
+ }\r
+ else\r
+ {\r
+ nDataRead = fread(pChain, 1, nAllocatedSize, file);\r
+ }\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+\r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
+ m_fTotalDiskAccessTime += fTime;\r
+\r
+ int nRainbowChainCountRead;\r
+\r
+ if(doRti2Format)\r
+ nRainbowChainCountRead = nDataRead / 8;\r
+ else\r
+ nRainbowChainCountRead = nDataRead / 16;\r
+\r
+ // Verify table chunk\r
+ if (!fVerified)\r
+ {\r
+ printf("verifying the file...\n");\r
+\r
+ // Chain length test\r
+ int nIndexToVerify = nRainbowChainCountRead / 2;\r
+ CChainWalkContext cwc;\r
+ cwc.SetIndex(pChain[nIndexToVerify].nIndexS);\r
+ int nPos;\r
+ for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
+ {\r
+ cwc.IndexToPlain();\r
+ cwc.PlainToHash();\r
+ cwc.HashToIndex(nPos);\r
+ }\r
+ if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)\r
+ {\r
+ printf("rainbow chain length verify fail\n");\r
+ break;\r
+ }\r
+\r
+ // Chain sort test\r
+ int i;\r
+ for (i = 0; i < nRainbowChainCountRead - 1; i++)\r
+ {\r
+ if (pChain[i].nIndexE > pChain[i + 1].nIndexE)\r
+ break;\r
+ }\r
+ if (i != nRainbowChainCountRead - 1)\r
+ {\r
+ printf("this file is not sorted\n");\r
+ break;\r
+ }\r
+\r
+ fVerified = true;\r
+ }\r
+\r
+ // Search table chunk\r
+ gettimeofday( &tv, NULL );\r
+ SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+ fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ printf("cryptanalysis time: %.2f s\n", fTime);\r
+ m_fTotalCryptanalysisTime += fTime;\r
+\r
+ // Already finished?\r
+ if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
+ break;\r
+\r
+/*\r
+ // XXX eliminated by PB - check correctness\r
+ // finished the current table\r
+ if( doRti2Format && nDataToRead > (nDataRead / 8) )\r
+ {\r
+ delete pReader;\r
+ break;\r
+ }\r
+*/\r
+ }\r
+ }\r
+ else\r
+ printf("memory allocation fail\n");\r
+ \r
+ //delete pChain;\r
+ }\r
+ else\r
+ {\r
+ static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);\r
+ uint64 nAllocatedSizeIndex;\r
+\r
+ //int nIndexSize = 0;\r
+ //IndexChain *pIndex = NULL;\r
+\r
+ FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");\r
+ if(fIndex != NULL)\r
+ {\r
+ // File length check\r
+ long nFileLenIndex = GetFileLen(fIndex);\r
+ //unsigned int nRows = nFileLenIndex / 11;\r
+ //unsigned int nSize = nRows * sizeof(IndexChain);\r
+ //printf("Debug: 8\n");\r
+ if (nFileLenIndex % 11 != 0)\r
+ printf("index file length mismatch (%ld bytes)\n", nFileLenIndex);\r
+ else\r
+ {\r
+ //printf("index nSize: %d\n", nSize);\r
+ //pIndex = (IndexChain*)new unsigned char[nSize];\r
+ IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);\r
+ #ifdef _WIN32\r
+ if (debug) printf("Debug: Allocated %I64u bytes for index with filelen %ld\n", nAllocatedSizeIndex, nFileLenIndex);\r
+ #else\r
+ if (debug) printf("Debug: Allocated %llu bytes for index with filelen %ld\n", nAllocatedSizeIndex, nFileLenIndex);\r
+ #endif\r
+ \r
+ static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);\r
+ \r
+ if (pIndex != NULL && nAllocatedSizeIndex > 0)\r
+ {\r
+ nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain); // Round to sizeOfIndexChain boundary\r
+ \r
+ fseek(fIndex, 0, SEEK_SET);\r
+\r
+ while ( ftell(fIndex) != nFileLenIndex ) // Index chunk read loop\r
+ {\r
+ // Load index chunk\r
+#ifdef _WIN32\r
+ if (debug) printf("Debug: Setting index to 0x00 in memory, %I64u bytes\n", nAllocatedSizeIndex);\r
+#else\r
+ if (debug) printf("Debug: Setting index to 0x00 in memory, %llu bytes\n", nAllocatedSizeIndex);\r
+#endif\r
+ memset(pIndex, 0x00, nAllocatedSizeIndex);\r
+ printf("reading index... ");\r
+ gettimeofday( &tv, NULL );\r
+ unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+\r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
+ m_fTotalDiskAccessTime += fTime;\r
+ \r
+ //nIndexSize = nFileLenIndex / 11;\r
+ int nIndexChainCountRead = nDataRead / sizeof(IndexChain);\r
+ //fclose(fIndex);\r
+ unsigned int nCoveredRainbowTableChains = 0;\r
+ for(int i = 0; i < nIndexChainCountRead; i++)\r
+ {\r
+ nCoveredRainbowTableChains += pIndex[i].nChainCount;\r
+ }\r
+\r
+ //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);\r
+ RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);\r
+ #ifdef _WIN32\r
+ if (debug) printf("Debug: Allocated %I64u bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);\r
+ #else\r
+ if (debug) printf("Debug: Allocated %llu bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);\r
+ #endif\r
+\r
+ if (pChain != NULL && nAllocatedSize > 0)\r
+ {\r
+ nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary\r
+\r
+ //bool fVerified = false;\r
+ uint32 nProcessedChains = 0;\r
+ while ( ftell(file) != nFileLen \r
+ && nProcessedChains < nCoveredRainbowTableChains ) // Chunk read loop\r
+ {\r
+ // Load table chunk\r
+ if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");\r
+ memset(pChain, 0x00, nAllocatedSize);\r
+ printf("reading table... ");\r
+ gettimeofday( &tv, NULL );\r
+ unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+\r
+ float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
+ m_fTotalDiskAccessTime += fTime;\r
+ int nRainbowChainCountRead = nDataRead / sizeOfChain;\r
+ // Verify table chunk (Too lazy to implement this)\r
+ \r
+ if (!fVerified)\r
+ {\r
+ printf("verifying the file... ");\r
+\r
+ // Chain length test\r
+ int nIndexToVerify = nRainbowChainCountRead / 2;\r
+ CChainWalkContext cwc;\r
+ uint64 nIndexS;\r
+ nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes\r
+\r
+ //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());\r
+ cwc.SetIndex(nIndexS);\r
+ \r
+ int nPos;\r
+ for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
+ {\r
+ cwc.IndexToPlain();\r
+ cwc.PlainToHash();\r
+ cwc.HashToIndex(nPos);\r
+ }\r
+\r
+ uint64 nEndPoint = 0;\r
+\r
+ //for(int i = 0; i < nIndexSize; i++)\r
+ for(int i = 0; i < nIndexChainCountRead; i++)\r
+ {\r
+ if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index\r
+ { // Now we need to seek nIndexToVerify into the chains\r
+ nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes\r
+ //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());\r
+ //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);\r
+ //printf("nChainCount: %d\n", pIndex[i].nChainCount);\r
+ nEndPoint += pChain[nIndexToVerify].nIndexE;\r
+ break;\r
+ }\r
+ }\r
+\r
+ if (cwc.GetIndex() != nEndPoint)\r
+ {\r
+ printf("rainbow chain length verify fail\n");\r
+ break;\r
+ }\r
+\r
+ fVerified = true;\r
+ printf("ok\n");\r
+ }\r
+\r
+ // Search table chunk\r
+ gettimeofday( &tv, NULL );\r
+ float preTime = m_fTotalCryptanalysisTime;\r
+\r
+ SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);\r
+ float postTime = m_fTotalCryptanalysisTime;\r
+ gettimeofday( &tv2, NULL );\r
+ final = sub_timeofday( tv2, tv );\r
+\r
+ fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+ printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);\r
+ m_fTotalCryptanalysisTime += fTime;\r
+ nProcessedChains += nRainbowChainCountRead;\r
+ // Already finished?\r
+ if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
+ break;\r
+ }\r
+ }\r
+ else printf("memory allocation failed for rainbow table\n");\r
+\r
+ //delete pChain;\r
+ }\r
+ }\r
+ else printf("memory allocation failed for index\n");\r
+ } \r
+ }\r
+ else \r
+ {\r
+ printf("Can't load index\n");\r
+ return;\r
+ }\r
+ fclose(fIndex);\r
+ \r
+ //delete pIndex;\r
+ }\r
+ }\r
+ fclose(file);\r
+\r
+ if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());\r
+ FILE* file = fopen(sProgressPathName.c_str(), "a");\r
+ if (file!=NULL)\r
+ {\r
+ string buffer = sPathName + "\n";\r
+ fputs (buffer.c_str(), file);\r
+ fclose (file);\r
+ }\r
+ }\r
+ else\r
+ printf("can't open file\n");\r
+}\r
+\r
+void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)\r
+{\r
+#ifndef _WIN32\r
+ tty_init();\r
+#endif\r
+ resumeSession = resume;\r
+ debug = bDebug;\r
+\r
+ maxThreads = i_maxThreads;\r
+ maxMem = i_maxMem;\r
+ // Reset statistics\r
+ ResetStatistics();\r
+\r
+ // XXX it's not like the STL has a sort method...\r
+ // Sort vPathName (CChainWalkSet need it)\r
+ uint32 i, j;\r
+ for (i = 0; i < vPathName.size() - 1; i++)\r
+ for (j = 0; j < vPathName.size() - i - 1; j++)\r
+ {\r
+ if (vPathName[j] > vPathName[j + 1])\r
+ {\r
+ string sTemp;\r
+ sTemp = vPathName[j];\r
+ vPathName[j] = vPathName[j + 1];\r
+ vPathName[j + 1] = sTemp;\r
+ }\r
+ }\r
+\r
+ // Run\r
+ for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)\r
+ {\r
+ SearchRainbowTable(vPathName[i], hs);\r
+ printf("\n");\r
+ }\r
+\r
+ // delete precalc files\r
+ if (!keepPrecalcFiles)\r
+ m_cws.removePrecalcFiles();\r
+\r
+#ifndef _WIN32\r
+ tty_done();\r
+#endif\r
+}\r
+\r
+void CCrackEngine::setOutputFile(string sPathName)\r
+{\r
+ writeOutput = true;\r
+ outputFile = sPathName;\r
+}\r
+\r
+void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)\r
+{\r
+ sSessionPathName = sSession;\r
+ sProgressPathName = sProgress;\r
+ sPrecalcPathName = sPrecalc;\r
+ keepPrecalcFiles = keepPrecalc;\r
+}\r
+\r
+float CCrackEngine::GetStatTotalDiskAccessTime()\r
+{\r
+ return m_fTotalDiskAccessTime;\r
+}\r
+/*float CCrackEngine::GetWastedTime()\r
+{\r
+ return m_fIndexTime;\r
+}*/\r
+float CCrackEngine::GetStatTotalCryptanalysisTime()\r
+{\r
+ return m_fTotalCryptanalysisTime;\r
+}\r
+\r
+float CCrackEngine::GetStatTotalPrecalculationTime()\r
+{\r
+ return m_fTotalPrecalculationTime;\r
+}\r
+\r
+uint64 CCrackEngine::GetStatTotalChainWalkStep()\r
+{\r
+ return m_nTotalChainWalkStep;\r
+}\r
+\r
+int CCrackEngine::GetStatTotalFalseAlarm()\r
+{\r
+ return m_nTotalFalseAlarm;\r
+}\r
+\r
+uint64 CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()\r
+{\r
+ return m_nTotalChainWalkStepDueToFalseAlarm;\r
+}\r