]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/CrackEngine.cpp
remove old deprecated rcracki
[freerainbowtables] / Client Applications / rcracki_mt / CrackEngine.cpp
1 /*\r
2  * rcracki_mt is a multithreaded implementation and fork of the original \r
3  * RainbowCrack\r
4  *\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
10  *\r
11  * This file is part of racrcki_mt.\r
12  *\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
17  *\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
22  *\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
25  */\r
26 \r
27 #ifdef _WIN32\r
28         #pragma warning(disable : 4786 4267 4018)\r
29 #endif\r
30 \r
31 #include "CrackEngine.h"\r
32 #include "RTI2Reader.h"\r
33 \r
34 CCrackEngine::CCrackEngine()\r
35 {\r
36         ResetStatistics();\r
37         writeOutput = false;\r
38         resumeSession = false;\r
39         debug = false;\r
40         keepPrecalcFiles = false;\r
41 \r
42         sSessionPathName = "";\r
43         sProgressPathName = "";\r
44 }\r
45 \r
46 CCrackEngine::~CCrackEngine()\r
47 {\r
48 }\r
49 \r
50 //////////////////////////////////////////////////////////////////////\r
51 \r
52 void CCrackEngine::ResetStatistics()\r
53 {\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
61 }\r
62 \r
63 int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)\r
64 {\r
65         int nLow = 0;\r
66         int nHigh = nRainbowChainCount - 1;\r
67         while (nLow <= nHigh)\r
68         {\r
69                 int nMid = (nLow + nHigh) / 2;\r
70                 if (nIndex == pChain[nMid].nIndexE)\r
71                         return nMid;\r
72                 else if (nIndex < pChain[nMid].nIndexE)\r
73                         nHigh = nMid - 1;\r
74                 else\r
75                         nLow = nMid + 1;\r
76         }\r
77 \r
78         return -1;\r
79 }\r
80 \r
81 RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)\r
82 {\r
83         uint64 nPrefix = nIndex >> 16;\r
84         int nLow, nHigh;        \r
85         bool found = false;\r
86         //int nChains = 0;\r
87         \r
88         if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file\r
89         {\r
90                 return NULL;\r
91         }\r
92 \r
93         int nBLow = 0;\r
94         int nBHigh = nIndexSize - 1;\r
95         while (nBLow <= nBHigh)\r
96         {\r
97                 int nBMid = (nBLow + nBHigh) / 2;\r
98                 if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
99                 {\r
100                         //nLow = nChains;\r
101                         //int nChains = 0;\r
102 \r
103                         nLow = pIndex[nBMid].nFirstChain;\r
104                         nHigh = nLow + pIndex[nBMid].nChainCount;\r
105                         if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead) \r
106                         {                                       \r
107                                 if(nHigh > nIndexStart + nChainCountRead)\r
108                                         nHigh = nIndexStart + nChainCountRead;\r
109                         }\r
110                         else if(nLow < nIndexStart && nHigh >= nIndexStart)\r
111                         {\r
112                                 nLow = nIndexStart;\r
113                         }\r
114                         else break;                                     \r
115                         found = true;\r
116                         break;\r
117                 }\r
118                 else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
119                         nBHigh = nBMid - 1;\r
120                 else\r
121                         nBLow = nBMid + 1;\r
122         }\r
123         if(found == true)\r
124         {\r
125                 for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)\r
126                 {\r
127                         int nSIndex = ((int)nIndex) & 0x0000FFFF;\r
128 \r
129                         if (nSIndex == pChain[i].nIndexE)\r
130                         {\r
131                                 return &pChain[i];\r
132                         }                               \r
133                         else if(pChain[i].nIndexE > nSIndex)\r
134                                 break;\r
135                 }\r
136         }       \r
137         return NULL;\r
138 }\r
139 \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
142 //{\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
147 //      int nPos;\r
148 //      for (nPos = 0; nPos < nGuessedPos; nPos++)\r
149 //      {\r
150 //              cwc.IndexToPlain();\r
151 //              cwc.PlainToHash();\r
152 //              cwc.HashToIndex(nPos);\r
153 //              // Not using checkpoints atm\r
154 //              /*\r
155 //              switch(nPos)\r
156 //              {\r
157 //              case 5000:\r
158 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)\r
159 //                              {\r
160 //                                      m_nTotalFalseAlarmSkipped += 10000 - 5000;\r
161 ////                                    printf("CheckPoint caught false alarm at position 7600\n");\r
162 //                                      return false;\r
163 //                              }\r
164 //                              break;\r
165 //              case 6000:\r
166 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)\r
167 //                              {\r
168 ////                                    printf("CheckPoint caught false alarm at position 8200\n");\r
169 //                                      m_nTotalFalseAlarmSkipped += 10000 - 6000;\r
170 //                                      return false;\r
171 //                              }\r
172 //                              break;\r
173 //\r
174 //              case 7600:\r
175 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)\r
176 //                              {\r
177 ////                                    printf("CheckPoint caught false alarm at position 8700\n");\r
178 //                                      m_nTotalFalseAlarmSkipped += 10000 - 7600;\r
179 //                                      return false;\r
180 //                              }\r
181 //                              break;\r
182 //\r
183 //              case 8200:\r
184 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)\r
185 //                              {\r
186 ////                                    printf("CheckPoint caught false alarm at position 9000\n");\r
187 //                                      m_nTotalFalseAlarmSkipped += 10000 - 8200;\r
188 //                                      return false;\r
189 //                              }\r
190 //                              break;\r
191 //\r
192 //                      case 8700:\r
193 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)\r
194 //                              {\r
195 ////                                    printf("CheckPoint caught false alarm at position 9300\n");\r
196 //                                      m_nTotalFalseAlarmSkipped += 10000 - 8700;\r
197 //                                      return false;\r
198 //                              }\r
199 //\r
200 //                              break;\r
201 //                      case 9000:\r
202 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)\r
203 //                              {\r
204 ////                                    printf("CheckPoint caught false alarm at position 9600\n");\r
205 //                                      m_nTotalFalseAlarmSkipped += 10000 - 9000;\r
206 //                                      return false;\r
207 //                              }\r
208 //\r
209 //                              break;\r
210 //                      case 9300:\r
211 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)\r
212 //                              {\r
213 ////                                    printf("CheckPoint caught false alarm at position 9600\n");\r
214 //                                      m_nTotalFalseAlarmSkipped += 10000 - 9300;\r
215 //                                      return false;\r
216 //                              }\r
217 //                              break;\r
218 //                      case 9600:\r
219 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))\r
220 //                              {\r
221 ////                                    printf("CheckPoint caught false alarm at position 9600\n");\r
222 //                                      m_nTotalFalseAlarmSkipped += 10000 - 9600;\r
223 //                                      return false;\r
224 //                              }\r
225 //                              break;\r
226 //\r
227 //              }*/\r
228 //      }\r
229 //      cwc.IndexToPlain();\r
230 //      cwc.PlainToHash();\r
231 //      if (cwc.CheckHash(pHash))\r
232 //      {\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
235 //              return true;\r
236 //      }\r
237 //\r
238 //      return false;\r
239 //}\r
240 \r
241 //bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)\r
242 //{\r
243 //      CChainWalkContext cwc;\r
244 //      cwc.SetIndex(pChain->nIndexS);\r
245 //      int nPos;\r
246 //      for (nPos = 0; nPos < nGuessedPos; nPos++)\r
247 //      {\r
248 //              cwc.IndexToPlain();\r
249 //              cwc.PlainToHash();\r
250 //              cwc.HashToIndex(nPos);\r
251 //      }\r
252 //      cwc.IndexToPlain();\r
253 //      cwc.PlainToHash();\r
254 //      if (cwc.CheckHash(pHash))\r
255 //      {\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
258 //              return true;\r
259 //      }\r
260 //\r
261 //      return false;\r
262 //}\r
263 \r
264 void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,\r
265                                                                                                           int nRainbowChainCount,\r
266                                                                                                           int nMatchingIndexE,\r
267                                                                                                           int& nMatchingIndexEFrom,\r
268                                                                                                           int& nMatchingIndexETo)\r
269 {\r
270         nMatchingIndexEFrom = nMatchingIndexE;\r
271         nMatchingIndexETo   = nMatchingIndexE;\r
272         while (nMatchingIndexEFrom > 0)\r
273         {\r
274                 if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
275                         nMatchingIndexEFrom--;\r
276                 else\r
277                         break;\r
278         }\r
279         while (nMatchingIndexETo < nRainbowChainCount - 1)\r
280         {\r
281                 if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
282                         nMatchingIndexETo++;\r
283                 else\r
284                         break;\r
285         }\r
286 }\r
287 \r
288 void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)\r
289 {\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
294 \r
295         int nChainWalkStep = 0;\r
296         int nFalseAlarm = 0;\r
297         int nChainWalkStepDueToFalseAlarm = 0;\r
298 \r
299         vector<rcrackiThread*> threadPool;\r
300         vector<pthread_t> pThreads;\r
301 \r
302         pthread_attr_t attr;\r
303         pthread_attr_init(&attr);\r
304         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
305         #ifdef _WIN32\r
306         sched_param param;\r
307         param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
308         pthread_attr_setschedparam (&attr, &param);\r
309         #endif\r
310         // XXX else set it to 5 or something (for linux)?\r
311 \r
312         bool pausing = false;\r
313 \r
314         UINT4 nHashIndex;\r
315         for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
316         {\r
317                 #ifdef _WIN32\r
318                 if (_kbhit())\r
319                 {\r
320                         int ch = _getch();\r
321                         ch = toupper(ch);\r
322                         if (ch == 'P')\r
323                         {\r
324                                 pausing = true;\r
325                                 printf( "\nPausing, press P again to continue... ");\r
326 \r
327                                 timeval tv;\r
328                                 timeval tv2;\r
329                                 timeval final;\r
330                                 gettimeofday( &tv, NULL );\r
331 \r
332                                 while (pausing)\r
333                                 {\r
334                                         if (_kbhit())\r
335                                         {\r
336                                                 ch = _getch();\r
337                                                 ch = toupper(ch);\r
338                                                 if (ch == 'P')\r
339                                                 {\r
340                                                         printf( " [Continuing]\n");\r
341                                                         pausing = false;\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
346                                                 }\r
347                                         }\r
348                                         Sleep(500);\r
349                                 }\r
350                         }\r
351                         else\r
352                         {\r
353                                 printf( "\nPress 'P' to pause...\n");\r
354                         }\r
355                 }\r
356                 #else\r
357                 int c = tty_getchar();\r
358                 if (c >= 0) {\r
359                         tty_flush();\r
360                         if (c==112) { // = p\r
361                                 pausing = true;\r
362                                 printf( "\nPausing, press 'p' again to continue... ");\r
363                                 \r
364                                 timeval tv;\r
365                                 timeval tv2;\r
366                                 timeval final;\r
367                                 gettimeofday( &tv, NULL );\r
368                                 \r
369                                 while (pausing)\r
370                                 {\r
371                                         if ((c = tty_getchar()) >= 0)\r
372                                         {\r
373                                                 tty_flush();\r
374                                                 if (c == 112)\r
375                                                 {\r
376                                                         printf( " [Continuing]\n");\r
377                                                         pausing = false;\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
382                                                 }\r
383                                         }\r
384                                         usleep(500*1000);\r
385                                 }\r
386                         }\r
387                         else {\r
388                                 printf( "\nPress 'p' to pause...\n");\r
389                         }\r
390                 }\r
391                 #endif\r
392                 unsigned char TargetHash[MAX_HASH_LEN];\r
393                 int nHashLen;\r
394                 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
395                 if (nHashLen != CChainWalkContext::GetHashLen())\r
396                         printf("debug: nHashLen mismatch\n");\r
397 \r
398                 // Rqeuest ChainWalk\r
399                 bool fNewlyGenerated;\r
400                 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
401                                                                                                         nHashLen,\r
402                                                                                                         CChainWalkContext::GetHashRoutineName(),\r
403                                                                                                         CChainWalkContext::GetPlainCharsetName(),\r
404                                                                                                         CChainWalkContext::GetPlainLenMin(),\r
405                                                                                                         CChainWalkContext::GetPlainLenMax(),\r
406                                                                                                         CChainWalkContext::GetRainbowTableIndex(),\r
407                                                                                                         nRainbowChainLen,\r
408                                                                                                         fNewlyGenerated,\r
409                                                                                                         debug,\r
410                                                                                                         sPrecalcPathName);\r
411                 //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",\r
412                 //                                                                              vHash[nHashIndex].c_str());\r
413 \r
414                 // Walk\r
415                 if (fNewlyGenerated)\r
416                 {\r
417                         timeval tv;\r
418                         timeval tv2;\r
419                         timeval final;\r
420 \r
421                         gettimeofday( &tv, NULL );\r
422 \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
426                         pThreads.clear();\r
427                         \r
428                         UINT4 thread_ID;\r
429                         for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
430                         {\r
431                                 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
432                                 if (r_Thread)\r
433                                 {\r
434                                         pthread_t pThread;\r
435                                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
436 \r
437                                         if( returnValue != 0 )\r
438                                         {\r
439                                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
440                                         }\r
441                                         else\r
442                                         {\r
443                                                 pThreads.push_back(pThread);\r
444                                         }\r
445 \r
446                                         threadPool.push_back(r_Thread);\r
447                                 }\r
448                                 else \r
449                                 {\r
450                                         printf("r_Thread creation failed!\n");\r
451                                 }\r
452                         }\r
453                         \r
454                         //printf("%d r_Threads created\t\t\n", threadPool.size());\r
455                         \r
456                         for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
457                         {\r
458                                 pthread_t pThread = pThreads[thread_ID];\r
459                                 int returnValue = pthread_join(pThread, NULL);\r
460                                 if( returnValue != 0 )\r
461                                 {\r
462                                         printf("pThread join failed, returnValue: %d\n", returnValue);\r
463                                 }\r
464                                         \r
465                                 rcrackiThread* rThread = threadPool[thread_ID];\r
466                                 nChainWalkStep += rThread->GetChainWalkStep();\r
467                         }\r
468 \r
469                         gettimeofday( &tv2, NULL );\r
470                         final = sub_timeofday( tv2, tv );\r
471                         \r
472                         float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
473 \r
474                         m_fTotalPrecalculationTime += fTime;\r
475                         m_fTotalCryptanalysisTime -= fTime;\r
476 \r
477                         printf("%-50s\r", "");\r
478 \r
479                         if ( debug )\r
480                                 printf("pre-calculation time: %.2f s\n", fTime);\r
481                 }\r
482 \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
486 \r
487                 threadPool.clear();\r
488                 pThreads.clear();\r
489 \r
490                 int i;\r
491                 for (i = 0; i < maxThreads; i++)\r
492                 {\r
493                         rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);\r
494                         threadPool.push_back(r_Thread);\r
495                 }\r
496 \r
497                 UINT4 thread_ID = 0;\r
498                 int nPos;\r
499                 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
500                 {\r
501                         uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
502                 \r
503                         // Search matching nIndexE\r
504                         int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);\r
505                         if (nMatchingIndexE != -1)\r
506                         {\r
507                                 int nMatchingIndexEFrom, nMatchingIndexETo;\r
508                                 GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,\r
509                                                                                                    nMatchingIndexE,\r
510                                                                                                    nMatchingIndexEFrom, nMatchingIndexETo);\r
511                                 int i;\r
512                                 for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)\r
513                                 {\r
514                                         rcrackiThread* rThread = threadPool[thread_ID];\r
515                                         rThread->AddAlarmCheckO(pChain + i, nPos);\r
516                                         if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
517                                                 thread_ID++;\r
518                                         } else {\r
519                                                 thread_ID = 0;\r
520                                         }\r
521                                 }\r
522                         }\r
523                 }\r
524 \r
525                 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
526                 {\r
527                         rcrackiThread* r_Thread = threadPool[thread_ID];\r
528                         pthread_t pThread;\r
529 \r
530                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
531 \r
532                         if( returnValue != 0 )\r
533                         {\r
534                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
535                         }\r
536                         else\r
537                         {\r
538                                 pThreads.push_back(pThread);\r
539                         }\r
540                 }\r
541                 \r
542                 //printf("%d r_Threads created\t\t\n", threadPool.size());\r
543 \r
544                 bool foundHashInThread = false;\r
545                 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
546                 {\r
547                         rcrackiThread* rThread = threadPool[thread_ID];\r
548                         pthread_t pThread = pThreads[thread_ID];\r
549 \r
550                         int returnValue = pthread_join(pThread, NULL);\r
551                         if( returnValue != 0 )\r
552                         {\r
553                                 printf("pThread join failed, returnValue: %d\n", returnValue);\r
554                         }\r
555 \r
556                         nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
557                         nFalseAlarm += rThread->GetnFalseAlarm();\r
558 \r
559                         if (rThread->FoundHash() && !foundHashInThread) {\r
560                                 //printf("\t\t\t\t\t\t\r");\r
561                                 printf("%-50s\r", "");\r
562 \r
563                                 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());\r
564                                 if (writeOutput)\r
565                                 {\r
566                                         if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
567                                                 printf("Couldn't write this result to file!\n");\r
568                                 }\r
569                                 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
570 \r
571                                 FILE* file = fopen(sSessionPathName.c_str(), "a");\r
572                                 if (file!=NULL)\r
573                                 {\r
574                                         string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
575                                         fputs (buffer.c_str(), file);\r
576                                         fclose (file);\r
577                                 }\r
578 \r
579                                 m_cws.DiscardWalk(pStartPosIndexE);\r
580                                 foundHashInThread = true;\r
581                         }\r
582                 }\r
583 \r
584                 pThreads.clear();\r
585                 threadPool.clear();\r
586         }\r
587 \r
588         //printf("\t\t\t\t\t\t\t\r");\r
589         printf("%-50s\r", "");\r
590         pThreads.clear();\r
591         threadPool.clear();\r
592         pthread_attr_destroy(&attr);\r
593 \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
597 \r
598         m_nTotalChainWalkStep += nChainWalkStep;\r
599         m_nTotalFalseAlarm += nFalseAlarm;\r
600         m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
601 }\r
602 \r
603 void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)\r
604 {\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
611 \r
612         int nChainWalkStep = 0;\r
613         int nFalseAlarm = 0;\r
614         int nChainWalkStepDueToFalseAlarm = 0;\r
615 \r
616         vector<rcrackiThread*> threadPool;\r
617         vector<pthread_t> pThreads;\r
618 \r
619         pthread_attr_t attr;\r
620         pthread_attr_init(&attr);\r
621         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
622         #ifdef _WIN32\r
623         sched_param param;\r
624         param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
625         pthread_attr_setschedparam (&attr, &param);\r
626         #endif\r
627         // else set it to 5 or something (for linux)?\r
628 \r
629         bool pausing = false;\r
630 \r
631         UINT4 nHashIndex;\r
632         for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
633         {\r
634                 #ifdef _WIN32\r
635                 if (_kbhit())\r
636                 {\r
637                         int ch = _getch();\r
638                         ch = toupper(ch);\r
639                         if (ch == 'P')\r
640                         {\r
641                                 pausing = true;\r
642                                 printf( "\nPausing, press P again to continue... ");\r
643                                 \r
644                                 timeval tv;\r
645                                 timeval tv2;\r
646                                 timeval final;\r
647                                 gettimeofday( &tv, NULL );\r
648 \r
649                                 while (pausing)\r
650                                 {\r
651                                         if (_kbhit())\r
652                                         {\r
653                                                 ch = _getch();\r
654                                                 ch = toupper(ch);\r
655                                                 if (ch == 'P')\r
656                                                 {\r
657                                                         printf( " [Continuing]\n");\r
658                                                         pausing = false;\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
663                                                 }\r
664                                         }\r
665                                         Sleep(500);\r
666                                 }\r
667                         }\r
668                         else\r
669                         {\r
670                                 printf( "\nPress 'P' to pause...\n");\r
671                         }\r
672                 }\r
673                 #else\r
674                 int c = tty_getchar();\r
675                 if (c >= 0) {\r
676                         tty_flush();\r
677                         if (c==112) { // = p\r
678                                 pausing = true;\r
679                                 printf( "\nPausing, press 'p' again to continue... ");\r
680 \r
681                                 timeval tv;\r
682                                 timeval tv2;\r
683                                 timeval final;\r
684                                 gettimeofday( &tv, NULL );\r
685 \r
686                                 while (pausing)\r
687                                 {\r
688                                         if ((c = tty_getchar()) >= 0)\r
689                                         {\r
690                                                 tty_flush();\r
691                                                 if (c == 112)\r
692                                                 {\r
693                                                         printf( " [Continuing]\n");\r
694                                                         pausing = false;\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
699                                                 }\r
700                                         }\r
701                                         usleep(500*1000);\r
702                                 }\r
703                         }\r
704                         else {\r
705                                 printf( "\nPress 'p' to pause...\n");\r
706                         }\r
707                 }\r
708                 #endif\r
709                 unsigned char TargetHash[MAX_HASH_LEN];\r
710                 int nHashLen;\r
711                 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
712                 if (nHashLen != CChainWalkContext::GetHashLen())\r
713                         printf("debug: nHashLen mismatch\n");\r
714 \r
715                 // Request ChainWalk\r
716                 bool fNewlyGenerated;\r
717 //              printf("Requesting walk...");\r
718                  \r
719 \r
720                 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
721                                                                                                         nHashLen,\r
722                                                                                                         CChainWalkContext::GetHashRoutineName(),\r
723                                                                                                         CChainWalkContext::GetPlainCharsetName(),\r
724                                                                                                         CChainWalkContext::GetPlainLenMin(),\r
725                                                                                                         CChainWalkContext::GetPlainLenMax(),\r
726                                                                                                         CChainWalkContext::GetRainbowTableIndex(),\r
727                                                                                                         nRainbowChainLen,\r
728                                                                                                         fNewlyGenerated,\r
729                                                                                                         debug,\r
730                                                                                                         sPrecalcPathName);\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
734 \r
735                 if (fNewlyGenerated)\r
736                 {\r
737                         timeval tv;\r
738                         timeval tv2;\r
739                         timeval final;\r
740 \r
741                         gettimeofday( &tv, NULL );\r
742 \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
746                         pThreads.clear();\r
747                         \r
748                         UINT4 thread_ID;\r
749                         for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
750                         {\r
751                                 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
752                                 if (r_Thread)\r
753                                 {\r
754                                         pthread_t pThread;\r
755                                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
756 \r
757                                         if( returnValue != 0 )\r
758                                         {\r
759                                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
760                                         }\r
761                                         else\r
762                                         {\r
763                                                 pThreads.push_back(pThread);\r
764                                         }\r
765 \r
766                                         threadPool.push_back(r_Thread);\r
767                                 }\r
768                                 else \r
769                                 {\r
770                                         printf("r_Thread creation failed!\n");\r
771                                 }\r
772                         }\r
773                         \r
774                         //printf("%d r_Threads created\t\t\n", threadPool.size());\r
775                         \r
776                         for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
777                         {\r
778                                 pthread_t pThread = pThreads[thread_ID];\r
779                                 int returnValue = pthread_join(pThread, NULL);\r
780                                 if( returnValue != 0 )\r
781                                 {\r
782                                         printf("pThread join failed, returnValue: %d\n", returnValue);\r
783                                 }\r
784                                         \r
785                                 rcrackiThread* rThread = threadPool[thread_ID];\r
786                                 nChainWalkStep += rThread->GetChainWalkStep();\r
787                                 delete rThread;\r
788                         }\r
789 \r
790                         m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);\r
791                         gettimeofday( &tv2, NULL );\r
792                         final = sub_timeofday( tv2, tv );\r
793                         \r
794                         float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
795 \r
796                         m_fTotalPrecalculationTime += fTime;\r
797                         m_fTotalCryptanalysisTime -= fTime;\r
798 \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
801 \r
802                         printf("%-50s\r", "");\r
803 \r
804                         if ( debug )\r
805                                 printf("pre-calculation time: %.2f s\n", fTime);\r
806                 }\r
807 \r
808                 threadPool.clear();\r
809                 pThreads.clear();\r
810 \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
814 \r
815                 int i;\r
816                 for (i = 0; i < maxThreads; i++)\r
817                 {\r
818                         rcrackiThread* r_Thread = new rcrackiThread(TargetHash);\r
819                         threadPool.push_back(r_Thread);\r
820                 }\r
821 \r
822                 UINT4 thread_ID = 0;\r
823                 int nPos;\r
824                 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
825                 {\r
826                         uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
827                 \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
831                         {\r
832                                 rcrackiThread* rThread = threadPool[thread_ID];\r
833                                 rThread->AddAlarmCheck(pChainFound, nPos);\r
834                                 if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
835                                         thread_ID++;\r
836                                 } else {\r
837                                         thread_ID = 0;\r
838                                 }\r
839                         }\r
840                 }\r
841 \r
842                 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
843                 {\r
844                         rcrackiThread* r_Thread = threadPool[thread_ID];\r
845                         pthread_t pThread;\r
846 \r
847                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
848 \r
849                         if( returnValue != 0 )\r
850                         {\r
851                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
852                         }\r
853                         else\r
854                         {\r
855                                 pThreads.push_back(pThread);\r
856                         }\r
857                 }\r
858                 \r
859                 //printf("%d r_Threads created\t\t\n", threadPool.size());\r
860 \r
861                 bool foundHashInThread = false;\r
862                 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
863                 {\r
864                         rcrackiThread* rThread = threadPool[thread_ID];\r
865                         pthread_t pThread = pThreads[thread_ID];\r
866 \r
867                         int returnValue = pthread_join(pThread, NULL);\r
868                         if( returnValue != 0 )\r
869                         {\r
870                                 printf("pThread join failed, returnValue: %d\n", returnValue);\r
871                         }\r
872 \r
873                         nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
874                         nFalseAlarm += rThread->GetnFalseAlarm();\r
875 \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
880                                 if (writeOutput)\r
881                                 {\r
882                                         if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
883                                                 printf("Couldn't write this result to file!\n");\r
884                                 }\r
885                                 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
886                                 \r
887                                 FILE* file = fopen(sSessionPathName.c_str(), "a");\r
888                                 if (file!=NULL)\r
889                                 {\r
890                                         string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
891                                         fputs (buffer.c_str(), file);\r
892                                         fclose (file);\r
893                                 }\r
894 \r
895                                 m_cws.DiscardWalk(pStartPosIndexE);\r
896                                 foundHashInThread = true;\r
897                         }\r
898                         //pthread\r
899                         delete rThread;\r
900                 }\r
901 \r
902                 pThreads.clear();\r
903                 threadPool.clear();\r
904 \r
905                 //printf("\t\t\t\t\r");\r
906                 //printf("pChainFounds: %d\n", pChainsFound.size());\r
907 //NEXT_HASH:;\r
908         }\r
909         //printf("\t\t\t\t\t\t\t\r");\r
910         printf("%-50s\r", "");\r
911         pThreads.clear();\r
912         threadPool.clear();\r
913         pthread_attr_destroy(&attr);\r
914 \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
918 \r
919         m_nTotalChainWalkStep += nChainWalkStep;\r
920         m_nTotalFalseAlarm += nFalseAlarm;\r
921         m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
922 }\r
923 \r
924 void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)\r
925 {\r
926         // Did we already go through this file in this session?\r
927         if (resumeSession)\r
928         {\r
929                 vector<string> sessionFinishedPathNames;\r
930                 if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))\r
931                 {\r
932                         UINT4 i;\r
933                         for (i = 0; i < sessionFinishedPathNames.size(); i++)\r
934                         {\r
935                                 if (sessionFinishedPathNames[i] == sPathName)\r
936                                 {\r
937                                         printf("Skipping %s\n", sPathName.c_str());\r
938                                         return;\r
939                                 }\r
940                         }\r
941                 }\r
942         }\r
943 \r
944         // FileName\r
945 #ifdef _WIN32\r
946         int nIndex = sPathName.find_last_of('\\');\r
947 #else\r
948         int nIndex = (int) sPathName.find_last_of('/');\r
949 #endif\r
950         string sFileName;\r
951         if (nIndex != -1)\r
952                 sFileName = sPathName.substr(nIndex + 1);\r
953         else\r
954                 sFileName = sPathName;\r
955 \r
956         // Info\r
957         printf("%s:\n", sFileName.c_str());\r
958 \r
959         // Setup\r
960         int nRainbowChainLen, nRainbowChainCount;\r
961         if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))\r
962                 return;\r
963         //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());\r
964         // Already finished?\r
965         if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
966         {\r
967                 printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());\r
968                 return;\r
969         }\r
970 \r
971         // Open\r
972         FILE* file = fopen(sPathName.c_str(), "rb");\r
973         if (file != NULL)\r
974         {\r
975                 // File length check\r
976                 bool doOldFormat = CChainWalkContext::isOldFormat();\r
977                 bool doRti2Format = CChainWalkContext::isRti2Format();\r
978                 UINT4 sizeOfChain;\r
979                 bool fVerified = false;\r
980                 UINT4 nFileLen = GetFileLen(file);\r
981 \r
982                 if (doOldFormat)\r
983                         sizeOfChain = 16;\r
984                 else\r
985                         sizeOfChain = 8;\r
986 \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
990                 else\r
991                 {\r
992                         fseek(file, 0, SEEK_SET);\r
993                         timeval tv;\r
994                         timeval tv2;\r
995                         timeval final;\r
996 \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
999 \r
1000                         uint64 nAllocatedSize;\r
1001 \r
1002                         if (doRti2Format || doOldFormat)\r
1003                         {\r
1004                                 RTI2Reader *pReader = NULL;\r
1005 \r
1006                                 if(doRti2Format) {\r
1007                                         pReader = new RTI2Reader(sPathName);\r
1008 \r
1009                                 }\r
1010 \r
1011                                 if (debug)\r
1012                                 {\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
1017                                 }\r
1018 \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
1023                                 {\r
1024                                         nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary\r
1025 \r
1026                                         //fseek(file, 0, SEEK_SET);\r
1027                                         //bool fVerified = false;\r
1028                                         while (true)    // Chunk read loop\r
1029                                         {\r
1030                                                 if ((unsigned long)ftell(file) == nFileLen)\r
1031                                                         break;\r
1032 \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
1038                                                 {\r
1039                                                         nDataRead = nAllocatedSize / 16;\r
1040                                                         pReader->ReadChains(nDataRead, pChain);\r
1041                                                         nDataRead *= 8; // Convert from chains read to bytes\r
1042 \r
1043                                                         if ( nDataRead == 0 ) // No more data\r
1044                                                                 break;\r
1045                                                 }\r
1046                                                 else\r
1047                                                 {\r
1048                                                         nDataRead = fread(pChain, 1, nAllocatedSize, file);\r
1049                                                 }\r
1050                                                 gettimeofday( &tv2, NULL );\r
1051                                                 final = sub_timeofday( tv2, tv );\r
1052 \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
1056 \r
1057                                                 int nRainbowChainCountRead = nDataRead / 16;\r
1058 \r
1059                                                 // Verify table chunk\r
1060                                                 if (!fVerified)\r
1061                                                 {\r
1062                                                         printf("verifying the file...\n");\r
1063 \r
1064                                                         // Chain length test\r
1065                                                         int nIndexToVerify = nRainbowChainCountRead / 2;\r
1066                                                         CChainWalkContext cwc;\r
1067                                                         cwc.SetIndex(pChain[nIndexToVerify].nIndexS);\r
1068                                                         int nPos;\r
1069                                                         for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
1070                                                         {\r
1071                                                                 cwc.IndexToPlain();\r
1072                                                                 cwc.PlainToHash();\r
1073                                                                 cwc.HashToIndex(nPos);\r
1074                                                         }\r
1075                                                         if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)\r
1076                                                         {\r
1077                                                                 printf("rainbow chain length verify fail\n");\r
1078                                                                 break;\r
1079                                                         }\r
1080 \r
1081                                                         // Chain sort test\r
1082                                                         int i;\r
1083                                                         for (i = 0; i < nRainbowChainCountRead - 1; i++)\r
1084                                                         {\r
1085                                                                 if (pChain[i].nIndexE > pChain[i + 1].nIndexE)\r
1086                                                                         break;\r
1087                                                         }\r
1088                                                         if (i != nRainbowChainCountRead - 1)\r
1089                                                         {\r
1090                                                                 printf("this file is not sorted\n");\r
1091                                                                 break;\r
1092                                                         }\r
1093 \r
1094                                                         fVerified = true;\r
1095                                                 }\r
1096 \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
1105 \r
1106                                                 // Already finished?\r
1107                                                 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
1108                                                         break;\r
1109                                         }\r
1110                                 }\r
1111                                 else\r
1112                                         printf("memory allocation fail\n");\r
1113                                 \r
1114                                 //delete pChain;\r
1115                         }\r
1116                         else\r
1117                         {\r
1118                                 static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);\r
1119                                 uint64 nAllocatedSizeIndex;\r
1120 \r
1121                                 //int nIndexSize = 0;\r
1122                                 //IndexChain *pIndex = NULL;\r
1123 \r
1124                                 FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");\r
1125                                 if(fIndex != NULL)\r
1126                                 {\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
1134                                         else\r
1135                                         {\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
1140                                 \r
1141                                                 static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);\r
1142                                                 \r
1143                                                 if (pIndex != NULL && nAllocatedSizeIndex > 0)\r
1144                                                 {\r
1145                                                         nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain);            // Round to sizeOfIndexChain boundary\r
1146                                                 \r
1147                                                         fseek(fIndex, 0, SEEK_SET);\r
1148 \r
1149                                                         while ( (unsigned long)ftell(fIndex) != nFileLenIndex ) // Index chunk read loop\r
1150                                                         {\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
1159 \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
1163                                                         \r
1164                                                                 //nIndexSize = nFileLenIndex / 11;\r
1165                                                                 int nIndexChainCountRead = nDataRead / sizeof(IndexChain);\r
1166                                                                 //fclose(fIndex);\r
1167                                                                 unsigned int nCoveredRainbowTableChains = 0;\r
1168                                                                 for(int i = 0; i < nIndexChainCountRead; i++)\r
1169                                                                 {\r
1170                                                                         nCoveredRainbowTableChains += pIndex[i].nChainCount;\r
1171                                                                 }\r
1172 \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
1176 \r
1177                                                                 if (pChain != NULL && nAllocatedSize > 0)\r
1178                                                                 {\r
1179                                                                         nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary\r
1180 \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
1186                                                                         {\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
1195 \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
1201                                                                                 \r
1202                                                                                 if (!fVerified)\r
1203                                                                                 {\r
1204                                                                                         printf("verifying the file... ");\r
1205 \r
1206                                                                                         // Chain length test\r
1207                                                                                         int nIndexToVerify = nRainbowChainCountRead / 2;\r
1208                                                                                         CChainWalkContext cwc;\r
1209                                                                                         uint64 nIndexS;\r
1210                                                                                         nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes\r
1211 \r
1212                                                                                         //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());\r
1213                                                                                         cwc.SetIndex(nIndexS);\r
1214                                                                                         \r
1215                                                                                         int nPos;\r
1216                                                                                         for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
1217                                                                                         {\r
1218                                                                                                 cwc.IndexToPlain();\r
1219                                                                                                 cwc.PlainToHash();\r
1220                                                                                                 cwc.HashToIndex(nPos);\r
1221                                                                                         }\r
1222 \r
1223                                                                                         uint64 nEndPoint = 0;\r
1224 \r
1225                                                                                         //for(int i = 0; i < nIndexSize; i++)\r
1226                                                                                         for(int i = 0; i < nIndexChainCountRead; i++)\r
1227                                                                                         {\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
1235                                                                                                         break;\r
1236                                                                                                 }\r
1237                                                                                         }\r
1238 \r
1239                                                                                         if (cwc.GetIndex() != nEndPoint)\r
1240                                                                                         {\r
1241                                                                                                 printf("rainbow chain length verify fail\n");\r
1242                                                                                                 break;\r
1243                                                                                         }\r
1244 \r
1245                                                                                         fVerified = true;\r
1246                                                                                         printf("ok\n");\r
1247                                                                                 }\r
1248 \r
1249                                                                                 // Search table chunk\r
1250                                                                                 gettimeofday( &tv, NULL );\r
1251                                                                                 float preTime = m_fTotalCryptanalysisTime;\r
1252 \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
1257 \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
1264                                                                                         break;\r
1265                                                                         }\r
1266                                                                 }\r
1267                                                                 else printf("memory allocation failed for rainbow table\n");\r
1268 \r
1269                                                                 //delete pChain;\r
1270                                                         }\r
1271                                                 }\r
1272                                                 else printf("memory allocation failed for index\n");\r
1273                                         }               \r
1274                                 }\r
1275                                 else \r
1276                                 {\r
1277                                         printf("Can't load index\n");\r
1278                                         return;\r
1279                                 }\r
1280                                 fclose(fIndex);\r
1281                                 \r
1282                                 //delete pIndex;\r
1283                         }\r
1284                 }\r
1285                 fclose(file);\r
1286 \r
1287                 if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());\r
1288                 FILE* file = fopen(sProgressPathName.c_str(), "a");\r
1289                 if (file!=NULL)\r
1290                 {\r
1291                         string buffer = sPathName + "\n";\r
1292                         fputs (buffer.c_str(), file);\r
1293                         fclose (file);\r
1294                 }\r
1295         }\r
1296         else\r
1297                 printf("can't open file\n");\r
1298 }\r
1299 \r
1300 void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)\r
1301 {\r
1302 #ifndef _WIN32\r
1303         tty_init();\r
1304 #endif\r
1305         resumeSession = resume;\r
1306         debug = bDebug;\r
1307 \r
1308         maxThreads = i_maxThreads;\r
1309         maxMem = i_maxMem;\r
1310         // Reset statistics\r
1311         ResetStatistics();\r
1312 \r
1313         // Sort vPathName (CChainWalkSet need it)\r
1314         UINT4 i, j;\r
1315         for (i = 0; i < vPathName.size() - 1; i++)\r
1316                 for (j = 0; j < vPathName.size() - i - 1; j++)\r
1317                 {\r
1318                         if (vPathName[j] > vPathName[j + 1])\r
1319                         {\r
1320                                 string sTemp;\r
1321                                 sTemp = vPathName[j];\r
1322                                 vPathName[j] = vPathName[j + 1];\r
1323                                 vPathName[j + 1] = sTemp;\r
1324                         }\r
1325                 }\r
1326 \r
1327         // Run\r
1328         for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)\r
1329         {\r
1330                 SearchRainbowTable(vPathName[i], hs);\r
1331                 printf("\n");\r
1332         }\r
1333 \r
1334         // delete precalc files\r
1335         if (!keepPrecalcFiles)\r
1336                 m_cws.removePrecalcFiles();\r
1337 \r
1338 #ifndef _WIN32\r
1339         tty_done();\r
1340 #endif\r
1341 }\r
1342 \r
1343 void CCrackEngine::setOutputFile(string sPathName)\r
1344 {\r
1345         writeOutput = true;\r
1346         outputFile = sPathName;\r
1347 }\r
1348 \r
1349 void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)\r
1350 {\r
1351         sSessionPathName = sSession;\r
1352         sProgressPathName = sProgress;\r
1353         sPrecalcPathName = sPrecalc;\r
1354         keepPrecalcFiles = keepPrecalc;\r
1355 }\r
1356 \r
1357 float CCrackEngine::GetStatTotalDiskAccessTime()\r
1358 {\r
1359         return m_fTotalDiskAccessTime;\r
1360 }\r
1361 /*float CCrackEngine::GetWastedTime()\r
1362 {\r
1363         return m_fIndexTime;\r
1364 }*/\r
1365 float CCrackEngine::GetStatTotalCryptanalysisTime()\r
1366 {\r
1367         return m_fTotalCryptanalysisTime;\r
1368 }\r
1369 \r
1370 float CCrackEngine::GetStatTotalPrecalculationTime()\r
1371 {\r
1372         return m_fTotalPrecalculationTime;\r
1373 }\r
1374 \r
1375 int CCrackEngine::GetStatTotalChainWalkStep()\r
1376 {\r
1377         return m_nTotalChainWalkStep;\r
1378 }\r
1379 \r
1380 int CCrackEngine::GetStatTotalFalseAlarm()\r
1381 {\r
1382         return m_nTotalFalseAlarm;\r
1383 }\r
1384 \r
1385 int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()\r
1386 {\r
1387         return m_nTotalChainWalkStepDueToFalseAlarm;\r
1388 }\r