19 #include "MemoryPool.h"
25 printf("converti2 - Original to Indexed rainbow table converter\n");
26 printf("by Martin Westergaard <martinwj2005@gmail.com>\n");
27 printf("http://www.freerainbowtables.com\n\n");
29 printf("usage: converti2 rainbow_table_pathname\n");
30 printf("rainbow_table_pathname: pathname of the rainbow table(s), wildchar(*, ?) supported\n");
32 printf("example: converti2 *.rt\n");
33 printf(" converti2 md5_*.rt\n");
37 int GetMaxBits(uint64 highvalue)
61 if(highvalue < 0x1000)
63 if(highvalue < 0x2000)
65 if(highvalue < 0x4000)
67 if(highvalue < 0x8000)
69 if(highvalue < 0x10000)
71 if(highvalue < 0x20000)
73 if(highvalue < 0x40000)
75 if(highvalue < 0x80000)
77 if(highvalue < 0x100000)
79 if(highvalue < 0x200000)
81 if(highvalue < 0x400000)
83 if(highvalue < 0x800000)
85 if(highvalue < 0x1000000)
87 if(highvalue < 0x2000000)
89 if(highvalue < 0x4000000)
91 if(highvalue < 0x8000000)
93 if(highvalue < 0x10000000)
95 if(highvalue < 0x20000000)
97 if(highvalue < 0x40000000)
99 if(highvalue < 0x80000000)
102 if(highvalue < 0x0000000100000000I64)
104 if(highvalue < 0x0000000200000000I64)
106 if(highvalue < 0x0000000400000000I64)
108 if(highvalue < 0x0000000800000000I64)
110 if(highvalue < 0x0000001000000000I64)
112 if(highvalue < 0x0000002000000000I64)
114 if(highvalue < 0x0000004000000000I64)
116 if(highvalue < 0x0000008000000000I64)
118 if(highvalue < 0x0000010000000000I64)
120 if(highvalue < 0x0000020000000000I64)
122 if(highvalue < 0x0000040000000000I64)
124 if(highvalue < 0x0000080000000000I64)
126 if(highvalue < 0x0000100000000000I64)
128 if(highvalue < 0x0000200000000000I64)
130 if(highvalue < 0x0000400000000000I64)
132 if(highvalue < 0x0000800000000000I64)
134 if(highvalue < 0x0001000000000000I64)
136 if(highvalue < 0x0002000000000000I64)
138 if(highvalue < 0x0004000000000000I64)
140 if(highvalue < 0x0008000000000000I64)
142 if(highvalue < 0x0010000000000000I64)
144 if(highvalue < 0x0020000000000000I64)
146 if(highvalue < 0x0040000000000000I64)
148 if(highvalue < 0x0080000000000000I64)
150 if(highvalue < 0x0100000000000000I64)
152 if(highvalue < 0x0200000000000000I64)
154 if(highvalue < 0x0400000000000000I64)
156 if(highvalue < 0x0800000000000000I64)
158 if(highvalue < 0x1000000000000000I64)
160 if(highvalue < 0x2000000000000000I64)
162 if(highvalue < 0x4000000000000000I64)
164 if(highvalue < 0x8000000000000000I64)
167 if(highvalue < 0x0000000100000000LL)
169 if(highvalue < 0x0000000200000000LL)
171 if(highvalue < 0x0000000400000000LL)
173 if(highvalue < 0x0000000800000000LL)
175 if(highvalue < 0x0000001000000000LL)
177 if(highvalue < 0x0000002000000000LL)
179 if(highvalue < 0x0000004000000000LL)
181 if(highvalue < 0x0000008000000000LL)
183 if(highvalue < 0x0000010000000000LL)
185 if(highvalue < 0x0000020000000000LL)
187 if(highvalue < 0x0000040000000000LL)
189 if(highvalue < 0x0000080000000000LL)
191 if(highvalue < 0x0000100000000000LL)
193 if(highvalue < 0x0000200000000000LL)
195 if(highvalue < 0x0000400000000000LL)
197 if(highvalue < 0x0000800000000000LL)
199 if(highvalue < 0x0001000000000000LL)
201 if(highvalue < 0x0002000000000000LL)
203 if(highvalue < 0x0004000000000000LL)
205 if(highvalue < 0x0008000000000000LL)
207 if(highvalue < 0x0010000000000000LL)
209 if(highvalue < 0x0020000000000000LL)
211 if(highvalue < 0x0040000000000000LL)
213 if(highvalue < 0x0080000000000000LL)
215 if(highvalue < 0x0100000000000000LL)
217 if(highvalue < 0x0200000000000000LL)
219 if(highvalue < 0x0400000000000000LL)
221 if(highvalue < 0x0800000000000000LL)
223 if(highvalue < 0x1000000000000000LL)
225 if(highvalue < 0x2000000000000000LL)
227 if(highvalue < 0x4000000000000000LL)
229 if(highvalue < 0x8000000000000000LL)
238 void GetTableList(string sWildCharPathName, vector<string>& vPathName)
243 int n = sWildCharPathName.find_last_of('\\');
245 sPath = sWildCharPathName.substr(0, n + 1);
248 long handle = _findfirst(sWildCharPathName.c_str(), &fd);
253 string sName = fd.name;
254 if (sName != "." && sName != ".." && !(fd.attrib & _A_SUBDIR))
256 string sPathName = sPath + sName;
257 vPathName.push_back(sPathName);
259 } while (_findnext(handle, &fd) == 0);
265 void GetTableList(int argc, char* argv[], vector<string>& vPathName)
270 for (i = 1; i < argc; i++)
272 string sPathName = argv[i];
274 if (lstat(sPathName.c_str(), &buf) == 0)
276 if (S_ISREG(buf.st_mode))
277 vPathName.push_back(sPathName);
285 void ConvertRainbowTable(string sPathName, string sResultFileName, unsigned int rti_startptlength, unsigned int rti_endptlength, int showDistribution, int hascp, int rti_cplength, vector<unsigned int> rti_cppos)
288 int nIndex = sPathName.find_last_of('\\');
290 int nIndex = sPathName.find_last_of('/');
294 sFileName = sPathName.substr(nIndex + 1);
296 sFileName = sPathName;
298 printf("%s:\n", sFileName.c_str());
299 FILE* file = fopen(sPathName.c_str(), "rb");
300 FILE* fileR = fopen(sResultFileName.c_str(), "wb");
301 unsigned int distribution[64] = {0};
302 unsigned int numProcessedChains = 0;
304 if (file != NULL && fileR != NULL)
307 UINT4 nFileLen = GetFileLen(file);
308 UINT4 nTotalChainCount = 0;
309 if(hascp == 0) nTotalChainCount = nFileLen / 16;
310 else nTotalChainCount = nFileLen / 18;
311 if ((hascp == 0 && nFileLen % 16 != 0) || (hascp == 1 && nFileLen % 18 != 0))
313 printf("file length mismatch\n");
317 static CMemoryPool mp;
318 unsigned int nAllocatedSize;
319 RainbowChainCP* pChain = (RainbowChainCP*)mp.Allocate(nFileLen, nAllocatedSize);
321 unsigned int chainrowsize = ceil((float)(rti_startptlength + rti_endptlength + rti_cplength) / 8) * 8 ; // The size in bits (in whole bytes)
322 unsigned int chainrowsizebytes = chainrowsize / 8;
327 nAllocatedSize = nAllocatedSize / sizeof(RainbowChainCP) * sizeof(RainbowChainCP);
328 fseek(file, 0, SEEK_SET);
329 uint64 curPrefix = 0, prefixStart = 0;
330 vector<IndexRow> indexes;
331 UINT4 nRainbowChainCountRead = 0;
332 while (true) // Chunk read loop
334 /* if (ftell(file) == nFileLen)
336 UINT4 nReadThisRound;
337 memset(pChain, 0x00, nAllocatedSize);
338 printf("reading...\n");
339 clock_t t1 = clock();
340 for(nReadThisRound = 0; nReadThisRound < nAllocatedSize / sizeof(RainbowChainCP) && nRainbowChainCountRead < nTotalChainCount; nReadThisRound++)
342 if(fread(&pChain[nReadThisRound], 16, 1, file) != 1)
344 printf("Error reading file\n"); exit(1);
348 if(fread(&pChain[nReadThisRound].nCheckPoint, 2, 1, file) != 1)
350 printf("Error reading file\n"); exit(2);
353 nRainbowChainCountRead++;
355 clock_t t2 = clock();
356 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
357 int nDataRead = nRainbowChainCountRead * 16;
358 if(hascp == 1) nDataRead += nRainbowChainCountRead * 2; // Add the index readings too
359 printf("%u bytes read, disk access time: %.2f s\n", nDataRead , fTime);
362 for(UINT4 i = 0; i < nReadThisRound; i++)
364 if(showDistribution == 1)
366 distribution[GetMaxBits(pChain[i].nIndexS)-1]++;
370 uint64 chainrow = pChain[i].nIndexS; // Insert the complete start point
371 chainrow |= ((uint64)pChain[i].nIndexE & (0xffffffff >> (32 - rti_endptlength))) << rti_startptlength; //
372 if(hascp == 1 && rti_cplength > 0)
374 chainrow |= (uint64)pChain[i].nCheckPoint << rti_startptlength + rti_endptlength;
376 fwrite(&chainrow, 1, chainrowsizebytes, fileR);
377 uint64 prefix = pChain[i].nIndexE >> rti_endptlength;
378 if(i == 0) curPrefix = prefix;
379 if(prefix != curPrefix && numProcessedChains - prefixStart > 0)
381 if(prefix < curPrefix)
383 printf("**** Error writeChain(): Prefix is smaller than previous prefix. %llu < %llu****\n", prefix, curPrefix);
386 //unsigned char index[11] = {0}; // [0 - 10]
387 unsigned int numchains = numProcessedChains - prefixStart;
389 index.prefix = curPrefix;
390 // index.prefixstart = prefixStart;
391 index.numchains = numchains;
392 indexes.push_back(index);
393 prefixStart = numProcessedChains;
397 numProcessedChains++;
400 fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
401 printf("conversion time: %.2f s\n", fTime);
402 if(nRainbowChainCountRead == nTotalChainCount)
404 if(showDistribution == 1)
406 for(int i = 0; i < 64; i++)
408 printf("%u - %u\n", (i+1), distribution[i]);
417 // We need to write the last index down
419 index.prefix = curPrefix;
420 index.prefixstart = prefixStart;
421 index.numchains = numProcessedChains - prefixStart;
422 indexes.push_back(index);
424 IndexRow high = {0}; // Used to find the highest numbers. This tells us how much we can pack the index bits
425 for(UINT4 i = 0; i < indexes.size(); i++)
427 if(indexes[i].numchains > high.numchains)
428 high.numchains = indexes[i].numchains;
429 /* if(indexes[i].prefixstart > high.prefixstart)
430 high.prefixstart = indexes[i].prefixstart;
431 if(indexes[i].prefix > high.prefix)
432 high.prefix = indexes[i].prefix;
435 high.prefix = indexes[indexes.size()-1].prefix; // The last prefix is always the highest prefix
436 // unsigned int m_rti_index_prefixlength = GetMaxBits(high.prefix);
437 unsigned int m_rti_index_numchainslength = GetMaxBits(high.numchains);
438 // unsigned int m_rti_index_indexlength = GetMaxBits(high.prefixstart);
439 unsigned int m_indexrowsize = ceil((float)(/*m_rti_index_indexlength + */m_rti_index_numchainslength) / 8) * 8; // The size in bits (in whole bytes)
440 unsigned int m_indexrowsizebytes = m_indexrowsize / 8;
441 FILE *pFileIndex = fopen(sResultFileName.append(".index").c_str(), "wb");
442 fwrite("RTI2", 1, 4, pFileIndex);
443 fwrite(&rti_startptlength, 1, 1, pFileIndex);
444 fwrite(&rti_endptlength, 1, 1, pFileIndex);
445 fwrite(&rti_cplength, 1, 1, pFileIndex);
446 // fwrite(&m_rti_index_indexlength , 1, 1, pFileIndex);
447 fwrite(&m_rti_index_numchainslength, 1, 1, pFileIndex);
448 for(UINT4 i = 0; i < rti_cppos.size(); i++)
450 fwrite(&rti_cppos[i], 1, 4, pFileIndex); // The position of the checkpoints
452 // fwrite(&m_rti_index_prefixlength, 1, 1, pFileIndex);
454 fwrite(&indexes[0].prefix, 1, 8, pFileIndex); // Write the first prefix
455 unsigned int lastPrefix = 0;
456 for(UINT4 i = 0; i < indexes.size(); i++)
459 lastPrefix = indexes[0].prefix;
460 // Checks how big a distance there is between the current and the next prefix. eg cur is 3 and next is 10 = 7.
461 unsigned int diffSize = indexes[i].prefix - lastPrefix;
462 if(i > 0 && diffSize > 1)
464 //indexrow |= indexes[i].prefixstart;
465 //printf("Diffsize is %u\n", diffSize);
467 // then write the distance amount of 00's
468 if(diffSize > 1000) {
469 printf("WARNING! The distance to the next prefix is %i. Do you want to continue writing %i bytes of 0x00? Press y to continue", diffSize, diffSize);
471 if ( _getch() != 'y' ) {
473 if ( tty_getchar() != 'y' ) {
475 printf("Aborting...");
479 for(UINT4 j = 1; j < diffSize; j++)
481 fwrite(&zero, 1, m_indexrowsizebytes, pFileIndex);
484 fwrite(&indexes[i].numchains, 1, m_indexrowsizebytes, pFileIndex);
485 lastPrefix = indexes[i].prefix;
489 else printf("memory allocation fail\n");
498 printf("can't open file\n");
502 int main(int argc, char* argv[])
504 int argi = 1, i, argsUsed = 0;
505 unsigned int sptl = 40, eptl = 16;
506 int showDistribution = 0;
507 int usecp = 0;// How many bits to use from the index
509 vector<unsigned int> cppositions;
517 for (; argi < argc; argi++)
519 if (strcmp(argv[argi], "-d") == 0 && (argsUsed & 0x8) == 0)
521 // Enable verbose mode
523 showDistribution = 1;
525 else if (strncmp(argv[argi], "-sptl=", 6) == 0 && (argsUsed & 0x1) == 0)
527 // Maximum index for starting point
530 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
533 sptl += ((int) argv[argi][i]) - 0x30;
535 if (argv[argi][i] != '\0')
537 printf("Error: Invalid number.\n\n");
541 if (i > 23) // i - 3 > 20
543 printf("Error: Number is too large.\n\n");
549 else if (strncmp(argv[argi], "-eptl=", 6) == 0 && (argsUsed & 0x2) == 0)
551 // Maximum index for ending points
554 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
557 eptl += ((int) argv[argi][i]) - 0x30;
559 if (argv[argi][i] != '\0')
561 printf("Error: Invalid number.\n\n");
565 if (i > 23) // i - 3 > 20
567 printf("Error: Number is too large.\n\n");
572 else if(strncmp(argv[argi], "-usecp=", 7) == 0 && (argsUsed & 0x4) == 0)
577 unsigned int cppos = 0;
578 for(i = 7; argv[argi][i] != ' ' && argv[argi][i] != '\n' && argv[argi][i] != 0;)
580 if(cppositions.size() > 0) i++;
581 for (; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
584 cppos += ((int) argv[argi][i]) - 0x30;
586 /* if(argv[argi][i] == ',')
588 cppositions.push_back(cppos);
593 if (argv[argi][i] != '\0')
595 printf("Error: Invalid number.\n\n");
599 if (usecp > 16) // i - 3 > 20
601 printf("Error: Number is too large.\n\n");
605 else printf("Using %i bits of the checkpoints\n", usecp);
610 vector<string> vPathName;
612 string sWildCharPathName = argv[1];
613 GetTableList(sWildCharPathName, vPathName);
615 GetTableList(argc, argv, vPathName);
617 if (vPathName.size() == 0)
619 printf("no rainbow table found\n");
622 for (UINT4 i = 0; i < vPathName.size(); i++)
625 int n = vPathName[i].find_last_of('\\');
627 sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "i2";
629 sResultFile = vPathName[i] + "i2"; // Resulting file is .rt, not .rti
630 printf("Using %i of 64 bits. sptl: %i, eptl: %i, cp: %i. Chains will be %i bytes in size\n", (sptl + eptl + usecp), sptl, eptl, usecp, ((sptl + eptl + usecp) / 8));
631 if(sptl + eptl + usecp > 64)
635 ConvertRainbowTable(vPathName[i], sResultFile, sptl, eptl, showDistribution, hascp, usecp, cppositions);