]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/CrackEngine.cpp
Merge branch 'master' of git@gitorious.org:freerainbowtables-applications/freerainbow...
[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 2009, 2010 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 rcracki_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 #if defined(_WIN32) && !defined(__GNUC__)\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 #ifndef _WIN32\r
35         #include <sys/resource.h>\r
36 #endif\r
37 \r
38 CCrackEngine::CCrackEngine()\r
39 {\r
40         ResetStatistics();\r
41         writeOutput = false;\r
42         resumeSession = false;\r
43         debug = false;\r
44         keepPrecalcFiles = false;\r
45 \r
46         sSessionPathName = "";\r
47         sProgressPathName = "";\r
48 }\r
49 \r
50 CCrackEngine::~CCrackEngine()\r
51 {\r
52 }\r
53 \r
54 //////////////////////////////////////////////////////////////////////\r
55 \r
56 void CCrackEngine::ResetStatistics()\r
57 {\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
65 }\r
66 \r
67 int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)\r
68 {\r
69         int nLow = 0;\r
70         int nHigh = nRainbowChainCount - 1;\r
71         while (nLow <= nHigh)\r
72         {\r
73                 int nMid = (nLow + nHigh) / 2;\r
74                 if (nIndex == pChain[nMid].nIndexE)\r
75                         return nMid;\r
76                 else if (nIndex < pChain[nMid].nIndexE)\r
77                         nHigh = nMid - 1;\r
78                 else\r
79                         nLow = nMid + 1;\r
80         }\r
81 \r
82         return -1;\r
83 }\r
84 \r
85 RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)\r
86 {\r
87         uint64 nPrefix = nIndex >> 16;\r
88         int nLow, nHigh;        \r
89         bool found = false;\r
90         //int nChains = 0;\r
91         \r
92         if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file\r
93         {\r
94                 return NULL;\r
95         }\r
96 \r
97         int nBLow = 0;\r
98         int nBHigh = nIndexSize - 1;\r
99         while (nBLow <= nBHigh)\r
100         {\r
101                 int nBMid = (nBLow + nBHigh) / 2;\r
102                 if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
103                 {\r
104                         //nLow = nChains;\r
105                         //int nChains = 0;\r
106 \r
107                         nLow = pIndex[nBMid].nFirstChain;\r
108                         nHigh = nLow + pIndex[nBMid].nChainCount;\r
109                         if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead) \r
110                         {                                       \r
111                                 if(nHigh > nIndexStart + nChainCountRead)\r
112                                         nHigh = nIndexStart + nChainCountRead;\r
113                         }\r
114                         else if(nLow < nIndexStart && nHigh >= nIndexStart)\r
115                         {\r
116                                 nLow = nIndexStart;\r
117                         }\r
118                         else break;                                     \r
119                         found = true;\r
120                         break;\r
121                 }\r
122                 else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
123                         nBHigh = nBMid - 1;\r
124                 else\r
125                         nBLow = nBMid + 1;\r
126         }\r
127         if(found == true)\r
128         {\r
129                 for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)\r
130                 {\r
131                         int nSIndex = ((int)nIndex) & 0x0000FFFF;\r
132 \r
133                         if (nSIndex == pChain[i].nIndexE)\r
134                         {\r
135                                 return &pChain[i];\r
136                         }                               \r
137                         else if(pChain[i].nIndexE > nSIndex)\r
138                                 break;\r
139                 }\r
140         }       \r
141         return NULL;\r
142 }\r
143 \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
146 //{\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
151 //      int nPos;\r
152 //      for (nPos = 0; nPos < nGuessedPos; nPos++)\r
153 //      {\r
154 //              cwc.IndexToPlain();\r
155 //              cwc.PlainToHash();\r
156 //              cwc.HashToIndex(nPos);\r
157 //              // Not using checkpoints atm\r
158 //              /*\r
159 //              switch(nPos)\r
160 //              {\r
161 //              case 5000:\r
162 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)\r
163 //                              {\r
164 //                                      m_nTotalFalseAlarmSkipped += 10000 - 5000;\r
165 ////                                    printf("CheckPoint caught false alarm at position 7600\n");\r
166 //                                      return false;\r
167 //                              }\r
168 //                              break;\r
169 //              case 6000:\r
170 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)\r
171 //                              {\r
172 ////                                    printf("CheckPoint caught false alarm at position 8200\n");\r
173 //                                      m_nTotalFalseAlarmSkipped += 10000 - 6000;\r
174 //                                      return false;\r
175 //                              }\r
176 //                              break;\r
177 //\r
178 //              case 7600:\r
179 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)\r
180 //                              {\r
181 ////                                    printf("CheckPoint caught false alarm at position 8700\n");\r
182 //                                      m_nTotalFalseAlarmSkipped += 10000 - 7600;\r
183 //                                      return false;\r
184 //                              }\r
185 //                              break;\r
186 //\r
187 //              case 8200:\r
188 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)\r
189 //                              {\r
190 ////                                    printf("CheckPoint caught false alarm at position 9000\n");\r
191 //                                      m_nTotalFalseAlarmSkipped += 10000 - 8200;\r
192 //                                      return false;\r
193 //                              }\r
194 //                              break;\r
195 //\r
196 //                      case 8700:\r
197 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)\r
198 //                              {\r
199 ////                                    printf("CheckPoint caught false alarm at position 9300\n");\r
200 //                                      m_nTotalFalseAlarmSkipped += 10000 - 8700;\r
201 //                                      return false;\r
202 //                              }\r
203 //\r
204 //                              break;\r
205 //                      case 9000:\r
206 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)\r
207 //                              {\r
208 ////                                    printf("CheckPoint caught false alarm at position 9600\n");\r
209 //                                      m_nTotalFalseAlarmSkipped += 10000 - 9000;\r
210 //                                      return false;\r
211 //                              }\r
212 //\r
213 //                              break;\r
214 //                      case 9300:\r
215 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)\r
216 //                              {\r
217 ////                                    printf("CheckPoint caught false alarm at position 9600\n");\r
218 //                                      m_nTotalFalseAlarmSkipped += 10000 - 9300;\r
219 //                                      return false;\r
220 //                              }\r
221 //                              break;\r
222 //                      case 9600:\r
223 //                              if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))\r
224 //                              {\r
225 ////                                    printf("CheckPoint caught false alarm at position 9600\n");\r
226 //                                      m_nTotalFalseAlarmSkipped += 10000 - 9600;\r
227 //                                      return false;\r
228 //                              }\r
229 //                              break;\r
230 //\r
231 //              }*/\r
232 //      }\r
233 //      cwc.IndexToPlain();\r
234 //      cwc.PlainToHash();\r
235 //      if (cwc.CheckHash(pHash))\r
236 //      {\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
239 //              return true;\r
240 //      }\r
241 //\r
242 //      return false;\r
243 //}\r
244 \r
245 //bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)\r
246 //{\r
247 //      CChainWalkContext cwc;\r
248 //      cwc.SetIndex(pChain->nIndexS);\r
249 //      int nPos;\r
250 //      for (nPos = 0; nPos < nGuessedPos; nPos++)\r
251 //      {\r
252 //              cwc.IndexToPlain();\r
253 //              cwc.PlainToHash();\r
254 //              cwc.HashToIndex(nPos);\r
255 //      }\r
256 //      cwc.IndexToPlain();\r
257 //      cwc.PlainToHash();\r
258 //      if (cwc.CheckHash(pHash))\r
259 //      {\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
262 //              return true;\r
263 //      }\r
264 //\r
265 //      return false;\r
266 //}\r
267 \r
268 void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,\r
269                                                                                                           int nRainbowChainCount,\r
270                                                                                                           int nMatchingIndexE,\r
271                                                                                                           int& nMatchingIndexEFrom,\r
272                                                                                                           int& nMatchingIndexETo)\r
273 {\r
274         nMatchingIndexEFrom = nMatchingIndexE;\r
275         nMatchingIndexETo   = nMatchingIndexE;\r
276         while (nMatchingIndexEFrom > 0)\r
277         {\r
278                 if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
279                         nMatchingIndexEFrom--;\r
280                 else\r
281                         break;\r
282         }\r
283         while (nMatchingIndexETo < nRainbowChainCount - 1)\r
284         {\r
285                 if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
286                         nMatchingIndexETo++;\r
287                 else\r
288                         break;\r
289         }\r
290 }\r
291 \r
292 void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)\r
293 {\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
298 \r
299         int nChainWalkStep = 0;\r
300         int nFalseAlarm = 0;\r
301         int nChainWalkStepDueToFalseAlarm = 0;\r
302 \r
303         vector<rcrackiThread*> threadPool;\r
304         vector<pthread_t> pThreads;\r
305 \r
306         #ifndef _WIN32\r
307                 /*\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
312                  */\r
313                 setpriority( PRIO_PROCESS, 0, 2 );\r
314         #endif\r
315 \r
316         pthread_attr_t attr;\r
317         pthread_attr_init(&attr);\r
318         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
319         #ifdef _WIN32\r
320         sched_param param;\r
321         /*\r
322          * windows scheduling is 0 to 32 (low to high) with 8 as normal and 7 as\r
323          * BELOW_NORMAL\r
324          */\r
325         param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
326         pthread_attr_setschedparam (&attr, &param);\r
327         #endif\r
328 \r
329         bool pausing = false;\r
330 \r
331         uint32 nHashIndex;\r
332         for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
333         {\r
334                 #ifdef _WIN32\r
335                 if (_kbhit())\r
336                 {\r
337                         int ch = _getch();\r
338                         ch = toupper(ch);\r
339                         if (ch == 'P')\r
340                         {\r
341                                 pausing = true;\r
342                                 printf( "\nPausing, press P again to continue... ");\r
343 \r
344                                 timeval tv;\r
345                                 timeval tv2;\r
346                                 timeval final;\r
347                                 gettimeofday( &tv, NULL );\r
348 \r
349                                 while (pausing)\r
350                                 {\r
351                                         if (_kbhit())\r
352                                         {\r
353                                                 ch = _getch();\r
354                                                 ch = toupper(ch);\r
355                                                 if (ch == 'P')\r
356                                                 {\r
357                                                         printf( " [Continuing]\n");\r
358                                                         pausing = false;\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
363                                                 }\r
364                                         }\r
365                                         Sleep(500);\r
366                                 }\r
367                         }\r
368                         else\r
369                         {\r
370                                 printf( "\nPress 'P' to pause...\n");\r
371                         }\r
372                 }\r
373                 #else\r
374                 int c = tty_getchar();\r
375                 if (c >= 0) {\r
376                         tty_flush();\r
377                         if (c==112) { // = p\r
378                                 pausing = true;\r
379                                 printf( "\nPausing, press 'p' again to continue... ");\r
380                                 \r
381                                 timeval tv;\r
382                                 timeval tv2;\r
383                                 timeval final;\r
384                                 gettimeofday( &tv, NULL );\r
385                                 \r
386                                 while (pausing)\r
387                                 {\r
388                                         if ((c = tty_getchar()) >= 0)\r
389                                         {\r
390                                                 tty_flush();\r
391                                                 if (c == 112)\r
392                                                 {\r
393                                                         printf( " [Continuing]\n");\r
394                                                         pausing = false;\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
399                                                 }\r
400                                         }\r
401                                         usleep(500*1000);\r
402                                 }\r
403                         }\r
404                         else {\r
405                                 printf( "\nPress 'p' to pause...\n");\r
406                         }\r
407                 }\r
408                 #endif\r
409                 unsigned char TargetHash[MAX_HASH_LEN];\r
410                 int nHashLen;\r
411                 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
412                 if (nHashLen != CChainWalkContext::GetHashLen())\r
413                         printf("debug: nHashLen mismatch\n");\r
414 \r
415                 // Rqeuest ChainWalk\r
416                 bool fNewlyGenerated;\r
417                 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
418                                                                                                         nHashLen,\r
419                                                                                                         CChainWalkContext::GetHashRoutineName(),\r
420                                                                                                         CChainWalkContext::GetPlainCharsetName(),\r
421                                                                                                         CChainWalkContext::GetPlainLenMin(),\r
422                                                                                                         CChainWalkContext::GetPlainLenMax(),\r
423                                                                                                         CChainWalkContext::GetRainbowTableIndex(),\r
424                                                                                                         nRainbowChainLen,\r
425                                                                                                         fNewlyGenerated,\r
426                                                                                                         debug,\r
427                                                                                                         sPrecalcPathName);\r
428                 //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",\r
429                 //                                                                              vHash[nHashIndex].c_str());\r
430 \r
431                 // Walk\r
432                 if (fNewlyGenerated)\r
433                 {\r
434                         timeval tv;\r
435                         timeval tv2;\r
436                         timeval final;\r
437 \r
438                         gettimeofday( &tv, NULL );\r
439 \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
443                         pThreads.clear();\r
444                         \r
445                         uint32 thread_ID;\r
446                         for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
447                         {\r
448                                 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
449                                 if (r_Thread)\r
450                                 {\r
451                                         pthread_t pThread;\r
452                                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
453 \r
454                                         if( returnValue != 0 )\r
455                                         {\r
456                                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
457                                         }\r
458                                         else\r
459                                         {\r
460                                                 pThreads.push_back(pThread);\r
461                                         }\r
462 \r
463                                         threadPool.push_back(r_Thread);\r
464                                 }\r
465                                 else \r
466                                 {\r
467                                         printf("r_Thread creation failed!\n");\r
468                                 }\r
469                         }\r
470                         \r
471                         //printf("%d r_Threads created\t\t\n", threadPool.size());\r
472                         \r
473                         for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
474                         {\r
475                                 pthread_t pThread = pThreads[thread_ID];\r
476                                 int returnValue = pthread_join(pThread, NULL);\r
477                                 if( returnValue != 0 )\r
478                                 {\r
479                                         printf("pThread join failed, returnValue: %d\n", returnValue);\r
480                                 }\r
481                                         \r
482                                 rcrackiThread* rThread = threadPool[thread_ID];\r
483                                 nChainWalkStep += rThread->GetChainWalkStep();\r
484                         }\r
485 \r
486                         gettimeofday( &tv2, NULL );\r
487                         final = sub_timeofday( tv2, tv );\r
488                         \r
489                         float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
490 \r
491                         m_fTotalPrecalculationTime += fTime;\r
492                         m_fTotalCryptanalysisTime -= fTime;\r
493 \r
494                         printf("%-50s\r", "");\r
495 \r
496                         if ( debug )\r
497                                 printf("pre-calculation time: %.2f s\n", fTime);\r
498                 }\r
499 \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
503 \r
504                 threadPool.clear();\r
505                 pThreads.clear();\r
506 \r
507                 int i;\r
508                 for (i = 0; i < maxThreads; i++)\r
509                 {\r
510                         rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);\r
511                         threadPool.push_back(r_Thread);\r
512                 }\r
513 \r
514                 uint32 thread_ID = 0;\r
515                 int nPos;\r
516                 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
517                 {\r
518                         uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
519                 \r
520                         // Search matching nIndexE\r
521                         int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);\r
522                         if (nMatchingIndexE != -1)\r
523                         {\r
524                                 int nMatchingIndexEFrom, nMatchingIndexETo;\r
525                                 GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,\r
526                                                                                                    nMatchingIndexE,\r
527                                                                                                    nMatchingIndexEFrom, nMatchingIndexETo);\r
528                                 int i;\r
529                                 for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)\r
530                                 {\r
531                                         rcrackiThread* rThread = threadPool[thread_ID];\r
532                                         rThread->AddAlarmCheckO(pChain + i, nPos);\r
533                                         if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
534                                                 thread_ID++;\r
535                                         } else {\r
536                                                 thread_ID = 0;\r
537                                         }\r
538                                 }\r
539                         }\r
540                 }\r
541 \r
542                 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
543                 {\r
544                         rcrackiThread* r_Thread = threadPool[thread_ID];\r
545                         pthread_t pThread;\r
546 \r
547                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
548 \r
549                         if( returnValue != 0 )\r
550                         {\r
551                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
552                         }\r
553                         else\r
554                         {\r
555                                 pThreads.push_back(pThread);\r
556                         }\r
557                 }\r
558                 \r
559                 //printf("%d r_Threads created\t\t\n", threadPool.size());\r
560 \r
561                 bool foundHashInThread = false;\r
562                 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
563                 {\r
564                         rcrackiThread* rThread = threadPool[thread_ID];\r
565                         pthread_t pThread = pThreads[thread_ID];\r
566 \r
567                         int returnValue = pthread_join(pThread, NULL);\r
568                         if( returnValue != 0 )\r
569                         {\r
570                                 printf("pThread join failed, returnValue: %d\n", returnValue);\r
571                         }\r
572 \r
573                         nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
574                         nFalseAlarm += rThread->GetnFalseAlarm();\r
575 \r
576                         if (rThread->FoundHash() && !foundHashInThread) {\r
577                                 //printf("\t\t\t\t\t\t\r");\r
578                                 printf("%-50s\r", "");\r
579 \r
580                                 printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());\r
581                                 if (writeOutput)\r
582                                 {\r
583                                         if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
584                                                 printf("Couldn't write this result to file!\n");\r
585                                 }\r
586                                 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
587 \r
588                                 FILE* file = fopen(sSessionPathName.c_str(), "a");\r
589                                 if (file!=NULL)\r
590                                 {\r
591                                         string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
592                                         fputs (buffer.c_str(), file);\r
593                                         fclose (file);\r
594                                 }\r
595 \r
596                                 m_cws.DiscardWalk(pStartPosIndexE);\r
597                                 foundHashInThread = true;\r
598                         }\r
599                 }\r
600 \r
601                 pThreads.clear();\r
602                 threadPool.clear();\r
603         }\r
604 \r
605         //printf("\t\t\t\t\t\t\t\r");\r
606         printf("%-50s\r", "");\r
607         pThreads.clear();\r
608         threadPool.clear();\r
609         pthread_attr_destroy(&attr);\r
610 \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
614 \r
615         m_nTotalChainWalkStep += nChainWalkStep;\r
616         m_nTotalFalseAlarm += nFalseAlarm;\r
617         m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
618 }\r
619 \r
620 void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)\r
621 {\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
628 \r
629         int nChainWalkStep = 0;\r
630         int nFalseAlarm = 0;\r
631         int nChainWalkStepDueToFalseAlarm = 0;\r
632 \r
633         vector<rcrackiThread*> threadPool;\r
634         vector<pthread_t> pThreads;\r
635         \r
636         #ifndef _WIN32\r
637                 /*\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
642                  */\r
643                 setpriority( PRIO_PROCESS, 0, 2 );\r
644         #endif\r
645 \r
646         pthread_attr_t attr;\r
647         pthread_attr_init(&attr);\r
648         pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
649         #ifdef _WIN32\r
650         sched_param param;\r
651         param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
652         pthread_attr_setschedparam (&attr, &param);\r
653         #endif\r
654         // else set it to 5 or something (for linux)?\r
655 \r
656         bool pausing = false;\r
657 \r
658         uint32 nHashIndex;\r
659         for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
660         {\r
661                 #ifdef _WIN32\r
662                 if (_kbhit())\r
663                 {\r
664                         int ch = _getch();\r
665                         ch = toupper(ch);\r
666                         if (ch == 'P')\r
667                         {\r
668                                 pausing = true;\r
669                                 printf( "\nPausing, press P again to continue... ");\r
670                                 \r
671                                 timeval tv;\r
672                                 timeval tv2;\r
673                                 timeval final;\r
674                                 gettimeofday( &tv, NULL );\r
675 \r
676                                 while (pausing)\r
677                                 {\r
678                                         if (_kbhit())\r
679                                         {\r
680                                                 ch = _getch();\r
681                                                 ch = toupper(ch);\r
682                                                 if (ch == 'P')\r
683                                                 {\r
684                                                         printf( " [Continuing]\n");\r
685                                                         pausing = false;\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
690                                                 }\r
691                                         }\r
692                                         Sleep(500);\r
693                                 }\r
694                         }\r
695                         else\r
696                         {\r
697                                 printf( "\nPress 'P' to pause...\n");\r
698                         }\r
699                 }\r
700                 #else\r
701                 int c = tty_getchar();\r
702                 if (c >= 0) {\r
703                         tty_flush();\r
704                         if (c==112) { // = p\r
705                                 pausing = true;\r
706                                 printf( "\nPausing, press 'p' again to continue... ");\r
707 \r
708                                 timeval tv;\r
709                                 timeval tv2;\r
710                                 timeval final;\r
711                                 gettimeofday( &tv, NULL );\r
712 \r
713                                 while (pausing)\r
714                                 {\r
715                                         if ((c = tty_getchar()) >= 0)\r
716                                         {\r
717                                                 tty_flush();\r
718                                                 if (c == 112)\r
719                                                 {\r
720                                                         printf( " [Continuing]\n");\r
721                                                         pausing = false;\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
726                                                 }\r
727                                         }\r
728                                         usleep(500*1000);\r
729                                 }\r
730                         }\r
731                         else {\r
732                                 printf( "\nPress 'p' to pause...\n");\r
733                         }\r
734                 }\r
735                 #endif\r
736                 unsigned char TargetHash[MAX_HASH_LEN];\r
737                 int nHashLen;\r
738                 ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
739                 if (nHashLen != CChainWalkContext::GetHashLen())\r
740                         printf("debug: nHashLen mismatch\n");\r
741 \r
742                 // Request ChainWalk\r
743                 bool fNewlyGenerated;\r
744 //              printf("Requesting walk...");\r
745                  \r
746 \r
747                 uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
748                                                                                                         nHashLen,\r
749                                                                                                         CChainWalkContext::GetHashRoutineName(),\r
750                                                                                                         CChainWalkContext::GetPlainCharsetName(),\r
751                                                                                                         CChainWalkContext::GetPlainLenMin(),\r
752                                                                                                         CChainWalkContext::GetPlainLenMax(),\r
753                                                                                                         CChainWalkContext::GetRainbowTableIndex(),\r
754                                                                                                         nRainbowChainLen,\r
755                                                                                                         fNewlyGenerated,\r
756                                                                                                         debug,\r
757                                                                                                         sPrecalcPathName);\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
761 \r
762                 if (fNewlyGenerated)\r
763                 {\r
764                         timeval tv;\r
765                         timeval tv2;\r
766                         timeval final;\r
767 \r
768                         gettimeofday( &tv, NULL );\r
769 \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
773                         pThreads.clear();\r
774                         \r
775                         uint32 thread_ID;\r
776                         for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
777                         {\r
778                                 rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
779                                 if (r_Thread)\r
780                                 {\r
781                                         pthread_t pThread;\r
782                                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
783 \r
784                                         if( returnValue != 0 )\r
785                                         {\r
786                                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
787                                         }\r
788                                         else\r
789                                         {\r
790                                                 pThreads.push_back(pThread);\r
791                                         }\r
792 \r
793                                         threadPool.push_back(r_Thread);\r
794                                 }\r
795                                 else \r
796                                 {\r
797                                         printf("r_Thread creation failed!\n");\r
798                                 }\r
799                         }\r
800                         \r
801                         //printf("%d r_Threads created\t\t\n", threadPool.size());\r
802                         \r
803                         for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
804                         {\r
805                                 pthread_t pThread = pThreads[thread_ID];\r
806                                 int returnValue = pthread_join(pThread, NULL);\r
807                                 if( returnValue != 0 )\r
808                                 {\r
809                                         printf("pThread join failed, returnValue: %d\n", returnValue);\r
810                                 }\r
811                                         \r
812                                 rcrackiThread* rThread = threadPool[thread_ID];\r
813                                 nChainWalkStep += rThread->GetChainWalkStep();\r
814                                 delete rThread;\r
815                         }\r
816 \r
817                         m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);\r
818                         gettimeofday( &tv2, NULL );\r
819                         final = sub_timeofday( tv2, tv );\r
820                         \r
821                         float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
822 \r
823                         m_fTotalPrecalculationTime += fTime;\r
824                         m_fTotalCryptanalysisTime -= fTime;\r
825 \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
828 \r
829                         printf("%-50s\r", "");\r
830 \r
831                         if ( debug )\r
832                                 printf("pre-calculation time: %.2f s\n", fTime);\r
833                 }\r
834 \r
835                 threadPool.clear();\r
836                 pThreads.clear();\r
837 \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
841 \r
842                 int i;\r
843                 for (i = 0; i < maxThreads; i++)\r
844                 {\r
845                         rcrackiThread* r_Thread = new rcrackiThread(TargetHash);\r
846                         threadPool.push_back(r_Thread);\r
847                 }\r
848 \r
849                 uint32 thread_ID = 0;\r
850                 int nPos;\r
851                 for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
852                 {\r
853                         uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
854                 \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
858                         {\r
859                                 rcrackiThread* rThread = threadPool[thread_ID];\r
860                                 rThread->AddAlarmCheck(pChainFound, nPos);\r
861                                 if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
862                                         thread_ID++;\r
863                                 } else {\r
864                                         thread_ID = 0;\r
865                                 }\r
866                         }\r
867                 }\r
868 \r
869                 for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
870                 {\r
871                         rcrackiThread* r_Thread = threadPool[thread_ID];\r
872                         pthread_t pThread;\r
873 \r
874                         int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
875 \r
876                         if( returnValue != 0 )\r
877                         {\r
878                                 printf("pThread creation failed, returnValue: %d\n", returnValue);\r
879                         }\r
880                         else\r
881                         {\r
882                                 pThreads.push_back(pThread);\r
883                         }\r
884                 }\r
885                 \r
886                 //printf("%d r_Threads created\t\t\n", threadPool.size());\r
887 \r
888                 bool foundHashInThread = false;\r
889                 for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
890                 {\r
891                         rcrackiThread* rThread = threadPool[thread_ID];\r
892                         pthread_t pThread = pThreads[thread_ID];\r
893 \r
894                         int returnValue = pthread_join(pThread, NULL);\r
895                         if( returnValue != 0 )\r
896                         {\r
897                                 printf("pThread join failed, returnValue: %d\n", returnValue);\r
898                         }\r
899 \r
900                         nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
901                         nFalseAlarm += rThread->GetnFalseAlarm();\r
902 \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
907                                 if (writeOutput)\r
908                                 {\r
909                                         if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
910                                                 printf("Couldn't write this result to file!\n");\r
911                                 }\r
912                                 hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
913                                 \r
914                                 FILE* file = fopen(sSessionPathName.c_str(), "a");\r
915                                 if (file!=NULL)\r
916                                 {\r
917                                         string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
918                                         fputs (buffer.c_str(), file);\r
919                                         fclose (file);\r
920                                 }\r
921 \r
922                                 m_cws.DiscardWalk(pStartPosIndexE);\r
923                                 foundHashInThread = true;\r
924                         }\r
925                         //pthread\r
926                         delete rThread;\r
927                 }\r
928 \r
929                 pThreads.clear();\r
930                 threadPool.clear();\r
931 \r
932                 //printf("\t\t\t\t\r");\r
933                 //printf("pChainFounds: %d\n", pChainsFound.size());\r
934 //NEXT_HASH:;\r
935         }\r
936         //printf("\t\t\t\t\t\t\t\r");\r
937         printf("%-50s\r", "");\r
938         pThreads.clear();\r
939         threadPool.clear();\r
940         pthread_attr_destroy(&attr);\r
941 \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
945 \r
946         m_nTotalChainWalkStep += nChainWalkStep;\r
947         m_nTotalFalseAlarm += nFalseAlarm;\r
948         m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
949 }\r
950 \r
951 void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)\r
952 {\r
953         // Did we already go through this file in this session?\r
954         if (resumeSession)\r
955         {\r
956                 vector<string> sessionFinishedPathNames;\r
957                 if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))\r
958                 {\r
959                         uint32 i;\r
960                         for (i = 0; i < sessionFinishedPathNames.size(); i++)\r
961                         {\r
962                                 if (sessionFinishedPathNames[i] == sPathName)\r
963                                 {\r
964                                         printf("Skipping %s\n", sPathName.c_str());\r
965                                         return;\r
966                                 }\r
967                         }\r
968                 }\r
969         }\r
970 \r
971         // FileName\r
972 #ifdef _WIN32\r
973         string::size_type nIndex = sPathName.find_last_of('\\');\r
974 #else\r
975         string::size_type nIndex = sPathName.find_last_of('/');\r
976 #endif\r
977         string sFileName;\r
978         if (nIndex != string::npos)\r
979                 sFileName = sPathName.substr(nIndex + 1);\r
980         else\r
981                 sFileName = sPathName;\r
982 \r
983         // Info\r
984         printf("%s:\n", sFileName.c_str());\r
985 \r
986         // Setup\r
987         int nRainbowChainLen, nRainbowChainCount;\r
988         if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))\r
989                 return;\r
990         //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());\r
991         // Already finished?\r
992         if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
993         {\r
994                 printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());\r
995                 return;\r
996         }\r
997 \r
998         // Open\r
999         FILE* file = fopen(sPathName.c_str(), "rb");\r
1000         if (file != NULL)\r
1001         {\r
1002                 // File length check\r
1003                 bool doOldFormat = CChainWalkContext::isOldFormat();\r
1004                 bool doRti2Format = CChainWalkContext::isRti2Format();\r
1005                 uint32 sizeOfChain;\r
1006                 bool fVerified = false;\r
1007                 long nFileLen = GetFileLen(file);\r
1008 \r
1009                 if (doOldFormat)\r
1010                         sizeOfChain = 16;\r
1011                 else\r
1012                         sizeOfChain = 8;\r
1013 \r
1014                 //if (nFileLen % 8 != 0 || nRainbowChainCount * 8 != nFileLen)\r
1015                 if ( ( (unsigned long)nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != (unsigned long)nFileLen) && doRti2Format == false )\r
1016                         printf("file length mismatch\n");\r
1017                 else\r
1018                 {\r
1019                         fseek(file, 0, SEEK_SET);\r
1020                         timeval tv;\r
1021                         timeval tv2;\r
1022                         timeval final;\r
1023 \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
1026 \r
1027                         uint64 nAllocatedSize;\r
1028 \r
1029                         if (doRti2Format || doOldFormat)\r
1030                         {\r
1031                                 RTI2Reader *pReader = NULL;\r
1032 \r
1033                                 if(doRti2Format) {\r
1034                                         pReader = new RTI2Reader(sPathName);\r
1035 \r
1036                                 }\r
1037 \r
1038                                 if (debug)\r
1039                                 {\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
1044                                 }\r
1045 \r
1046                                 static CMemoryPool mp(bytesForChainWalkSet, debug, maxMem);\r
1047                                 RainbowChainO* pChain = NULL;\r
1048                                 if(doRti2Format) {\r
1049                                         pChain = (RainbowChainO*)mp.Allocate(pReader->GetChainsLeft() * 16, nAllocatedSize);\r
1050                                 } else {\r
1051                                         pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);\r
1052                                 }\r
1053                                 #if defined(_WIN32) && !defined(__GNUC__)\r
1054                                         if (debug) printf("Allocated %I64 bytes, filelen %ld\n", nAllocatedSize, nFileLen);\r
1055                                 #else\r
1056                                         if (debug) printf("Allocated %llu bytes, filelen %ld\n", nAllocatedSize, nFileLen);\r
1057                                 #endif\r
1058 \r
1059                                 if (pChain != NULL)\r
1060                                 {\r
1061                                         nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary\r
1062 \r
1063                                         //fseek(file, 0, SEEK_SET);\r
1064                                         //bool fVerified = false;\r
1065                                         while (true)    // Chunk read loop\r
1066                                         {\r
1067                                                 if (ftell(file) == nFileLen)\r
1068                                                         break;\r
1069 \r
1070                                                 // Load table chunk\r
1071                                                 if (debug) printf("reading...\n");\r
1072                                                 unsigned int nDataRead = 0;\r
1073                                                 gettimeofday( &tv, NULL );\r
1074                                                 if ( doRti2Format )\r
1075                                                 {\r
1076                                                         nDataRead = nAllocatedSize / 16;\r
1077                                                         if(pReader->GetChainsLeft() <= 0) // No more data\r
1078                                                                 break; \r
1079                                                         pReader->ReadChains(nDataRead, pChain);\r
1080 \r
1081                                                         nDataRead *= 8; // Convert from chains read to bytes\r
1082                                                 }\r
1083                                                 else\r
1084                                                 {\r
1085                                                         nDataRead = fread(pChain, 1, nAllocatedSize, file);\r
1086                                                 }\r
1087                                                 gettimeofday( &tv2, NULL );\r
1088                                                 final = sub_timeofday( tv2, tv );\r
1089 \r
1090                                                 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
1091                                                 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
1092                                                 m_fTotalDiskAccessTime += fTime;\r
1093 \r
1094                                                 int nRainbowChainCountRead = nDataRead / 16;\r
1095 \r
1096                                                 if(doRti2Format) {\r
1097                                                         nRainbowChainCountRead = nDataRead / 8;\r
1098                                                 }\r
1099 \r
1100                                                 // Verify table chunk\r
1101                                                 if (!fVerified)\r
1102                                                 {\r
1103                                                         printf("verifying the file...\n");\r
1104 \r
1105                                                         // Chain length test\r
1106                                                         int nIndexToVerify = nRainbowChainCountRead / 2;\r
1107                                                         CChainWalkContext cwc;\r
1108                                                         cwc.SetIndex(pChain[nIndexToVerify].nIndexS);\r
1109                                                         int nPos;\r
1110                                                         for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
1111                                                         {\r
1112                                                                 cwc.IndexToPlain();\r
1113                                                                 cwc.PlainToHash();\r
1114                                                                 cwc.HashToIndex(nPos);\r
1115                                                         }\r
1116                                                         if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)\r
1117                                                         {\r
1118                                                                 printf("rainbow chain length verify fail\n");\r
1119                                                                 break;\r
1120                                                         }\r
1121 \r
1122                                                         // Chain sort test\r
1123                                                         int i;\r
1124                                                         for (i = 0; i < nRainbowChainCountRead - 1; i++)\r
1125                                                         {\r
1126                                                                 if (pChain[i].nIndexE > pChain[i + 1].nIndexE)\r
1127                                                                         break;\r
1128                                                         }\r
1129                                                         if (i != nRainbowChainCountRead - 1)\r
1130                                                         {\r
1131                                                                 printf("this file is not sorted\n");\r
1132                                                                 break;\r
1133                                                         }\r
1134 \r
1135                                                         fVerified = true;\r
1136                                                 }\r
1137 \r
1138                                                 // Search table chunk\r
1139                                                 gettimeofday( &tv, NULL );\r
1140                                                 SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);\r
1141                                                 gettimeofday( &tv2, NULL );\r
1142                                                 final = sub_timeofday( tv2, tv );\r
1143                                                 fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
1144                                                 printf("cryptanalysis time: %.2f s\n", fTime);\r
1145                                                 m_fTotalCryptanalysisTime += fTime;\r
1146 \r
1147                                                 // Already finished?\r
1148                                                 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
1149                                                         break;\r
1150 \r
1151 /*\r
1152         // XXX eliminated by PB - check correctness\r
1153                                                 // finished the current table\r
1154                                                 if( doRti2Format && nDataToRead > (nDataRead / 8) )\r
1155                                                 {\r
1156                                                         delete pReader;\r
1157                                                         break;\r
1158                                                 }\r
1159 */\r
1160                                         }\r
1161                                 }\r
1162                                 else\r
1163                                         printf("memory allocation fail\n");\r
1164                                 \r
1165                                 //delete pChain;\r
1166                         }\r
1167                         else\r
1168                         {\r
1169                                 static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);\r
1170                                 uint64 nAllocatedSizeIndex;\r
1171 \r
1172                                 //int nIndexSize = 0;\r
1173                                 //IndexChain *pIndex = NULL;\r
1174 \r
1175                                 FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");\r
1176                                 if(fIndex != NULL)\r
1177                                 {\r
1178                                         // File length check\r
1179                                         long nFileLenIndex = GetFileLen(fIndex);\r
1180                                         //unsigned int nRows = nFileLenIndex / 11;\r
1181                                         //unsigned int nSize = nRows * sizeof(IndexChain);\r
1182                                         //printf("Debug: 8\n");\r
1183                                         if (nFileLenIndex % 11 != 0)\r
1184                                                 printf("index file length mismatch (%ld bytes)\n", nFileLenIndex);\r
1185                                         else\r
1186                                         {\r
1187                                                 //printf("index nSize: %d\n", nSize);\r
1188                                                 //pIndex = (IndexChain*)new unsigned char[nSize];\r
1189                                                 IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);\r
1190                                                 #ifdef _WIN32\r
1191                                                         if (debug) printf("Debug: Allocated %I64u bytes for index with filelen %ld\n", nAllocatedSizeIndex, nFileLenIndex);\r
1192                                                 #else\r
1193                                                         if (debug) printf("Debug: Allocated %llu bytes for index with filelen %ld\n", nAllocatedSizeIndex, nFileLenIndex);\r
1194                                                 #endif\r
1195                                 \r
1196                                                 static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);\r
1197                                                 \r
1198                                                 if (pIndex != NULL && nAllocatedSizeIndex > 0)\r
1199                                                 {\r
1200                                                         nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain);            // Round to sizeOfIndexChain boundary\r
1201                                                 \r
1202                                                         fseek(fIndex, 0, SEEK_SET);\r
1203 \r
1204                                                         while ( ftell(fIndex) != nFileLenIndex )        // Index chunk read loop\r
1205                                                         {\r
1206                                                                 // Load index chunk\r
1207 #ifdef _WIN32\r
1208                                                                 if (debug) printf("Debug: Setting index to 0x00 in memory, %I64u bytes\n", nAllocatedSizeIndex);\r
1209 #else\r
1210                                                                 if (debug) printf("Debug: Setting index to 0x00 in memory, %llu bytes\n", nAllocatedSizeIndex);\r
1211 #endif\r
1212                                                                 memset(pIndex, 0x00, nAllocatedSizeIndex);\r
1213                                                                 printf("reading index... ");\r
1214                                                                 gettimeofday( &tv, NULL );\r
1215                                                                 unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);\r
1216                                                                 gettimeofday( &tv2, NULL );\r
1217                                                                 final = sub_timeofday( tv2, tv );\r
1218 \r
1219                                                                 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
1220                                                                 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
1221                                                                 m_fTotalDiskAccessTime += fTime;\r
1222                                                         \r
1223                                                                 //nIndexSize = nFileLenIndex / 11;\r
1224                                                                 int nIndexChainCountRead = nDataRead / sizeof(IndexChain);\r
1225                                                                 //fclose(fIndex);\r
1226                                                                 unsigned int nCoveredRainbowTableChains = 0;\r
1227                                                                 for(int i = 0; i < nIndexChainCountRead; i++)\r
1228                                                                 {\r
1229                                                                         nCoveredRainbowTableChains += pIndex[i].nChainCount;\r
1230                                                                 }\r
1231 \r
1232                                                                 //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);\r
1233                                                                 RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);\r
1234                                                                 #ifdef _WIN32\r
1235                                                                         if (debug) printf("Debug: Allocated %I64u bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);\r
1236                                                                 #else\r
1237                                                                         if (debug) printf("Debug: Allocated %llu bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);\r
1238                                                                 #endif\r
1239 \r
1240                                                                 if (pChain != NULL && nAllocatedSize > 0)\r
1241                                                                 {\r
1242                                                                         nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary\r
1243 \r
1244                                                                         //fseek(file, 0, SEEK_SET);\r
1245                                                                         //bool fVerified = false;\r
1246                                                                         uint32 nProcessedChains = 0;\r
1247                                                                         while ( ftell(file) != nFileLen \r
1248                                                                                 && nProcessedChains < nCoveredRainbowTableChains )      // Chunk read loop\r
1249                                                                         {\r
1250                                                                                 // Load table chunk\r
1251                                                                                 if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");\r
1252                                                                                 memset(pChain, 0x00, nAllocatedSize);\r
1253                                                                                 printf("reading table... ");\r
1254                                                                                 gettimeofday( &tv, NULL );\r
1255                                                                                 unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);\r
1256                                                                                 gettimeofday( &tv2, NULL );\r
1257                                                                                 final = sub_timeofday( tv2, tv );\r
1258 \r
1259                                                                                 float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
1260                                                                                 printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
1261                                                                                 m_fTotalDiskAccessTime += fTime;\r
1262                                                                                 int nRainbowChainCountRead = nDataRead / sizeOfChain;\r
1263                                                                                 // Verify table chunk (Too lazy to implement this)\r
1264                                                                                 \r
1265                                                                                 if (!fVerified)\r
1266                                                                                 {\r
1267                                                                                         printf("verifying the file... ");\r
1268 \r
1269                                                                                         // Chain length test\r
1270                                                                                         int nIndexToVerify = nRainbowChainCountRead / 2;\r
1271                                                                                         CChainWalkContext cwc;\r
1272                                                                                         uint64 nIndexS;\r
1273                                                                                         nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes\r
1274 \r
1275                                                                                         //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());\r
1276                                                                                         cwc.SetIndex(nIndexS);\r
1277                                                                                         \r
1278                                                                                         int nPos;\r
1279                                                                                         for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
1280                                                                                         {\r
1281                                                                                                 cwc.IndexToPlain();\r
1282                                                                                                 cwc.PlainToHash();\r
1283                                                                                                 cwc.HashToIndex(nPos);\r
1284                                                                                         }\r
1285 \r
1286                                                                                         uint64 nEndPoint = 0;\r
1287 \r
1288                                                                                         //for(int i = 0; i < nIndexSize; i++)\r
1289                                                                                         for(int i = 0; i < nIndexChainCountRead; i++)\r
1290                                                                                         {\r
1291                                                                                                 if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index\r
1292                                                                                                 { // Now we need to seek nIndexToVerify into the chains\r
1293                                                                                                         nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes\r
1294                                                                                                         //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());\r
1295                                                                                                         //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);\r
1296                                                                                                         //printf("nChainCount: %d\n", pIndex[i].nChainCount);\r
1297                                                                                                         nEndPoint += pChain[nIndexToVerify].nIndexE;\r
1298                                                                                                         break;\r
1299                                                                                                 }\r
1300                                                                                         }\r
1301 \r
1302                                                                                         if (cwc.GetIndex() != nEndPoint)\r
1303                                                                                         {\r
1304                                                                                                 printf("rainbow chain length verify fail\n");\r
1305                                                                                                 break;\r
1306                                                                                         }\r
1307 \r
1308                                                                                         fVerified = true;\r
1309                                                                                         printf("ok\n");\r
1310                                                                                 }\r
1311 \r
1312                                                                                 // Search table chunk\r
1313                                                                                 gettimeofday( &tv, NULL );\r
1314                                                                                 float preTime = m_fTotalCryptanalysisTime;\r
1315 \r
1316                                                                                 SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);\r
1317                                                                                 float postTime = m_fTotalCryptanalysisTime;\r
1318                                                                                 gettimeofday( &tv2, NULL );\r
1319                                                                                 final = sub_timeofday( tv2, tv );\r
1320 \r
1321                                                                                 fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
1322                                                                                 printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);\r
1323                                                                                 m_fTotalCryptanalysisTime += fTime;\r
1324                                                                                 nProcessedChains += nRainbowChainCountRead;\r
1325                                                                                 // Already finished?\r
1326                                                                                 if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
1327                                                                                         break;\r
1328                                                                         }\r
1329                                                                 }\r
1330                                                                 else printf("memory allocation failed for rainbow table\n");\r
1331 \r
1332                                                                 //delete pChain;\r
1333                                                         }\r
1334                                                 }\r
1335                                                 else printf("memory allocation failed for index\n");\r
1336                                         }               \r
1337                                 }\r
1338                                 else \r
1339                                 {\r
1340                                         printf("Can't load index\n");\r
1341                                         return;\r
1342                                 }\r
1343                                 fclose(fIndex);\r
1344                                 \r
1345                                 //delete pIndex;\r
1346                         }\r
1347                 }\r
1348                 fclose(file);\r
1349 \r
1350                 if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());\r
1351                 FILE* file = fopen(sProgressPathName.c_str(), "a");\r
1352                 if (file!=NULL)\r
1353                 {\r
1354                         string buffer = sPathName + "\n";\r
1355                         fputs (buffer.c_str(), file);\r
1356                         fclose (file);\r
1357                 }\r
1358         }\r
1359         else\r
1360                 printf("can't open file\n");\r
1361 }\r
1362 \r
1363 void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)\r
1364 {\r
1365 #ifndef _WIN32\r
1366         tty_init();\r
1367 #endif\r
1368         resumeSession = resume;\r
1369         debug = bDebug;\r
1370 \r
1371         maxThreads = i_maxThreads;\r
1372         maxMem = i_maxMem;\r
1373         // Reset statistics\r
1374         ResetStatistics();\r
1375 \r
1376         // Sort vPathName (CChainWalkSet need it)\r
1377         uint32 i, j;\r
1378         for (i = 0; i < vPathName.size() - 1; i++)\r
1379                 for (j = 0; j < vPathName.size() - i - 1; j++)\r
1380                 {\r
1381                         if (vPathName[j] > vPathName[j + 1])\r
1382                         {\r
1383                                 string sTemp;\r
1384                                 sTemp = vPathName[j];\r
1385                                 vPathName[j] = vPathName[j + 1];\r
1386                                 vPathName[j + 1] = sTemp;\r
1387                         }\r
1388                 }\r
1389 \r
1390         // Run\r
1391         for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)\r
1392         {\r
1393                 SearchRainbowTable(vPathName[i], hs);\r
1394                 printf("\n");\r
1395         }\r
1396 \r
1397         // delete precalc files\r
1398         if (!keepPrecalcFiles)\r
1399                 m_cws.removePrecalcFiles();\r
1400 \r
1401 #ifndef _WIN32\r
1402         tty_done();\r
1403 #endif\r
1404 }\r
1405 \r
1406 void CCrackEngine::setOutputFile(string sPathName)\r
1407 {\r
1408         writeOutput = true;\r
1409         outputFile = sPathName;\r
1410 }\r
1411 \r
1412 void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)\r
1413 {\r
1414         sSessionPathName = sSession;\r
1415         sProgressPathName = sProgress;\r
1416         sPrecalcPathName = sPrecalc;\r
1417         keepPrecalcFiles = keepPrecalc;\r
1418 }\r
1419 \r
1420 float CCrackEngine::GetStatTotalDiskAccessTime()\r
1421 {\r
1422         return m_fTotalDiskAccessTime;\r
1423 }\r
1424 /*float CCrackEngine::GetWastedTime()\r
1425 {\r
1426         return m_fIndexTime;\r
1427 }*/\r
1428 float CCrackEngine::GetStatTotalCryptanalysisTime()\r
1429 {\r
1430         return m_fTotalCryptanalysisTime;\r
1431 }\r
1432 \r
1433 float CCrackEngine::GetStatTotalPrecalculationTime()\r
1434 {\r
1435         return m_fTotalPrecalculationTime;\r
1436 }\r
1437 \r
1438 int CCrackEngine::GetStatTotalChainWalkStep()\r
1439 {\r
1440         return m_nTotalChainWalkStep;\r
1441 }\r
1442 \r
1443 int CCrackEngine::GetStatTotalFalseAlarm()\r
1444 {\r
1445         return m_nTotalFalseAlarm;\r
1446 }\r
1447 \r
1448 int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()\r
1449 {\r
1450         return m_nTotalChainWalkStepDueToFalseAlarm;\r
1451 }\r