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 rcracki_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
27 #if defined(_WIN32) && !defined(__GNUC__)
\r
28 #pragma warning(disable : 4786 4267 4018)
\r
31 #include "CrackEngine.h"
\r
32 #include "RTI2Reader.h"
\r
35 #include <sys/resource.h>
\r
38 CCrackEngine::CCrackEngine()
\r
41 writeOutput = false;
\r
42 resumeSession = false;
\r
44 keepPrecalcFiles = false;
\r
46 sSessionPathName = "";
\r
47 sProgressPathName = "";
\r
50 CCrackEngine::~CCrackEngine()
\r
54 //////////////////////////////////////////////////////////////////////
\r
56 void CCrackEngine::ResetStatistics()
\r
58 m_fTotalDiskAccessTime = 0.0f;
\r
59 m_fTotalCryptanalysisTime = 0.0f;
\r
60 m_fTotalPrecalculationTime = 0.0f;
\r
61 m_nTotalChainWalkStep = 0;
\r
62 m_nTotalFalseAlarm = 0;
\r
63 m_nTotalChainWalkStepDueToFalseAlarm = 0;
\r
64 // m_nTotalFalseAlarmSkipped = 0;
\r
67 int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)
\r
70 int nHigh = nRainbowChainCount - 1;
\r
71 while (nLow <= nHigh)
\r
73 int nMid = (nLow + nHigh) / 2;
\r
74 if (nIndex == pChain[nMid].nIndexE)
\r
76 else if (nIndex < pChain[nMid].nIndexE)
\r
85 RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)
\r
87 uint64 nPrefix = nIndex >> 16;
\r
92 if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file
\r
98 int nBHigh = nIndexSize - 1;
\r
99 while (nBLow <= nBHigh)
\r
101 int nBMid = (nBLow + nBHigh) / 2;
\r
102 if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
\r
107 nLow = pIndex[nBMid].nFirstChain;
\r
108 nHigh = nLow + pIndex[nBMid].nChainCount;
\r
109 if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead)
\r
111 if(nHigh > nIndexStart + nChainCountRead)
\r
112 nHigh = nIndexStart + nChainCountRead;
\r
114 else if(nLow < nIndexStart && nHigh >= nIndexStart)
\r
116 nLow = nIndexStart;
\r
122 else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
\r
123 nBHigh = nBMid - 1;
\r
129 for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)
\r
131 int nSIndex = ((int)nIndex) & 0x0000FFFF;
\r
133 if (nSIndex == pChain[i].nIndexE)
\r
137 else if(pChain[i].nIndexE > nSIndex)
\r
144 // not used currently, leaving code for future checkpoints
\r
145 //bool CCrackEngine::CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
\r
147 // CChainWalkContext cwc;
\r
148 // //uint64 nIndexS = pChain->nIndexS >> 16;
\r
149 // uint64 nIndexS = pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
\r
150 // cwc.SetIndex(nIndexS);
\r
152 // for (nPos = 0; nPos < nGuessedPos; nPos++)
\r
154 // cwc.IndexToPlain();
\r
155 // cwc.PlainToHash();
\r
156 // cwc.HashToIndex(nPos);
\r
157 // // Not using checkpoints atm
\r
162 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)
\r
164 // m_nTotalFalseAlarmSkipped += 10000 - 5000;
\r
165 //// printf("CheckPoint caught false alarm at position 7600\n");
\r
170 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)
\r
172 //// printf("CheckPoint caught false alarm at position 8200\n");
\r
173 // m_nTotalFalseAlarmSkipped += 10000 - 6000;
\r
179 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)
\r
181 //// printf("CheckPoint caught false alarm at position 8700\n");
\r
182 // m_nTotalFalseAlarmSkipped += 10000 - 7600;
\r
188 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)
\r
190 //// printf("CheckPoint caught false alarm at position 9000\n");
\r
191 // m_nTotalFalseAlarmSkipped += 10000 - 8200;
\r
197 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)
\r
199 //// printf("CheckPoint caught false alarm at position 9300\n");
\r
200 // m_nTotalFalseAlarmSkipped += 10000 - 8700;
\r
206 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)
\r
208 //// printf("CheckPoint caught false alarm at position 9600\n");
\r
209 // m_nTotalFalseAlarmSkipped += 10000 - 9000;
\r
215 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)
\r
217 //// printf("CheckPoint caught false alarm at position 9600\n");
\r
218 // m_nTotalFalseAlarmSkipped += 10000 - 9300;
\r
223 // if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))
\r
225 //// printf("CheckPoint caught false alarm at position 9600\n");
\r
226 // m_nTotalFalseAlarmSkipped += 10000 - 9600;
\r
233 // cwc.IndexToPlain();
\r
234 // cwc.PlainToHash();
\r
235 // if (cwc.CheckHash(pHash))
\r
237 // printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
\r
238 // hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
\r
245 //bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
\r
247 // CChainWalkContext cwc;
\r
248 // cwc.SetIndex(pChain->nIndexS);
\r
250 // for (nPos = 0; nPos < nGuessedPos; nPos++)
\r
252 // cwc.IndexToPlain();
\r
253 // cwc.PlainToHash();
\r
254 // cwc.HashToIndex(nPos);
\r
256 // cwc.IndexToPlain();
\r
257 // cwc.PlainToHash();
\r
258 // if (cwc.CheckHash(pHash))
\r
260 // printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
\r
261 // hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
\r
268 void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,
\r
269 int nRainbowChainCount,
\r
270 int nMatchingIndexE,
\r
271 int& nMatchingIndexEFrom,
\r
272 int& nMatchingIndexETo)
\r
274 nMatchingIndexEFrom = nMatchingIndexE;
\r
275 nMatchingIndexETo = nMatchingIndexE;
\r
276 while (nMatchingIndexEFrom > 0)
\r
278 if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
\r
279 nMatchingIndexEFrom--;
\r
283 while (nMatchingIndexETo < nRainbowChainCount - 1)
\r
285 if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
\r
286 nMatchingIndexETo++;
\r
292 void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)
\r
294 vector<string> vHash;
\r
295 hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
\r
296 printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
\r
297 vHash.size() > 1 ? "es" : "");
\r
299 int nChainWalkStep = 0;
\r
300 int nFalseAlarm = 0;
\r
301 int nChainWalkStepDueToFalseAlarm = 0;
\r
303 vector<rcrackiThread*> threadPool;
\r
304 vector<pthread_t> pThreads;
\r
308 * On linux you cannot set the priority of a thread in the non real time
\r
309 * scheduling groups. You can set the priority of the process. In
\r
310 * windows BELOW_NORMAL represents a 1/8th drop in priority and this would
\r
311 * be 20 * 1/8 on linux or about 2.5
\r
313 setpriority( PRIO_PROCESS, 0, 2 );
\r
316 pthread_attr_t attr;
\r
317 pthread_attr_init(&attr);
\r
318 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
\r
322 * windows scheduling is 0 to 32 (low to high) with 8 as normal and 7 as
\r
325 param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
\r
326 pthread_attr_setschedparam (&attr, ¶m);
\r
329 bool pausing = false;
\r
332 for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
\r
342 printf( "\nPausing, press P again to continue... ");
\r
347 gettimeofday( &tv, NULL );
\r
357 printf( " [Continuing]\n");
\r
359 gettimeofday( &tv2, NULL );
\r
360 final = sub_timeofday( tv2, tv );
\r
361 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
362 m_fTotalCryptanalysisTime -= fTime;
\r
370 printf( "\nPress 'P' to pause...\n");
\r
374 int c = tty_getchar();
\r
377 if (c==112) { // = p
\r
379 printf( "\nPausing, press 'p' again to continue... ");
\r
384 gettimeofday( &tv, NULL );
\r
388 if ((c = tty_getchar()) >= 0)
\r
393 printf( " [Continuing]\n");
\r
395 gettimeofday( &tv2, NULL );
\r
396 final = sub_timeofday( tv2, tv );
\r
397 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
398 m_fTotalCryptanalysisTime -= fTime;
\r
405 printf( "\nPress 'p' to pause...\n");
\r
409 unsigned char TargetHash[MAX_HASH_LEN];
\r
411 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
\r
412 if (nHashLen != CChainWalkContext::GetHashLen())
\r
413 printf("debug: nHashLen mismatch\n");
\r
415 // Rqeuest ChainWalk
\r
416 bool fNewlyGenerated;
\r
417 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
\r
419 CChainWalkContext::GetHashRoutineName(),
\r
420 CChainWalkContext::GetPlainCharsetName(),
\r
421 CChainWalkContext::GetPlainLenMin(),
\r
422 CChainWalkContext::GetPlainLenMax(),
\r
423 CChainWalkContext::GetRainbowTableIndex(),
\r
428 //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
\r
429 // vHash[nHashIndex].c_str());
\r
432 if (fNewlyGenerated)
\r
438 gettimeofday( &tv, NULL );
\r
440 printf("Pre-calculating hash %lu of %lu.%-20s\r",
\r
441 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
442 threadPool.clear();
\r
446 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
448 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
\r
452 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
454 if( returnValue != 0 )
\r
456 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
460 pThreads.push_back(pThread);
\r
463 threadPool.push_back(r_Thread);
\r
467 printf("r_Thread creation failed!\n");
\r
471 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
473 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
475 pthread_t pThread = pThreads[thread_ID];
\r
476 int returnValue = pthread_join(pThread, NULL);
\r
477 if( returnValue != 0 )
\r
479 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
482 rcrackiThread* rThread = threadPool[thread_ID];
\r
483 nChainWalkStep += rThread->GetChainWalkStep();
\r
486 gettimeofday( &tv2, NULL );
\r
487 final = sub_timeofday( tv2, tv );
\r
489 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
491 m_fTotalPrecalculationTime += fTime;
\r
492 m_fTotalCryptanalysisTime -= fTime;
\r
494 printf("%-50s\r", "");
\r
497 printf("pre-calculation time: %.2f s\n", fTime);
\r
500 //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
\r
501 printf("Checking false alarms for hash %lu of %lu.%-20s\r",
\r
502 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
504 threadPool.clear();
\r
508 for (i = 0; i < maxThreads; i++)
\r
510 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);
\r
511 threadPool.push_back(r_Thread);
\r
514 UINT4 thread_ID = 0;
\r
516 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
\r
518 uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
\r
520 // Search matching nIndexE
\r
521 int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);
\r
522 if (nMatchingIndexE != -1)
\r
524 int nMatchingIndexEFrom, nMatchingIndexETo;
\r
525 GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,
\r
527 nMatchingIndexEFrom, nMatchingIndexETo);
\r
529 for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)
\r
531 rcrackiThread* rThread = threadPool[thread_ID];
\r
532 rThread->AddAlarmCheckO(pChain + i, nPos);
\r
533 if (thread_ID < (unsigned long)maxThreads - 1 ) {
\r
542 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
544 rcrackiThread* r_Thread = threadPool[thread_ID];
\r
547 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
549 if( returnValue != 0 )
\r
551 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
555 pThreads.push_back(pThread);
\r
559 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
561 bool foundHashInThread = false;
\r
562 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
564 rcrackiThread* rThread = threadPool[thread_ID];
\r
565 pthread_t pThread = pThreads[thread_ID];
\r
567 int returnValue = pthread_join(pThread, NULL);
\r
568 if( returnValue != 0 )
\r
570 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
573 nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
\r
574 nFalseAlarm += rThread->GetnFalseAlarm();
\r
576 if (rThread->FoundHash() && !foundHashInThread) {
\r
577 //printf("\t\t\t\t\t\t\r");
\r
578 printf("%-50s\r", "");
\r
580 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
\r
583 if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
\r
584 printf("Couldn't write this result to file!\n");
\r
586 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
\r
588 FILE* file = fopen(sSessionPathName.c_str(), "a");
\r
591 string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
\r
592 fputs (buffer.c_str(), file);
\r
596 m_cws.DiscardWalk(pStartPosIndexE);
\r
597 foundHashInThread = true;
\r
602 threadPool.clear();
\r
605 //printf("\t\t\t\t\t\t\t\r");
\r
606 printf("%-50s\r", "");
\r
608 threadPool.clear();
\r
609 pthread_attr_destroy(&attr);
\r
611 //printf("debug: chain walk step: %d\n", nChainWalkStep);
\r
612 //printf("debug: false alarm: %d\n", nFalseAlarm);
\r
613 //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
\r
615 m_nTotalChainWalkStep += nChainWalkStep;
\r
616 m_nTotalFalseAlarm += nFalseAlarm;
\r
617 m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
\r
620 void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)
\r
622 vector<string> vHash;
\r
623 //vector<uint64 *> vIndices;
\r
624 //vector<RainbowChain *> vChains;
\r
625 hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
\r
626 printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
\r
627 vHash.size() > 1 ? "es" : "");
\r
629 int nChainWalkStep = 0;
\r
630 int nFalseAlarm = 0;
\r
631 int nChainWalkStepDueToFalseAlarm = 0;
\r
633 vector<rcrackiThread*> threadPool;
\r
634 vector<pthread_t> pThreads;
\r
638 * On linux you cannot set the priority of a thread in the non real time
\r
639 * scheduling groups. You can set the priority of the process. In
\r
640 * windows BELOW_NORMAL represents a 1/8th drop in priority and this would
\r
641 * be 20 * 1/8 on linux or about 2.5
\r
643 setpriority( PRIO_PROCESS, 0, 2 );
\r
646 pthread_attr_t attr;
\r
647 pthread_attr_init(&attr);
\r
648 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
\r
651 param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
\r
652 pthread_attr_setschedparam (&attr, ¶m);
\r
654 // else set it to 5 or something (for linux)?
\r
656 bool pausing = false;
\r
659 for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
\r
669 printf( "\nPausing, press P again to continue... ");
\r
674 gettimeofday( &tv, NULL );
\r
684 printf( " [Continuing]\n");
\r
686 gettimeofday( &tv2, NULL );
\r
687 final = sub_timeofday( tv2, tv );
\r
688 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
689 m_fTotalCryptanalysisTime -= fTime;
\r
697 printf( "\nPress 'P' to pause...\n");
\r
701 int c = tty_getchar();
\r
704 if (c==112) { // = p
\r
706 printf( "\nPausing, press 'p' again to continue... ");
\r
711 gettimeofday( &tv, NULL );
\r
715 if ((c = tty_getchar()) >= 0)
\r
720 printf( " [Continuing]\n");
\r
722 gettimeofday( &tv2, NULL );
\r
723 final = sub_timeofday( tv2, tv );
\r
724 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
725 m_fTotalCryptanalysisTime -= fTime;
\r
732 printf( "\nPress 'p' to pause...\n");
\r
736 unsigned char TargetHash[MAX_HASH_LEN];
\r
738 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
\r
739 if (nHashLen != CChainWalkContext::GetHashLen())
\r
740 printf("debug: nHashLen mismatch\n");
\r
742 // Request ChainWalk
\r
743 bool fNewlyGenerated;
\r
744 // printf("Requesting walk...");
\r
747 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
\r
749 CChainWalkContext::GetHashRoutineName(),
\r
750 CChainWalkContext::GetPlainCharsetName(),
\r
751 CChainWalkContext::GetPlainLenMin(),
\r
752 CChainWalkContext::GetPlainLenMax(),
\r
753 CChainWalkContext::GetRainbowTableIndex(),
\r
758 // printf("done!\n");
\r
759 // printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
\r
760 // vHash[nHashIndex].c_str());
\r
762 if (fNewlyGenerated)
\r
768 gettimeofday( &tv, NULL );
\r
770 printf("Pre-calculating hash %lu of %lu.%-20s\r",
\r
771 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
772 threadPool.clear();
\r
776 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
778 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
\r
782 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
784 if( returnValue != 0 )
\r
786 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
790 pThreads.push_back(pThread);
\r
793 threadPool.push_back(r_Thread);
\r
797 printf("r_Thread creation failed!\n");
\r
801 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
803 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
805 pthread_t pThread = pThreads[thread_ID];
\r
806 int returnValue = pthread_join(pThread, NULL);
\r
807 if( returnValue != 0 )
\r
809 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
812 rcrackiThread* rThread = threadPool[thread_ID];
\r
813 nChainWalkStep += rThread->GetChainWalkStep();
\r
817 m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);
\r
818 gettimeofday( &tv2, NULL );
\r
819 final = sub_timeofday( tv2, tv );
\r
821 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
823 m_fTotalPrecalculationTime += fTime;
\r
824 m_fTotalCryptanalysisTime -= fTime;
\r
826 //printf("\npStartPosIndexE[0]: %s\n", uint64tostr(pStartPosIndexE[0]).c_str());
\r
827 //printf("\npStartPosIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pStartPosIndexE[nRainbowChainLen-2]).c_str());
\r
829 printf("%-50s\r", "");
\r
832 printf("pre-calculation time: %.2f s\n", fTime);
\r
835 threadPool.clear();
\r
838 //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
\r
839 printf("Checking false alarms for hash %lu of %lu.%-20s\r",
\r
840 (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
\r
843 for (i = 0; i < maxThreads; i++)
\r
845 rcrackiThread* r_Thread = new rcrackiThread(TargetHash);
\r
846 threadPool.push_back(r_Thread);
\r
849 UINT4 thread_ID = 0;
\r
851 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
\r
853 uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
\r
855 // Search matching nIndexE
\r
856 RainbowChain *pChainFound = BinarySearch(pChain, nRainbowChainCount, nIndexEOfCurPos, pIndex, nIndexSize, nChainStart);
\r
857 if (pChainFound != NULL) // For perfected indexed tables we only recieve 1 result (huge speed increase!)
\r
859 rcrackiThread* rThread = threadPool[thread_ID];
\r
860 rThread->AddAlarmCheck(pChainFound, nPos);
\r
861 if (thread_ID < (unsigned long)maxThreads - 1 ) {
\r
869 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
\r
871 rcrackiThread* r_Thread = threadPool[thread_ID];
\r
874 int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
\r
876 if( returnValue != 0 )
\r
878 printf("pThread creation failed, returnValue: %d\n", returnValue);
\r
882 pThreads.push_back(pThread);
\r
886 //printf("%d r_Threads created\t\t\n", threadPool.size());
\r
888 bool foundHashInThread = false;
\r
889 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
\r
891 rcrackiThread* rThread = threadPool[thread_ID];
\r
892 pthread_t pThread = pThreads[thread_ID];
\r
894 int returnValue = pthread_join(pThread, NULL);
\r
895 if( returnValue != 0 )
\r
897 printf("pThread join failed, returnValue: %d\n", returnValue);
\r
900 nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
\r
901 nFalseAlarm += rThread->GetnFalseAlarm();
\r
903 if (rThread->FoundHash() && !foundHashInThread) {
\r
904 //printf("\t\t\t\t\t\t\r");
\r
905 printf("%-50s\r", "");
\r
906 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
\r
909 if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
\r
910 printf("Couldn't write this result to file!\n");
\r
912 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
\r
914 FILE* file = fopen(sSessionPathName.c_str(), "a");
\r
917 string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
\r
918 fputs (buffer.c_str(), file);
\r
922 m_cws.DiscardWalk(pStartPosIndexE);
\r
923 foundHashInThread = true;
\r
930 threadPool.clear();
\r
932 //printf("\t\t\t\t\r");
\r
933 //printf("pChainFounds: %d\n", pChainsFound.size());
\r
936 //printf("\t\t\t\t\t\t\t\r");
\r
937 printf("%-50s\r", "");
\r
939 threadPool.clear();
\r
940 pthread_attr_destroy(&attr);
\r
942 //printf("debug: chain walk step: %d\n", nChainWalkStep);
\r
943 //printf("debug: false alarm: %d\n", nFalseAlarm);
\r
944 //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
\r
946 m_nTotalChainWalkStep += nChainWalkStep;
\r
947 m_nTotalFalseAlarm += nFalseAlarm;
\r
948 m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
\r
951 void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)
\r
953 // Did we already go through this file in this session?
\r
956 vector<string> sessionFinishedPathNames;
\r
957 if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))
\r
960 for (i = 0; i < sessionFinishedPathNames.size(); i++)
\r
962 if (sessionFinishedPathNames[i] == sPathName)
\r
964 printf("Skipping %s\n", sPathName.c_str());
\r
973 string::size_type nIndex = sPathName.find_last_of('\\');
\r
975 string::size_type nIndex = sPathName.find_last_of('/');
\r
978 if (nIndex != string::npos)
\r
979 sFileName = sPathName.substr(nIndex + 1);
\r
981 sFileName = sPathName;
\r
984 printf("%s:\n", sFileName.c_str());
\r
987 int nRainbowChainLen, nRainbowChainCount;
\r
988 if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))
\r
990 //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());
\r
991 // Already finished?
\r
992 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
\r
994 printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());
\r
999 FILE* file = fopen(sPathName.c_str(), "rb");
\r
1002 // File length check
\r
1003 bool doOldFormat = CChainWalkContext::isOldFormat();
\r
1004 bool doRti2Format = CChainWalkContext::isRti2Format();
\r
1005 UINT4 sizeOfChain;
\r
1006 bool fVerified = false;
\r
1007 UINT4 nFileLen = GetFileLen(file);
\r
1014 //if (nFileLen % 8 != 0 || nRainbowChainCount * 8 != nFileLen)
\r
1015 if ( (nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != nFileLen) && doRti2Format == false )
\r
1016 printf("file length mismatch\n");
\r
1019 fseek(file, 0, SEEK_SET);
\r
1024 unsigned int bytesForChainWalkSet = hs.GetStatHashTotal() * (nRainbowChainLen-1) * 8;
\r
1025 if (debug) printf("Debug: Saving %u bytes of memory for chainwalkset.\n", bytesForChainWalkSet);
\r
1027 uint64 nAllocatedSize;
\r
1029 if (doRti2Format || doOldFormat)
\r
1031 RTI2Reader *pReader = NULL;
\r
1033 if(doRti2Format) {
\r
1034 pReader = new RTI2Reader(sPathName);
\r
1040 if ( doOldFormat )
\r
1041 printf("Debug: This is a table in the old .rt format.\n");
\r
1042 else if ( doRti2Format )
\r
1043 printf("Debug: This is a table in the .rti2 format.\n");
\r
1046 static CMemoryPool mp(bytesForChainWalkSet, debug, maxMem);
\r
1047 RainbowChainO* pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);
\r
1049 if (debug) printf("Allocated %I64u bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);
\r
1051 if (debug) printf("Allocated %llu bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);
\r
1054 if (pChain != NULL)
\r
1056 nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
\r
1058 //fseek(file, 0, SEEK_SET);
\r
1059 //bool fVerified = false;
\r
1060 while (true) // Chunk read loop
\r
1062 if ((unsigned long)ftell(file) == nFileLen)
\r
1065 // Load table chunk
\r
1066 if (debug) printf("reading...\n");
\r
1067 unsigned int nDataRead = 0;
\r
1068 gettimeofday( &tv, NULL );
\r
1069 if ( doRti2Format )
\r
1071 nDataRead = nAllocatedSize / 16;
\r
1072 pReader->ReadChains(nDataRead, pChain);
\r
1073 nDataRead *= 8; // Convert from chains read to bytes
\r
1075 if ( nDataRead == 0 ) // No more data
\r
1080 nDataRead = fread(pChain, 1, nAllocatedSize, file);
\r
1082 gettimeofday( &tv2, NULL );
\r
1083 final = sub_timeofday( tv2, tv );
\r
1085 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1086 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
\r
1087 m_fTotalDiskAccessTime += fTime;
\r
1089 int nRainbowChainCountRead = nDataRead / 16;
\r
1091 // Verify table chunk
\r
1094 printf("verifying the file...\n");
\r
1096 // Chain length test
\r
1097 int nIndexToVerify = nRainbowChainCountRead / 2;
\r
1098 CChainWalkContext cwc;
\r
1099 cwc.SetIndex(pChain[nIndexToVerify].nIndexS);
\r
1101 for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
\r
1103 cwc.IndexToPlain();
\r
1104 cwc.PlainToHash();
\r
1105 cwc.HashToIndex(nPos);
\r
1107 if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)
\r
1109 printf("rainbow chain length verify fail\n");
\r
1113 // Chain sort test
\r
1115 for (i = 0; i < nRainbowChainCountRead - 1; i++)
\r
1117 if (pChain[i].nIndexE > pChain[i + 1].nIndexE)
\r
1120 if (i != nRainbowChainCountRead - 1)
\r
1122 printf("this file is not sorted\n");
\r
1129 // Search table chunk
\r
1130 gettimeofday( &tv, NULL );
\r
1131 SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);
\r
1132 gettimeofday( &tv2, NULL );
\r
1133 final = sub_timeofday( tv2, tv );
\r
1134 fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1135 printf("cryptanalysis time: %.2f s\n", fTime);
\r
1136 m_fTotalCryptanalysisTime += fTime;
\r
1138 // Already finished?
\r
1139 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
\r
1144 printf("memory allocation fail\n");
\r
1150 static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);
\r
1151 uint64 nAllocatedSizeIndex;
\r
1153 //int nIndexSize = 0;
\r
1154 //IndexChain *pIndex = NULL;
\r
1156 FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");
\r
1157 if(fIndex != NULL)
\r
1159 // File length check
\r
1160 unsigned int nFileLenIndex = GetFileLen(fIndex);
\r
1161 //unsigned int nRows = nFileLenIndex / 11;
\r
1162 //unsigned int nSize = nRows * sizeof(IndexChain);
\r
1163 //printf("Debug: 8\n");
\r
1164 if (nFileLenIndex % 11 != 0)
\r
1165 printf("index file length mismatch (%u bytes)\n", nFileLenIndex);
\r
1168 //printf("index nSize: %d\n", nSize);
\r
1169 //pIndex = (IndexChain*)new unsigned char[nSize];
\r
1170 IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);
\r
1172 if (debug) printf("Debug: Allocated %I64u bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
\r
1174 if (debug) printf("Debug: Allocated %llu bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
\r
1177 static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);
\r
1179 if (pIndex != NULL && nAllocatedSizeIndex > 0)
\r
1181 nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain); // Round to sizeOfIndexChain boundary
\r
1183 fseek(fIndex, 0, SEEK_SET);
\r
1185 while ( (unsigned long)ftell(fIndex) != nFileLenIndex ) // Index chunk read loop
\r
1187 // Load index chunk
\r
1189 if (debug) printf("Debug: Setting index to 0x00 in memory, %I64u bytes\n", nAllocatedSizeIndex);
\r
1191 if (debug) printf("Debug: Setting index to 0x00 in memory, %llu bytes\n", nAllocatedSizeIndex);
\r
1193 memset(pIndex, 0x00, nAllocatedSizeIndex);
\r
1194 printf("reading index... ");
\r
1195 gettimeofday( &tv, NULL );
\r
1196 unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);
\r
1197 gettimeofday( &tv2, NULL );
\r
1198 final = sub_timeofday( tv2, tv );
\r
1200 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1201 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
\r
1202 m_fTotalDiskAccessTime += fTime;
\r
1204 //nIndexSize = nFileLenIndex / 11;
\r
1205 int nIndexChainCountRead = nDataRead / sizeof(IndexChain);
\r
1207 unsigned int nCoveredRainbowTableChains = 0;
\r
1208 for(int i = 0; i < nIndexChainCountRead; i++)
\r
1210 nCoveredRainbowTableChains += pIndex[i].nChainCount;
\r
1213 //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);
\r
1214 RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);
\r
1216 if (debug) printf("Debug: Allocated %I64u bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);
\r
1218 if (debug) printf("Debug: Allocated %llu bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);
\r
1221 if (pChain != NULL && nAllocatedSize > 0)
\r
1223 nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain; // Round to sizeOfChain boundary
\r
1225 //fseek(file, 0, SEEK_SET);
\r
1226 //bool fVerified = false;
\r
1227 UINT4 nProcessedChains = 0;
\r
1228 while ( (unsigned long)ftell(file) != nFileLen
\r
1229 && nProcessedChains < nCoveredRainbowTableChains ) // Chunk read loop
\r
1231 // Load table chunk
\r
1232 if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");
\r
1233 memset(pChain, 0x00, nAllocatedSize);
\r
1234 printf("reading table... ");
\r
1235 gettimeofday( &tv, NULL );
\r
1236 unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);
\r
1237 gettimeofday( &tv2, NULL );
\r
1238 final = sub_timeofday( tv2, tv );
\r
1240 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1241 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
\r
1242 m_fTotalDiskAccessTime += fTime;
\r
1243 int nRainbowChainCountRead = nDataRead / sizeOfChain;
\r
1244 // Verify table chunk (Too lazy to implement this)
\r
1248 printf("verifying the file... ");
\r
1250 // Chain length test
\r
1251 int nIndexToVerify = nRainbowChainCountRead / 2;
\r
1252 CChainWalkContext cwc;
\r
1254 nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
\r
1256 //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());
\r
1257 cwc.SetIndex(nIndexS);
\r
1260 for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
\r
1262 cwc.IndexToPlain();
\r
1263 cwc.PlainToHash();
\r
1264 cwc.HashToIndex(nPos);
\r
1267 uint64 nEndPoint = 0;
\r
1269 //for(int i = 0; i < nIndexSize; i++)
\r
1270 for(int i = 0; i < nIndexChainCountRead; i++)
\r
1272 if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index
\r
1273 { // Now we need to seek nIndexToVerify into the chains
\r
1274 nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes
\r
1275 //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());
\r
1276 //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);
\r
1277 //printf("nChainCount: %d\n", pIndex[i].nChainCount);
\r
1278 nEndPoint += pChain[nIndexToVerify].nIndexE;
\r
1283 if (cwc.GetIndex() != nEndPoint)
\r
1285 printf("rainbow chain length verify fail\n");
\r
1293 // Search table chunk
\r
1294 gettimeofday( &tv, NULL );
\r
1295 float preTime = m_fTotalCryptanalysisTime;
\r
1297 SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);
\r
1298 float postTime = m_fTotalCryptanalysisTime;
\r
1299 gettimeofday( &tv2, NULL );
\r
1300 final = sub_timeofday( tv2, tv );
\r
1302 fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
\r
1303 printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);
\r
1304 m_fTotalCryptanalysisTime += fTime;
\r
1305 nProcessedChains += nRainbowChainCountRead;
\r
1306 // Already finished?
\r
1307 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
\r
1311 else printf("memory allocation failed for rainbow table\n");
\r
1316 else printf("memory allocation failed for index\n");
\r
1321 printf("Can't load index\n");
\r
1331 if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());
\r
1332 FILE* file = fopen(sProgressPathName.c_str(), "a");
\r
1335 string buffer = sPathName + "\n";
\r
1336 fputs (buffer.c_str(), file);
\r
1341 printf("can't open file\n");
\r
1344 void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)
\r
1349 resumeSession = resume;
\r
1352 maxThreads = i_maxThreads;
\r
1353 maxMem = i_maxMem;
\r
1354 // Reset statistics
\r
1355 ResetStatistics();
\r
1357 // Sort vPathName (CChainWalkSet need it)
\r
1359 for (i = 0; i < vPathName.size() - 1; i++)
\r
1360 for (j = 0; j < vPathName.size() - i - 1; j++)
\r
1362 if (vPathName[j] > vPathName[j + 1])
\r
1365 sTemp = vPathName[j];
\r
1366 vPathName[j] = vPathName[j + 1];
\r
1367 vPathName[j + 1] = sTemp;
\r
1372 for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)
\r
1374 SearchRainbowTable(vPathName[i], hs);
\r
1378 // delete precalc files
\r
1379 if (!keepPrecalcFiles)
\r
1380 m_cws.removePrecalcFiles();
\r
1387 void CCrackEngine::setOutputFile(string sPathName)
\r
1389 writeOutput = true;
\r
1390 outputFile = sPathName;
\r
1393 void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)
\r
1395 sSessionPathName = sSession;
\r
1396 sProgressPathName = sProgress;
\r
1397 sPrecalcPathName = sPrecalc;
\r
1398 keepPrecalcFiles = keepPrecalc;
\r
1401 float CCrackEngine::GetStatTotalDiskAccessTime()
\r
1403 return m_fTotalDiskAccessTime;
\r
1405 /*float CCrackEngine::GetWastedTime()
\r
1407 return m_fIndexTime;
\r
1409 float CCrackEngine::GetStatTotalCryptanalysisTime()
\r
1411 return m_fTotalCryptanalysisTime;
\r
1414 float CCrackEngine::GetStatTotalPrecalculationTime()
\r
1416 return m_fTotalPrecalculationTime;
\r
1419 int CCrackEngine::GetStatTotalChainWalkStep()
\r
1421 return m_nTotalChainWalkStep;
\r
1424 int CCrackEngine::GetStatTotalFalseAlarm()
\r
1426 return m_nTotalFalseAlarm;
\r
1429 int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()
\r
1431 return m_nTotalChainWalkStepDueToFalseAlarm;
\r