2 * rcracki_mt is a multithreaded implementation and fork of the original
\r
5 * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
\r
6 * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
\r
7 * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
\r
8 * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
\r
9 * Copyright 2010 uroskn
\r
11 * This file is part of racrcki_mt.
\r
13 * rcracki_mt is free software: you can redistribute it and/or modify
\r
14 * it under the terms of the GNU General Public License as published by
\r
15 * the Free Software Foundation, either version 2 of the License, or
\r
16 * (at your option) any later version.
\r
18 * rcracki_mt is distributed in the hope that it will be useful,
\r
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
21 * GNU General Public License for more details.
\r
23 * You should have received a copy of the GNU General Public License
\r
24 * along with rcracki_mt. If not, see <http://www.gnu.org/licenses/>.
\r
28 #pragma warning(disable : 4786 4267 4018)
\r
31 #include "CrackEngine.h"
\r
32 #include "RTI2Reader.h"
\r
34 CCrackEngine::CCrackEngine()
\r
37 writeOutput = false;
\r
38 resumeSession = false;
\r
40 keepPrecalcFiles = false;
\r
42 sSessionPathName = "";
\r
43 sProgressPathName = "";
\r
46 CCrackEngine::~CCrackEngine()
\r
50 //////////////////////////////////////////////////////////////////////
\r
52 void CCrackEngine::ResetStatistics()
\r
54 m_fTotalDiskAccessTime = 0.0f;
\r
55 m_fTotalCryptanalysisTime = 0.0f;
\r
56 m_fTotalPrecalculationTime = 0.0f;
\r
57 m_nTotalChainWalkStep = 0;
\r
58 m_nTotalFalseAlarm = 0;
\r
59 m_nTotalChainWalkStepDueToFalseAlarm = 0;
\r
60 // m_nTotalFalseAlarmSkipped = 0;
\r
63 int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)
\r
66 int nHigh = nRainbowChainCount - 1;
\r
67 while (nLow <= nHigh)
\r
69 int nMid = (nLow + nHigh) / 2;
\r
70 if (nIndex == pChain[nMid].nIndexE)
\r
72 else if (nIndex < pChain[nMid].nIndexE)
\r
81 RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)
\r
83 uint64 nPrefix = nIndex >> 16;
\r
88 if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file
\r
94 int nBHigh = nIndexSize - 1;
\r
95 while (nBLow <= nBHigh)
\r
97 int nBMid = (nBLow + nBHigh) / 2;
\r
98 if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
\r
103 nLow = pIndex[nBMid].nFirstChain;
\r
104 nHigh = nLow + pIndex[nBMid].nChainCount;
\r
105 if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead)
\r
107 if(nHigh > nIndexStart + nChainCountRead)
\r
108 nHigh = nIndexStart + nChainCountRead;
\r
110 else if(nLow < nIndexStart && nHigh >= nIndexStart)
\r
112 nLow = nIndexStart;
\r
118 else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
\r
119 nBHigh = nBMid - 1;
\r
125 for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)
\r
127 int nSIndex = ((int)nIndex) & 0x0000FFFF;
\r
129 if (nSIndex == pChain[i].nIndexE)
\r
133 else if(pChain[i].nIndexE > nSIndex)
\r
140 // not used currently, leaving code for future checkpoints
\r
141 //bool CCrackEngine::CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
\r
143 // CChainWalkContext cwc;
\r
144 // //uint64 nIndexS = pChain->nIndexS >> 16;
\r
145 // uint64 nIndexS = pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
\r
146 // cwc.SetIndex(nIndexS);
\r
148 // for (nPos = 0; nPos < nGuessedPos; nPos++)
\r
150 // cwc.IndexToPlain();
\r
151 // cwc.PlainToHash();
\r
152 // cwc.HashToIndex(nPos);
\r
153 // // Not using checkpoints atm
\r
158 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)
\r
160 // m_nTotalFalseAlarmSkipped += 10000 - 5000;
\r
161 //// printf("CheckPoint caught false alarm at position 7600\n");
\r
166 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)
\r
168 //// printf("CheckPoint caught false alarm at position 8200\n");
\r
169 // m_nTotalFalseAlarmSkipped += 10000 - 6000;
\r
175 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)
\r
177 //// printf("CheckPoint caught false alarm at position 8700\n");
\r
178 // m_nTotalFalseAlarmSkipped += 10000 - 7600;
\r
184 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)
\r
186 //// printf("CheckPoint caught false alarm at position 9000\n");
\r
187 // m_nTotalFalseAlarmSkipped += 10000 - 8200;
\r
193 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)
\r
195 //// printf("CheckPoint caught false alarm at position 9300\n");
\r
196 // m_nTotalFalseAlarmSkipped += 10000 - 8700;
\r
202 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)
\r
204 //// printf("CheckPoint caught false alarm at position 9600\n");
\r
205 // m_nTotalFalseAlarmSkipped += 10000 - 9000;
\r
211 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)
\r
213 //// printf("CheckPoint caught false alarm at position 9600\n");
\r
214 // m_nTotalFalseAlarmSkipped += 10000 - 9300;
\r
219 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))
\r
221 //// printf("CheckPoint caught false alarm at position 9600\n");
\r
222 // m_nTotalFalseAlarmSkipped += 10000 - 9600;
\r
229 // cwc.IndexToPlain();
\r
230 // cwc.PlainToHash();
\r
231 // if (cwc.CheckHash(pHash))
\r
233 // printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
\r
234 // hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
\r
241 //bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
\r
243 // CChainWalkContext cwc;
\r
244 // cwc.SetIndex(pChain->nIndexS);
\r
246 // for (nPos = 0; nPos < nGuessedPos; nPos++)
\r
248 // cwc.IndexToPlain();
\r
249 // cwc.PlainToHash();
\r
250 // cwc.HashToIndex(nPos);
\r
252 // cwc.IndexToPlain();
\r
253 // cwc.PlainToHash();
\r
254 // if (cwc.CheckHash(pHash))
\r
256 // printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
\r
257 // hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
\r
264 void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,
\r
265 int nRainbowChainCount,
\r
266 int nMatchingIndexE,
\r
267 int& nMatchingIndexEFrom,
\r
268 int& nMatchingIndexETo)
\r
270 nMatchingIndexEFrom = nMatchingIndexE;
\r
271 nMatchingIndexETo = nMatchingIndexE;
\r
272 while (nMatchingIndexEFrom > 0)
\r
274 if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
\r
275 nMatchingIndexEFrom--;
\r
279 while (nMatchingIndexETo < nRainbowChainCount - 1)
\r
281 if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
\r
282 nMatchingIndexETo++;
\r
288 void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)
\r
290 vector<string> vHash;
\r
291 hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
\r
292 printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
\r
293 vHash.size() > 1 ? "es" : "");
\r
295 int nChainWalkStep = 0;
\r
296 int nFalseAlarm = 0;
\r
297 int nChainWalkStepDueToFalseAlarm = 0;
\r
299 vector<rcrackiThread*> threadPool;
\r
300 vector<pthread_t> pThreads;
\r
302 pthread_attr_t attr;
\r
303 pthread_attr_init(&attr);
\r
304 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
\r
307 param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
\r
308 pthread_attr_setschedparam (&attr, ¶m);
\r
310 // XXX else set it to 5 or something (for linux)?
\r
312 bool pausing = false;
\r
315 for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
\r
325 printf( "\nPausing, press P again to continue... ");
\r
330 gettimeofday( &tv, NULL );
\r
340 printf( " [Continuing]\n");
\r
342 gettimeofday( &tv2, NULL );
\r
343 final = sub_timeofday( tv2, tv );
\r
344 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
345 m_fTotalCryptanalysisTime -= fTime;
\r
353 printf( "\nPress 'P' to pause...\n");
\r
357 int c = tty_getchar();
\r
360 if (c==112) { // = p
\r
362 printf( "\nPausing, press 'p' again to continue... ");
\r
367 gettimeofday( &tv, NULL );
\r
371 if ((c = tty_getchar()) >= 0)
\r
376 printf( " [Continuing]\n");
\r
378 gettimeofday( &tv2, NULL );
\r
379 final = sub_timeofday( tv2, tv );
\r
380 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
381 m_fTotalCryptanalysisTime -= fTime;
\r
388 printf( "\nPress 'p' to pause...\n");
\r
392 unsigned char TargetHash[MAX_HASH_LEN];
\r
394 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
\r
395 if (nHashLen != CChainWalkContext::GetHashLen())
\r
396 printf("debug: nHashLen mismatch\n");
\r
398 // Rqeuest ChainWalk
\r
399 bool fNewlyGenerated;
\r
400 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
\r
402 CChainWalkContext::GetHashRoutineName(),
\r
403 CChainWalkContext::GetPlainCharsetName(),
\r
404 CChainWalkContext::GetPlainLenMin(),
\r
405 CChainWalkContext::GetPlainLenMax(),
\r
406 CChainWalkContext::GetRainbowTableIndex(),
\r
411 //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
\r
412 // vHash[nHashIndex].c_str());
\r
415 if (fNewlyGenerated)
\r
421 gettimeofday( &tv, NULL );
\r
423 printf("Pre-calculating hash %lu of %lu.%-20s\r",
\r
424 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
425 threadPool.clear();
\r
429 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
431 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
\r
435 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
437 if( returnValue != 0 )
\r
439 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
443 pThreads.push_back(pThread);
\r
446 threadPool.push_back(r_Thread);
\r
450 printf("r_Thread creation failed!\n");
\r
454 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
456 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
458 pthread_t pThread = pThreads[thread_ID];
\r
459 int returnValue = pthread_join(pThread, NULL);
\r
460 if( returnValue != 0 )
\r
462 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
465 rcrackiThread* rThread = threadPool[thread_ID];
\r
466 nChainWalkStep += rThread->GetChainWalkStep();
\r
469 gettimeofday( &tv2, NULL );
\r
470 final = sub_timeofday( tv2, tv );
\r
472 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
474 m_fTotalPrecalculationTime += fTime;
\r
475 m_fTotalCryptanalysisTime -= fTime;
\r
477 printf("%-50s\r", "");
\r
480 printf("pre-calculation time: %.2f s\n", fTime);
\r
483 //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
\r
484 printf("Checking false alarms for hash %lu of %lu.%-20s\r",
\r
485 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
487 threadPool.clear();
\r
491 for (i = 0; i < maxThreads; i++)
\r
493 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);
\r
494 threadPool.push_back(r_Thread);
\r
497 UINT4 thread_ID = 0;
\r
499 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
\r
501 uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
\r
503 // Search matching nIndexE
\r
504 int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);
\r
505 if (nMatchingIndexE != -1)
\r
507 int nMatchingIndexEFrom, nMatchingIndexETo;
\r
508 GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,
\r
510 nMatchingIndexEFrom, nMatchingIndexETo);
\r
512 for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)
\r
514 rcrackiThread* rThread = threadPool[thread_ID];
\r
515 rThread->AddAlarmCheckO(pChain + i, nPos);
\r
516 if (thread_ID < (unsigned long)maxThreads - 1 ) {
\r
525 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
527 rcrackiThread* r_Thread = threadPool[thread_ID];
\r
530 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
532 if( returnValue != 0 )
\r
534 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
538 pThreads.push_back(pThread);
\r
542 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
544 bool foundHashInThread = false;
\r
545 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
547 rcrackiThread* rThread = threadPool[thread_ID];
\r
548 pthread_t pThread = pThreads[thread_ID];
\r
550 int returnValue = pthread_join(pThread, NULL);
\r
551 if( returnValue != 0 )
\r
553 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
556 nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
\r
557 nFalseAlarm += rThread->GetnFalseAlarm();
\r
559 if (rThread->FoundHash() && !foundHashInThread) {
\r
560 //printf("\t\t\t\t\t\t\r");
\r
561 printf("%-50s\r", "");
\r
563 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
\r
566 if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
\r
567 printf("Couldn't write this result to file!\n");
\r
569 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
\r
571 FILE* file = fopen(sSessionPathName.c_str(), "a");
\r
574 string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
\r
575 fputs (buffer.c_str(), file);
\r
579 m_cws.DiscardWalk(pStartPosIndexE);
\r
580 foundHashInThread = true;
\r
585 threadPool.clear();
\r
588 //printf("\t\t\t\t\t\t\t\r");
\r
589 printf("%-50s\r", "");
\r
591 threadPool.clear();
\r
592 pthread_attr_destroy(&attr);
\r
594 //printf("debug: chain walk step: %d\n", nChainWalkStep);
\r
595 //printf("debug: false alarm: %d\n", nFalseAlarm);
\r
596 //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
\r
598 m_nTotalChainWalkStep += nChainWalkStep;
\r
599 m_nTotalFalseAlarm += nFalseAlarm;
\r
600 m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
\r
603 void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)
\r
605 vector<string> vHash;
\r
606 //vector<uint64 *> vIndices;
\r
607 //vector<RainbowChain *> vChains;
\r
608 hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
\r
609 printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
\r
610 vHash.size() > 1 ? "es" : "");
\r
612 int nChainWalkStep = 0;
\r
613 int nFalseAlarm = 0;
\r
614 int nChainWalkStepDueToFalseAlarm = 0;
\r
616 vector<rcrackiThread*> threadPool;
\r
617 vector<pthread_t> pThreads;
\r
619 pthread_attr_t attr;
\r
620 pthread_attr_init(&attr);
\r
621 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
\r
624 param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
\r
625 pthread_attr_setschedparam (&attr, ¶m);
\r
627 // else set it to 5 or something (for linux)?
\r
629 bool pausing = false;
\r
632 for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
\r
642 printf( "\nPausing, press P again to continue... ");
\r
647 gettimeofday( &tv, NULL );
\r
657 printf( " [Continuing]\n");
\r
659 gettimeofday( &tv2, NULL );
\r
660 final = sub_timeofday( tv2, tv );
\r
661 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
662 m_fTotalCryptanalysisTime -= fTime;
\r
670 printf( "\nPress 'P' to pause...\n");
\r
674 int c = tty_getchar();
\r
677 if (c==112) { // = p
\r
679 printf( "\nPausing, press 'p' again to continue... ");
\r
684 gettimeofday( &tv, NULL );
\r
688 if ((c = tty_getchar()) >= 0)
\r
693 printf( " [Continuing]\n");
\r
695 gettimeofday( &tv2, NULL );
\r
696 final = sub_timeofday( tv2, tv );
\r
697 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
698 m_fTotalCryptanalysisTime -= fTime;
\r
705 printf( "\nPress 'p' to pause...\n");
\r
709 unsigned char TargetHash[MAX_HASH_LEN];
\r
711 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
\r
712 if (nHashLen != CChainWalkContext::GetHashLen())
\r
713 printf("debug: nHashLen mismatch\n");
\r
715 // Request ChainWalk
\r
716 bool fNewlyGenerated;
\r
717 // printf("Requesting walk...");
\r
720 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
\r
722 CChainWalkContext::GetHashRoutineName(),
\r
723 CChainWalkContext::GetPlainCharsetName(),
\r
724 CChainWalkContext::GetPlainLenMin(),
\r
725 CChainWalkContext::GetPlainLenMax(),
\r
726 CChainWalkContext::GetRainbowTableIndex(),
\r
731 // printf("done!\n");
\r
732 // printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
\r
733 // vHash[nHashIndex].c_str());
\r
735 if (fNewlyGenerated)
\r
741 gettimeofday( &tv, NULL );
\r
743 printf("Pre-calculating hash %lu of %lu.%-20s\r",
\r
744 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
745 threadPool.clear();
\r
749 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
751 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
\r
755 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
757 if( returnValue != 0 )
\r
759 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
763 pThreads.push_back(pThread);
\r
766 threadPool.push_back(r_Thread);
\r
770 printf("r_Thread creation failed!\n");
\r
774 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
776 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
778 pthread_t pThread = pThreads[thread_ID];
\r
779 int returnValue = pthread_join(pThread, NULL);
\r
780 if( returnValue != 0 )
\r
782 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
785 rcrackiThread* rThread = threadPool[thread_ID];
\r
786 nChainWalkStep += rThread->GetChainWalkStep();
\r
790 m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);
\r
791 gettimeofday( &tv2, NULL );
\r
792 final = sub_timeofday( tv2, tv );
\r
794 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
796 m_fTotalPrecalculationTime += fTime;
\r
797 m_fTotalCryptanalysisTime -= fTime;
\r
799 //printf("\npStartPosIndexE[0]: %s\n", uint64tostr(pStartPosIndexE[0]).c_str());
\r
800 //printf("\npStartPosIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pStartPosIndexE[nRainbowChainLen-2]).c_str());
\r
802 printf("%-50s\r", "");
\r
805 printf("pre-calculation time: %.2f s\n", fTime);
\r
808 threadPool.clear();
\r
811 //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
\r
812 printf("Checking false alarms for hash %lu of %lu.%-20s\r",
\r
813 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
816 for (i = 0; i < maxThreads; i++)
\r
818 rcrackiThread* r_Thread = new rcrackiThread(TargetHash);
\r
819 threadPool.push_back(r_Thread);
\r
822 UINT4 thread_ID = 0;
\r
824 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
\r
826 uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
\r
828 // Search matching nIndexE
\r
829 RainbowChain *pChainFound = BinarySearch(pChain, nRainbowChainCount, nIndexEOfCurPos, pIndex, nIndexSize, nChainStart);
\r
830 if (pChainFound != NULL) // For perfected indexed tables we only recieve 1 result (huge speed increase!)
\r
832 rcrackiThread* rThread = threadPool[thread_ID];
\r
833 rThread->AddAlarmCheck(pChainFound, nPos);
\r
834 if (thread_ID < (unsigned long)maxThreads - 1 ) {
\r
842 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
844 rcrackiThread* r_Thread = threadPool[thread_ID];
\r
847 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
849 if( returnValue != 0 )
\r
851 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
855 pThreads.push_back(pThread);
\r
859 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
861 bool foundHashInThread = false;
\r
862 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
864 rcrackiThread* rThread = threadPool[thread_ID];
\r
865 pthread_t pThread = pThreads[thread_ID];
\r
867 int returnValue = pthread_join(pThread, NULL);
\r
868 if( returnValue != 0 )
\r
870 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
873 nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
\r
874 nFalseAlarm += rThread->GetnFalseAlarm();
\r
876 if (rThread->FoundHash() && !foundHashInThread) {
\r
877 //printf("\t\t\t\t\t\t\r");
\r
878 printf("%-50s\r", "");
\r
879 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
\r
882 if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
\r
883 printf("Couldn't write this result to file!\n");
\r
885 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
\r
887 FILE* file = fopen(sSessionPathName.c_str(), "a");
\r
890 string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
\r
891 fputs (buffer.c_str(), file);
\r
895 m_cws.DiscardWalk(pStartPosIndexE);
\r
896 foundHashInThread = true;
\r
903 threadPool.clear();
\r
905 //printf("\t\t\t\t\r");
\r
906 //printf("pChainFounds: %d\n", pChainsFound.size());
\r
909 //printf("\t\t\t\t\t\t\t\r");
\r
910 printf("%-50s\r", "");
\r
912 threadPool.clear();
\r
913 pthread_attr_destroy(&attr);
\r
915 //printf("debug: chain walk step: %d\n", nChainWalkStep);
\r
916 //printf("debug: false alarm: %d\n", nFalseAlarm);
\r
917 //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
\r
919 m_nTotalChainWalkStep += nChainWalkStep;
\r
920 m_nTotalFalseAlarm += nFalseAlarm;
\r
921 m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
\r
924 void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)
\r
926 // Did we already go through this file in this session?
\r
929 vector<string> sessionFinishedPathNames;
\r
930 if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))
\r
933 for (i = 0; i < sessionFinishedPathNames.size(); i++)
\r
935 if (sessionFinishedPathNames[i] == sPathName)
\r
937 printf("Skipping %s\n", sPathName.c_str());
\r
946 int nIndex = sPathName.find_last_of('\\');
\r
948 int nIndex = (int) sPathName.find_last_of('/');
\r
952 sFileName = sPathName.substr(nIndex + 1);
\r
954 sFileName = sPathName;
\r
957 printf("%s:\n", sFileName.c_str());
\r
960 int nRainbowChainLen, nRainbowChainCount;
\r
961 if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))
\r
963 //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());
\r
964 // Already finished?
\r
965 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
\r
967 printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());
\r
972 FILE* file = fopen(sPathName.c_str(), "rb");
\r
975 // File length check
\r
976 bool doOldFormat = CChainWalkContext::isOldFormat();
\r
977 bool doRti2Format = CChainWalkContext::isRti2Format();
\r
979 bool fVerified = false;
\r
980 UINT4 nFileLen = GetFileLen(file);
\r
987 //if (nFileLen % 8 != 0 || nRainbowChainCount * 8 != nFileLen)
\r
988 if ( (nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != nFileLen) && doRti2Format == false )
\r
989 printf("file length mismatch\n");
\r
992 fseek(file, 0, SEEK_SET);
\r
997 unsigned int bytesForChainWalkSet = hs.GetStatHashTotal() * (nRainbowChainLen-1) * 8;
\r
998 if (debug) printf("Debug: Saving %u bytes of memory for chainwalkset.\n", bytesForChainWalkSet);
\r
1000 uint64 nAllocatedSize;
\r
1002 if (doRti2Format || doOldFormat)
\r
1004 RTI2Reader *pReader = NULL;
\r
1006 if(doRti2Format) {
\r
1007 pReader = new RTI2Reader(sPathName);
\r
1013 if ( doOldFormat )
\r
1014 printf("Debug: This is a table in the old .rt format.\n");
\r
1015 else if ( doRti2Format )
\r
1016 printf("Debug: This is a table in the .rti2 format.\n");
\r
1019 static CMemoryPool mp(bytesForChainWalkSet, debug, maxMem);
\r
1020 RainbowChainO* pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);
\r
1021 if (debug) printf("Allocated %llu bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);
\r
1022 if (pChain != NULL)
\r
1024 nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
\r
1026 //fseek(file, 0, SEEK_SET);
\r
1027 //bool fVerified = false;
\r
1028 while (true) // Chunk read loop
\r
1030 if ((unsigned long)ftell(file) == nFileLen)
\r
1033 // Load table chunk
\r
1034 if (debug) printf("reading...\n");
\r
1035 unsigned int nDataRead = 0;
\r
1036 gettimeofday( &tv, NULL );
\r
1037 if ( doRti2Format )
\r
1039 nDataRead = nAllocatedSize / 16;
\r
1040 pReader->ReadChains(nDataRead, pChain);
\r
1041 nDataRead *= 8; // Convert from chains read to bytes
\r
1043 if ( nDataRead == 0 ) // No more data
\r
1048 nDataRead = fread(pChain, 1, nAllocatedSize, file);
\r
1050 gettimeofday( &tv2, NULL );
\r
1051 final = sub_timeofday( tv2, tv );
\r
1053 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1054 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
\r
1055 m_fTotalDiskAccessTime += fTime;
\r
1057 int nRainbowChainCountRead = nDataRead / 16;
\r
1059 // Verify table chunk
\r
1062 printf("verifying the file...\n");
\r
1064 // Chain length test
\r
1065 int nIndexToVerify = nRainbowChainCountRead / 2;
\r
1066 CChainWalkContext cwc;
\r
1067 cwc.SetIndex(pChain[nIndexToVerify].nIndexS);
\r
1069 for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
\r
1071 cwc.IndexToPlain();
\r
1072 cwc.PlainToHash();
\r
1073 cwc.HashToIndex(nPos);
\r
1075 if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)
\r
1077 printf("rainbow chain length verify fail\n");
\r
1081 // Chain sort test
\r
1083 for (i = 0; i < nRainbowChainCountRead - 1; i++)
\r
1085 if (pChain[i].nIndexE > pChain[i + 1].nIndexE)
\r
1088 if (i != nRainbowChainCountRead - 1)
\r
1090 printf("this file is not sorted\n");
\r
1097 // Search table chunk
\r
1098 gettimeofday( &tv, NULL );
\r
1099 SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);
\r
1100 gettimeofday( &tv2, NULL );
\r
1101 final = sub_timeofday( tv2, tv );
\r
1102 fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1103 printf("cryptanalysis time: %.2f s\n", fTime);
\r
1104 m_fTotalCryptanalysisTime += fTime;
\r
1106 // Already finished?
\r
1107 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
\r
1112 printf("memory allocation fail\n");
\r
1118 static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);
\r
1119 uint64 nAllocatedSizeIndex;
\r
1121 //int nIndexSize = 0;
\r
1122 //IndexChain *pIndex = NULL;
\r
1124 FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");
\r
1125 if(fIndex != NULL)
\r
1127 // File length check
\r
1128 unsigned int nFileLenIndex = GetFileLen(fIndex);
\r
1129 //unsigned int nRows = nFileLenIndex / 11;
\r
1130 //unsigned int nSize = nRows * sizeof(IndexChain);
\r
1131 //printf("Debug: 8\n");
\r
1132 if (nFileLenIndex % 11 != 0)
\r
1133 printf("index file length mismatch (%u bytes)\n", nFileLenIndex);
\r
1136 //printf("index nSize: %d\n", nSize);
\r
1137 //pIndex = (IndexChain*)new unsigned char[nSize];
\r
1138 IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);
\r
1139 if (debug) printf("Debug: Allocated %llu bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
\r
1141 static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);
\r
1143 if (pIndex != NULL && nAllocatedSizeIndex > 0)
\r
1145 nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain); // Round to sizeOfIndexChain boundary
\r
1147 fseek(fIndex, 0, SEEK_SET);
\r
1149 while ( (unsigned long)ftell(fIndex) != nFileLenIndex ) // Index chunk read loop
\r
1151 // Load index chunk
\r
1152 if (debug) printf("Debug: Setting index to 0x00 in memory, %llu bytes\n", nAllocatedSizeIndex);
\r
1153 memset(pIndex, 0x00, nAllocatedSizeIndex);
\r
1154 printf("reading index... ");
\r
1155 gettimeofday( &tv, NULL );
\r
1156 unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);
\r
1157 gettimeofday( &tv2, NULL );
\r
1158 final = sub_timeofday( tv2, tv );
\r
1160 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1161 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
\r
1162 m_fTotalDiskAccessTime += fTime;
\r
1164 //nIndexSize = nFileLenIndex / 11;
\r
1165 int nIndexChainCountRead = nDataRead / sizeof(IndexChain);
\r
1167 unsigned int nCoveredRainbowTableChains = 0;
\r
1168 for(int i = 0; i < nIndexChainCountRead; i++)
\r
1170 nCoveredRainbowTableChains += pIndex[i].nChainCount;
\r
1173 //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);
\r
1174 RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);
\r
1175 if (debug) printf("Debug: Allocated %llu bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);
\r
1177 if (pChain != NULL && nAllocatedSize > 0)
\r
1179 nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
\r
1181 //fseek(file, 0, SEEK_SET);
\r
1182 //bool fVerified = false;
\r
1183 UINT4 nProcessedChains = 0;
\r
1184 while ( (unsigned long)ftell(file) != nFileLen
\r
1185 && nProcessedChains < nCoveredRainbowTableChains ) // Chunk read loop
\r
1187 // Load table chunk
\r
1188 if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");
\r
1189 memset(pChain, 0x00, nAllocatedSize);
\r
1190 printf("reading table... ");
\r
1191 gettimeofday( &tv, NULL );
\r
1192 unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);
\r
1193 gettimeofday( &tv2, NULL );
\r
1194 final = sub_timeofday( tv2, tv );
\r
1196 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1197 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
\r
1198 m_fTotalDiskAccessTime += fTime;
\r
1199 int nRainbowChainCountRead = nDataRead / sizeOfChain;
\r
1200 // Verify table chunk (Too lazy to implement this)
\r
1204 printf("verifying the file... ");
\r
1206 // Chain length test
\r
1207 int nIndexToVerify = nRainbowChainCountRead / 2;
\r
1208 CChainWalkContext cwc;
\r
1210 nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
\r
1212 //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());
\r
1213 cwc.SetIndex(nIndexS);
\r
1216 for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
\r
1218 cwc.IndexToPlain();
\r
1219 cwc.PlainToHash();
\r
1220 cwc.HashToIndex(nPos);
\r
1223 uint64 nEndPoint = 0;
\r
1225 //for(int i = 0; i < nIndexSize; i++)
\r
1226 for(int i = 0; i < nIndexChainCountRead; i++)
\r
1228 if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index
\r
1229 { // Now we need to seek nIndexToVerify into the chains
\r
1230 nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes
\r
1231 //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());
\r
1232 //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);
\r
1233 //printf("nChainCount: %d\n", pIndex[i].nChainCount);
\r
1234 nEndPoint += pChain[nIndexToVerify].nIndexE;
\r
1239 if (cwc.GetIndex() != nEndPoint)
\r
1241 printf("rainbow chain length verify fail\n");
\r
1249 // Search table chunk
\r
1250 gettimeofday( &tv, NULL );
\r
1251 float preTime = m_fTotalCryptanalysisTime;
\r
1253 SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);
\r
1254 float postTime = m_fTotalCryptanalysisTime;
\r
1255 gettimeofday( &tv2, NULL );
\r
1256 final = sub_timeofday( tv2, tv );
\r
1258 fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1259 printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);
\r
1260 m_fTotalCryptanalysisTime += fTime;
\r
1261 nProcessedChains += nRainbowChainCountRead;
\r
1262 // Already finished?
\r
1263 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
\r
1267 else printf("memory allocation failed for rainbow table\n");
\r
1272 else printf("memory allocation failed for index\n");
\r
1277 printf("Can't load index\n");
\r
1287 if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());
\r
1288 FILE* file = fopen(sProgressPathName.c_str(), "a");
\r
1291 string buffer = sPathName + "\n";
\r
1292 fputs (buffer.c_str(), file);
\r
1297 printf("can't open file\n");
\r
1300 void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)
\r
1305 resumeSession = resume;
\r
1308 maxThreads = i_maxThreads;
\r
1309 maxMem = i_maxMem;
\r
1310 // Reset statistics
\r
1311 ResetStatistics();
\r
1313 // Sort vPathName (CChainWalkSet need it)
\r
1315 for (i = 0; i < vPathName.size() - 1; i++)
\r
1316 for (j = 0; j < vPathName.size() - i - 1; j++)
\r
1318 if (vPathName[j] > vPathName[j + 1])
\r
1321 sTemp = vPathName[j];
\r
1322 vPathName[j] = vPathName[j + 1];
\r
1323 vPathName[j + 1] = sTemp;
\r
1328 for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)
\r
1330 SearchRainbowTable(vPathName[i], hs);
\r
1334 // delete precalc files
\r
1335 if (!keepPrecalcFiles)
\r
1336 m_cws.removePrecalcFiles();
\r
1343 void CCrackEngine::setOutputFile(string sPathName)
\r
1345 writeOutput = true;
\r
1346 outputFile = sPathName;
\r
1349 void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)
\r
1351 sSessionPathName = sSession;
\r
1352 sProgressPathName = sProgress;
\r
1353 sPrecalcPathName = sPrecalc;
\r
1354 keepPrecalcFiles = keepPrecalc;
\r
1357 float CCrackEngine::GetStatTotalDiskAccessTime()
\r
1359 return m_fTotalDiskAccessTime;
\r
1361 /*float CCrackEngine::GetWastedTime()
\r
1363 return m_fIndexTime;
\r
1365 float CCrackEngine::GetStatTotalCryptanalysisTime()
\r
1367 return m_fTotalCryptanalysisTime;
\r
1370 float CCrackEngine::GetStatTotalPrecalculationTime()
\r
1372 return m_fTotalPrecalculationTime;
\r
1375 int CCrackEngine::GetStatTotalChainWalkStep()
\r
1377 return m_nTotalChainWalkStep;
\r
1380 int CCrackEngine::GetStatTotalFalseAlarm()
\r
1382 return m_nTotalFalseAlarm;
\r
1385 int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()
\r
1387 return m_nTotalChainWalkStepDueToFalseAlarm;
\r