16 #include "MemoryPool.h"
21 printf("converti2 - Original to Indexed rainbow table converter\n");
22 printf("by Martin Westergaard <martinwj2005@gmail.com>\n");
23 printf("http://www.freerainbowtables.com\n\n");
25 printf("usage: converti2 rainbow_table_pathname\n");
26 printf("rainbow_table_pathname: pathname of the rainbow table(s), wildchar(*, ?) supported\n");
28 printf("example: converti2 *.rt\n");
29 printf(" converti2 md5_*.rt\n");
33 int GetMaxBits(uint64 highvalue)
57 if(highvalue < 0x1000)
59 if(highvalue < 0x2000)
61 if(highvalue < 0x4000)
63 if(highvalue < 0x8000)
65 if(highvalue < 0x10000)
67 if(highvalue < 0x20000)
69 if(highvalue < 0x40000)
71 if(highvalue < 0x80000)
73 if(highvalue < 0x100000)
75 if(highvalue < 0x200000)
77 if(highvalue < 0x400000)
79 if(highvalue < 0x800000)
81 if(highvalue < 0x1000000)
83 if(highvalue < 0x2000000)
85 if(highvalue < 0x4000000)
87 if(highvalue < 0x8000000)
89 if(highvalue < 0x10000000)
91 if(highvalue < 0x20000000)
93 if(highvalue < 0x40000000)
95 if(highvalue < 0x80000000)
98 if(highvalue < 0x0000000100000000I64)
100 if(highvalue < 0x0000000200000000I64)
102 if(highvalue < 0x0000000400000000I64)
104 if(highvalue < 0x0000000800000000I64)
106 if(highvalue < 0x0000001000000000I64)
108 if(highvalue < 0x0000002000000000I64)
110 if(highvalue < 0x0000004000000000I64)
112 if(highvalue < 0x0000008000000000I64)
114 if(highvalue < 0x0000010000000000I64)
116 if(highvalue < 0x0000020000000000I64)
118 if(highvalue < 0x0000040000000000I64)
120 if(highvalue < 0x0000080000000000I64)
122 if(highvalue < 0x0000100000000000I64)
124 if(highvalue < 0x0000200000000000I64)
126 if(highvalue < 0x0000400000000000I64)
128 if(highvalue < 0x0000800000000000I64)
130 if(highvalue < 0x0001000000000000I64)
132 if(highvalue < 0x0002000000000000I64)
134 if(highvalue < 0x0004000000000000I64)
136 if(highvalue < 0x0008000000000000I64)
138 if(highvalue < 0x0010000000000000I64)
140 if(highvalue < 0x0020000000000000I64)
142 if(highvalue < 0x0040000000000000I64)
144 if(highvalue < 0x0080000000000000I64)
146 if(highvalue < 0x0100000000000000I64)
148 if(highvalue < 0x0200000000000000I64)
150 if(highvalue < 0x0400000000000000I64)
152 if(highvalue < 0x0800000000000000I64)
154 if(highvalue < 0x1000000000000000I64)
156 if(highvalue < 0x2000000000000000I64)
158 if(highvalue < 0x4000000000000000I64)
160 if(highvalue < 0x8000000000000000I64)
163 if(highvalue < 0x0000000100000000LL)
165 if(highvalue < 0x0000000200000000LL)
167 if(highvalue < 0x0000000400000000LL)
169 if(highvalue < 0x0000000800000000LL)
171 if(highvalue < 0x0000001000000000LL)
173 if(highvalue < 0x0000002000000000LL)
175 if(highvalue < 0x0000004000000000LL)
177 if(highvalue < 0x0000008000000000LL)
179 if(highvalue < 0x0000010000000000LL)
181 if(highvalue < 0x0000020000000000LL)
183 if(highvalue < 0x0000040000000000LL)
185 if(highvalue < 0x0000080000000000LL)
187 if(highvalue < 0x0000100000000000LL)
189 if(highvalue < 0x0000200000000000LL)
191 if(highvalue < 0x0000400000000000LL)
193 if(highvalue < 0x0000800000000000LL)
195 if(highvalue < 0x0001000000000000LL)
197 if(highvalue < 0x0002000000000000LL)
199 if(highvalue < 0x0004000000000000LL)
201 if(highvalue < 0x0008000000000000LL)
203 if(highvalue < 0x0010000000000000LL)
205 if(highvalue < 0x0020000000000000LL)
207 if(highvalue < 0x0040000000000000LL)
209 if(highvalue < 0x0080000000000000LL)
211 if(highvalue < 0x0100000000000000LL)
213 if(highvalue < 0x0200000000000000LL)
215 if(highvalue < 0x0400000000000000LL)
217 if(highvalue < 0x0800000000000000LL)
219 if(highvalue < 0x1000000000000000LL)
221 if(highvalue < 0x2000000000000000LL)
223 if(highvalue < 0x4000000000000000LL)
225 if(highvalue < 0x8000000000000000LL)
234 void GetTableList(string sWildCharPathName, vector<string>& vPathName)
239 int n = sWildCharPathName.find_last_of('\\');
241 sPath = sWildCharPathName.substr(0, n + 1);
244 long handle = _findfirst(sWildCharPathName.c_str(), &fd);
249 string sName = fd.name;
250 if (sName != "." && sName != ".." && !(fd.attrib & _A_SUBDIR))
252 string sPathName = sPath + sName;
253 vPathName.push_back(sPathName);
255 } while (_findnext(handle, &fd) == 0);
261 void GetTableList(int argc, char* argv[], vector<string>& vPathName)
266 for (i = 1; i < argc; i++)
268 string sPathName = argv[i];
270 if (lstat(sPathName.c_str(), &buf) == 0)
272 if (S_ISREG(buf.st_mode))
273 vPathName.push_back(sPathName);
281 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)
284 int nIndex = sPathName.find_last_of('\\');
286 int nIndex = sPathName.find_last_of('/');
290 sFileName = sPathName.substr(nIndex + 1);
292 sFileName = sPathName;
294 printf("%s:\n", sFileName.c_str());
295 FILE* file = fopen(sPathName.c_str(), "rb");
296 FILE* fileR = fopen(sResultFileName.c_str(), "wb");
297 unsigned int distribution[64] = {0};
298 unsigned int numProcessedChains = 0;
300 if (file != NULL && fileR != NULL)
303 unsigned int nFileLen = GetFileLen(file);
304 unsigned int nTotalChainCount = 0;
305 if(hascp == 0) nTotalChainCount = nFileLen / 16;
306 else nTotalChainCount = nFileLen / 18;
307 if ((hascp == 0 && nFileLen % 16 != 0) || (hascp == 1 && nFileLen % 18 != 0))
309 printf("file length mismatch\n");
313 static CMemoryPool mp;
314 unsigned int nAllocatedSize;
315 RainbowChainCP* pChain = (RainbowChainCP*)mp.Allocate(nFileLen, nAllocatedSize);
317 unsigned int chainrowsize = ceil((float)(rti_startptlength + rti_endptlength + rti_cplength) / 8) * 8 ; // The size in bits (in whole bytes)
318 unsigned int chainrowsizebytes = chainrowsize / 8;
323 nAllocatedSize = nAllocatedSize / sizeof(RainbowChainCP) * sizeof(RainbowChainCP);
324 fseek(file, 0, SEEK_SET);
325 uint64 curPrefix = 0, prefixStart = 0;
326 vector<IndexRow> indexes;
327 int nRainbowChainCountRead = 0;
328 while (true) // Chunk read loop
330 /* if (ftell(file) == nFileLen)
333 memset(pChain, 0x00, nAllocatedSize);
334 printf("reading...\n");
335 clock_t t1 = clock();
336 for(nReadThisRound = 0; nReadThisRound < nAllocatedSize / sizeof(RainbowChainCP) && nRainbowChainCountRead < nTotalChainCount; nReadThisRound++)
338 if(fread(&pChain[nReadThisRound], 16, 1, file) != 1)
340 printf("Error reading file\n"); exit(1);
344 if(fread(&pChain[nReadThisRound].nCheckPoint, 2, 1, file) != 1)
346 printf("Error reading file\n"); exit(2);
349 nRainbowChainCountRead++;
351 clock_t t2 = clock();
352 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
353 int nDataRead = nRainbowChainCountRead * 16;
354 if(hascp == 1) nDataRead += nRainbowChainCountRead * 2; // Add the index readings too
355 printf("%u bytes read, disk access time: %.2f s\n", nDataRead , fTime);
358 for(int i = 0; i < nReadThisRound; i++)
360 if(showDistribution == 1)
362 distribution[GetMaxBits(pChain[i].nIndexS)-1]++;
366 uint64 chainrow = pChain[i].nIndexS; // Insert the complete start point
367 chainrow |= ((uint64)pChain[i].nIndexE & (0xffffffff >> (32 - rti_endptlength))) << rti_startptlength; //
368 if(hascp == 1 && rti_cplength > 0)
370 chainrow |= (uint64)pChain[i].nCheckPoint << rti_startptlength + rti_endptlength;
372 fwrite(&chainrow, 1, chainrowsizebytes, fileR);
373 uint64 prefix = pChain[i].nIndexE >> rti_endptlength;
374 if(i == 0) curPrefix = prefix;
375 if(prefix != curPrefix && numProcessedChains - prefixStart > 0)
377 if(prefix < curPrefix)
379 printf("**** Error writeChain(): Prefix is smaller than previous prefix. %llu < %llu****\n", prefix, curPrefix);
382 //unsigned char index[11] = {0}; // [0 - 10]
383 unsigned int numchains = numProcessedChains - prefixStart;
385 index.prefix = curPrefix;
386 // index.prefixstart = prefixStart;
387 index.numchains = numchains;
388 indexes.push_back(index);
389 prefixStart = numProcessedChains;
393 numProcessedChains++;
396 fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
397 printf("conversion time: %.2f s\n", fTime);
398 if(nRainbowChainCountRead == nTotalChainCount)
400 if(showDistribution == 1)
402 for(int i = 0; i < 64; i++)
404 printf("%u - %u\n", (i+1), distribution[i]);
413 // We need to write the last index down
415 index.prefix = curPrefix;
416 index.prefixstart = prefixStart;
417 index.numchains = numProcessedChains - prefixStart;
418 indexes.push_back(index);
420 IndexRow high = {0}; // Used to find the highest numbers. This tells us how much we can pack the index bits
421 for(int i = 0; i < indexes.size(); i++)
423 if(indexes[i].numchains > high.numchains)
424 high.numchains = indexes[i].numchains;
425 /* if(indexes[i].prefixstart > high.prefixstart)
426 high.prefixstart = indexes[i].prefixstart;
427 if(indexes[i].prefix > high.prefix)
428 high.prefix = indexes[i].prefix;
431 high.prefix = indexes[indexes.size()-1].prefix; // The last prefix is always the highest prefix
432 // unsigned int m_rti_index_prefixlength = GetMaxBits(high.prefix);
433 unsigned int m_rti_index_numchainslength = GetMaxBits(high.numchains);
434 // unsigned int m_rti_index_indexlength = GetMaxBits(high.prefixstart);
435 unsigned int m_indexrowsize = ceil((float)(/*m_rti_index_indexlength + */m_rti_index_numchainslength) / 8) * 8; // The size in bits (in whole bytes)
436 unsigned int m_indexrowsizebytes = m_indexrowsize / 8;
437 FILE *pFileIndex = fopen(sResultFileName.append(".index").c_str(), "wb");
438 fwrite("RTI2", 1, 4, pFileIndex);
439 fwrite(&rti_startptlength, 1, 1, pFileIndex);
440 fwrite(&rti_endptlength, 1, 1, pFileIndex);
441 fwrite(&rti_cplength, 1, 1, pFileIndex);
442 // fwrite(&m_rti_index_indexlength , 1, 1, pFileIndex);
443 fwrite(&m_rti_index_numchainslength, 1, 1, pFileIndex);
444 for(int i = 0; i < rti_cppos.size(); i++)
446 fwrite(&rti_cppos[i], 1, 4, pFileIndex); // The position of the checkpoints
448 // fwrite(&m_rti_index_prefixlength, 1, 1, pFileIndex);
450 fwrite(&indexes[0].prefix, 1, 8, pFileIndex); // Write the first prefix
451 unsigned int lastPrefix = 0;
452 for(int i = 0; i < indexes.size(); i++)
455 lastPrefix = indexes[0].prefix;
456 unsigned int indexrow = 0;
457 // Checks how big a distance there is between the current and the next prefix. eg cur is 3 and next is 10 = 7.
458 unsigned int diffSize = indexes[i].prefix - lastPrefix;
459 if(i > 0 && diffSize > 1)
461 //indexrow |= indexes[i].prefixstart;
462 //printf("Diffsize is %u\n", diffSize);
464 // then write the distance amount of 00's
465 if(diffSize > 1000) {
466 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);
468 printf("Aborting...");
472 for(int j = 1; j < diffSize; j++)
474 fwrite(&zero, 1, m_indexrowsizebytes, pFileIndex);
477 fwrite(&indexes[i].numchains, 1, m_indexrowsizebytes, pFileIndex);
478 lastPrefix = indexes[i].prefix;
482 else printf("memory allocation fail\n");
491 printf("can't open file\n");
495 int main(int argc, char* argv[])
497 int argi = 1, i, argsUsed = 0;
498 unsigned int sptl = 40, eptl = 16;
499 int showDistribution = 0;
500 int usecp = 0;// How many bits to use from the index
502 vector<unsigned int> cppositions;
510 for (; argi < argc; argi++)
512 if (strcmp(argv[argi], "-d") == 0 && (argsUsed & 0x8) == 0)
514 // Enable verbose mode
516 showDistribution = 1;
518 else if (strncmp(argv[argi], "-sptl=", 6) == 0 && (argsUsed & 0x1) == 0)
520 // Maximum index for starting point
523 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
526 sptl += ((int) argv[argi][i]) - 0x30;
528 if (argv[argi][i] != '\0')
530 printf("Error: Invalid number.\n\n");
534 if (i > 23) // i - 3 > 20
536 printf("Error: Number is too large.\n\n");
542 else if (strncmp(argv[argi], "-eptl=", 6) == 0 && (argsUsed & 0x2) == 0)
544 // Maximum index for ending points
547 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
550 eptl += ((int) argv[argi][i]) - 0x30;
552 if (argv[argi][i] != '\0')
554 printf("Error: Invalid number.\n\n");
558 if (i > 23) // i - 3 > 20
560 printf("Error: Number is too large.\n\n");
565 else if(strncmp(argv[argi], "-usecp=", 7) == 0 && (argsUsed & 0x4) == 0)
570 unsigned int cppos = 0;
571 for(i = 7; argv[argi][i] != ' ' && argv[argi][i] != '\n' && argv[argi][i] != 0;)
573 if(cppositions.size() > 0) i++;
574 for (; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
577 cppos += ((int) argv[argi][i]) - 0x30;
579 /* if(argv[argi][i] == ',')
581 cppositions.push_back(cppos);
586 if (argv[argi][i] != '\0')
588 printf("Error: Invalid number.\n\n");
592 if (usecp > 16) // i - 3 > 20
594 printf("Error: Number is too large.\n\n");
598 else printf("Using %i bits of the checkpoints\n", usecp);
603 vector<string> vPathName;
605 string sWildCharPathName = argv[1];
606 GetTableList(sWildCharPathName, vPathName);
608 GetTableList(argc, argv, vPathName);
610 if (vPathName.size() == 0)
612 printf("no rainbow table found\n");
615 for (int i = 0; i < vPathName.size(); i++)
618 int n = vPathName[i].find_last_of('\\');
620 sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "i2";
622 sResultFile = vPathName[i] + "i2"; // Resulting file is .rt, not .rti
623 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));
624 if(sptl + eptl + usecp > 64)
628 ConvertRainbowTable(vPathName[i], sResultFile, sptl, eptl, showDistribution, hascp, usecp, cppositions);