19 #include "MemoryPool.h"
20 #include "RTIReader.h"
27 printf("converti2 - Original to Indexed rainbow table converter\n");
28 printf("by Martin Westergaard <martinwj2005@gmail.com>\n");
29 printf("http://www.freerainbowtables.com\n\n");
31 printf("usage: converti2 rainbow_table_pathname\n");
32 printf("rainbow_table_pathname: pathname of the rainbow table(s), wildchar(*, ?) supported\n");
34 printf("example: converti2 *.rt\n");
35 printf(" converti2 md5_*.rt\n");
39 int GetMaxBits(uint64 highvalue)
63 if(highvalue < 0x1000)
65 if(highvalue < 0x2000)
67 if(highvalue < 0x4000)
69 if(highvalue < 0x8000)
71 if(highvalue < 0x10000)
73 if(highvalue < 0x20000)
75 if(highvalue < 0x40000)
77 if(highvalue < 0x80000)
79 if(highvalue < 0x100000)
81 if(highvalue < 0x200000)
83 if(highvalue < 0x400000)
85 if(highvalue < 0x800000)
87 if(highvalue < 0x1000000)
89 if(highvalue < 0x2000000)
91 if(highvalue < 0x4000000)
93 if(highvalue < 0x8000000)
95 if(highvalue < 0x10000000)
97 if(highvalue < 0x20000000)
99 if(highvalue < 0x40000000)
101 if(highvalue < 0x80000000)
104 if(highvalue < 0x0000000100000000I64)
106 if(highvalue < 0x0000000200000000I64)
108 if(highvalue < 0x0000000400000000I64)
110 if(highvalue < 0x0000000800000000I64)
112 if(highvalue < 0x0000001000000000I64)
114 if(highvalue < 0x0000002000000000I64)
116 if(highvalue < 0x0000004000000000I64)
118 if(highvalue < 0x0000008000000000I64)
120 if(highvalue < 0x0000010000000000I64)
122 if(highvalue < 0x0000020000000000I64)
124 if(highvalue < 0x0000040000000000I64)
126 if(highvalue < 0x0000080000000000I64)
128 if(highvalue < 0x0000100000000000I64)
130 if(highvalue < 0x0000200000000000I64)
132 if(highvalue < 0x0000400000000000I64)
134 if(highvalue < 0x0000800000000000I64)
136 if(highvalue < 0x0001000000000000I64)
138 if(highvalue < 0x0002000000000000I64)
140 if(highvalue < 0x0004000000000000I64)
142 if(highvalue < 0x0008000000000000I64)
144 if(highvalue < 0x0010000000000000I64)
146 if(highvalue < 0x0020000000000000I64)
148 if(highvalue < 0x0040000000000000I64)
150 if(highvalue < 0x0080000000000000I64)
152 if(highvalue < 0x0100000000000000I64)
154 if(highvalue < 0x0200000000000000I64)
156 if(highvalue < 0x0400000000000000I64)
158 if(highvalue < 0x0800000000000000I64)
160 if(highvalue < 0x1000000000000000I64)
162 if(highvalue < 0x2000000000000000I64)
164 if(highvalue < 0x4000000000000000I64)
166 if(highvalue < 0x8000000000000000I64)
169 if(highvalue < 0x0000000100000000LL)
171 if(highvalue < 0x0000000200000000LL)
173 if(highvalue < 0x0000000400000000LL)
175 if(highvalue < 0x0000000800000000LL)
177 if(highvalue < 0x0000001000000000LL)
179 if(highvalue < 0x0000002000000000LL)
181 if(highvalue < 0x0000004000000000LL)
183 if(highvalue < 0x0000008000000000LL)
185 if(highvalue < 0x0000010000000000LL)
187 if(highvalue < 0x0000020000000000LL)
189 if(highvalue < 0x0000040000000000LL)
191 if(highvalue < 0x0000080000000000LL)
193 if(highvalue < 0x0000100000000000LL)
195 if(highvalue < 0x0000200000000000LL)
197 if(highvalue < 0x0000400000000000LL)
199 if(highvalue < 0x0000800000000000LL)
201 if(highvalue < 0x0001000000000000LL)
203 if(highvalue < 0x0002000000000000LL)
205 if(highvalue < 0x0004000000000000LL)
207 if(highvalue < 0x0008000000000000LL)
209 if(highvalue < 0x0010000000000000LL)
211 if(highvalue < 0x0020000000000000LL)
213 if(highvalue < 0x0040000000000000LL)
215 if(highvalue < 0x0080000000000000LL)
217 if(highvalue < 0x0100000000000000LL)
219 if(highvalue < 0x0200000000000000LL)
221 if(highvalue < 0x0400000000000000LL)
223 if(highvalue < 0x0800000000000000LL)
225 if(highvalue < 0x1000000000000000LL)
227 if(highvalue < 0x2000000000000000LL)
229 if(highvalue < 0x4000000000000000LL)
231 if(highvalue < 0x8000000000000000LL)
240 void GetTableList(string sWildCharPathName, vector<string>& vPathName)
245 int n = sWildCharPathName.find_last_of('\\');
247 sPath = sWildCharPathName.substr(0, n + 1);
250 long handle = _findfirst(sWildCharPathName.c_str(), &fd);
253 string sName = fd.name;
254 if (sName != "." && sName != ".." && !(fd.attrib & _A_SUBDIR)) {
255 string sPathName = sPath + sName;
256 vPathName.push_back(sPathName);
258 } while (_findnext(handle, &fd) == 0);
264 void GetTableList(int argc, char* argv[], vector<string>& vPathName)
269 for (i = 1; i < argc; i++)
271 string sPathName = argv[i];
273 if (lstat(sPathName.c_str(), &buf) == 0)
275 if (S_ISREG(buf.st_mode))
276 vPathName.push_back(sPathName);
284 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)
287 int nIndex = sPathName.find_last_of('\\');
289 int nIndex = sPathName.find_last_of('/');
293 sFileName = sPathName.substr(nIndex + 1);
296 sFileName = sPathName;
298 unsigned int distribution[64] = {0};
299 unsigned int numProcessedChains = 0;
301 BaseRTReader *reader = NULL;
302 if(sPathName.substr(sPathName.length() - 2, sPathName.length()) == "rt")
303 reader = (BaseRTReader*)new RTReader(sPathName);
304 else if(sPathName.substr(sPathName.length() - 3, sPathName.length()) == "rti")
305 reader = (BaseRTReader*)new RTIReader(sPathName);
307 printf("%s is not a supported file (Only RT and RTI is supported)\n", sPathName.c_str());
311 printf("%s:\n", sFileName.c_str());
312 if(showDistribution == 0) {
313 fileR = fopen(sResultFileName.c_str(), "wb");
315 if (fileR != NULL || showDistribution == 1) {
318 int size = reader->GetChainsLeft() * sizeof(RainbowChain);
319 static CMemoryPool mp;
320 unsigned int nAllocatedSize;
321 RainbowChain* pChain = (RainbowChain*)mp.Allocate(size, nAllocatedSize);
322 unsigned int chainrowsize = ceil((float)(rti_startptlength + rti_endptlength + rti_cplength) / 8) * 8 ; // The size in bits (in whole bytes)
323 unsigned int chainrowsizebytes = chainrowsize / 8;
325 if (pChain != NULL) {
326 nAllocatedSize = nAllocatedSize / sizeof(RainbowChain) * sizeof(RainbowChain);
327 unsigned int nChains = nAllocatedSize / sizeof(RainbowChain);
328 uint64 curPrefix = 0, prefixStart = 0;
329 vector<IndexRow> indexes;
330 while(reader->GetChainsLeft() > 0) {
332 /* if (ftell(file) == nFileLen)
335 clock_t t1 = clock();
336 printf("reading...\n");
338 printf("Grabbing %i chains from file\n", nChains);
340 reader->ReadChains(nChains, pChain);
342 printf("Recieved %i chains from file\n", nChains);
344 clock_t t2 = clock();
345 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
346 printf("reading time: %.2f s\n", fTime);
347 printf("converting %i chains...\n", nChains);
349 for(int i = 0; i < nChains; i++) {
350 if(showDistribution == 1) {
351 distribution[GetMaxBits(pChain[i].nIndexS)-1]++;
355 uint64 chainrow = pChain[i].nIndexS; // Insert the complete start point
356 chainrow |= ((uint64)pChain[i].nIndexE & (0xffffffff >> (32 - rti_endptlength))) << rti_startptlength; //
357 /* if(hascp == 1 && rti_cplength > 0) {
358 chainrow |= (uint64)pChain[i].nCheckPoint << rti_startptlength + rti_endptlength;
360 fwrite(&chainrow, 1, chainrowsizebytes, fileR);
361 uint64 prefix = pChain[i].nIndexE >> rti_endptlength;
362 if(i == 0) curPrefix = prefix;
363 if(prefix != curPrefix && numProcessedChains - prefixStart > 0) {
364 if(prefix < curPrefix) {
365 printf("**** Error writeChain(): Prefix is smaller than previous prefix. %llu < %llu****\n", prefix, curPrefix);
368 //unsigned char index[11] = {0}; // [0 - 10]
369 unsigned int numchains = numProcessedChains - prefixStart;
371 index.prefix = curPrefix;
372 // index.prefixstart = prefixStart;
373 index.numchains = numchains;
374 indexes.push_back(index);
375 prefixStart = numProcessedChains;
379 numProcessedChains++;
382 fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
383 printf("conversion time: %.2f s\n", fTime);
384 if(showDistribution == 1) {
385 for(int i = 0; i < 64; i++) {
386 printf("%u - %u\n", (i+1), distribution[i]);
396 // We need to write the last index down
398 index.prefix = curPrefix;
399 index.prefixstart = prefixStart;
400 index.numchains = numProcessedChains - prefixStart;
401 indexes.push_back(index);
403 IndexRow high = {0}; // Used to find the highest numbers. This tells us how much we can pack the index bits
404 for(UINT4 i = 0; i < indexes.size(); i++)
406 if(indexes[i].numchains > high.numchains)
407 high.numchains = indexes[i].numchains;
408 /* if(indexes[i].prefixstart > high.prefixstart)
409 high.prefixstart = indexes[i].prefixstart;
410 if(indexes[i].prefix > high.prefix)
411 high.prefix = indexes[i].prefix;
414 high.prefix = indexes[indexes.size()-1].prefix; // The last prefix is always the highest prefix
415 // unsigned int m_rti_index_prefixlength = GetMaxBits(high.prefix);
416 unsigned int m_rti_index_numchainslength = GetMaxBits(high.numchains);
417 // unsigned int m_rti_index_indexlength = GetMaxBits(high.prefixstart);
418 unsigned int m_indexrowsize = ceil((float)(/*m_rti_index_indexlength + */m_rti_index_numchainslength) / 8) * 8; // The size in bits (in whole bytes)
419 unsigned int m_indexrowsizebytes = m_indexrowsize / 8;
420 FILE *pFileIndex = fopen(sResultFileName.append(".index").c_str(), "wb");
421 fwrite("RTI2", 1, 4, pFileIndex);
422 fwrite(&rti_startptlength, 1, 1, pFileIndex);
423 fwrite(&rti_endptlength, 1, 1, pFileIndex);
424 fwrite(&rti_cplength, 1, 1, pFileIndex);
425 // fwrite(&m_rti_index_indexlength , 1, 1, pFileIndex);
427 fwrite(&m_rti_index_numchainslength, 1, 1, pFileIndex);
428 for(UINT4 i = 0; i < rti_cppos.size(); i++) {
429 fwrite(&rti_cppos[i], 1, 4, pFileIndex); // The position of the checkpoints
431 // fwrite(&m_rti_index_prefixlength, 1, 1, pFileIndex);
433 fwrite(&indexes[0].prefix, 1, 8, pFileIndex); // Write the first prefix
434 unsigned int lastPrefix = 0;
435 for(UINT4 i = 0; i < indexes.size(); i++) {
437 lastPrefix = indexes[0].prefix;
439 unsigned int indexrow = 0;
440 // Checks how big a distance there is between the current and the next prefix. eg cur is 3 and next is 10 = 7.
441 unsigned int diffSize = indexes[i].prefix - lastPrefix;
442 if(i > 0 && diffSize > 1) {
443 //indexrow |= indexes[i].prefixstart;
444 //printf("Diffsize is %u\n", diffSize);
446 // then write the distance amount of 00's
447 if(diffSize > 1000) {
448 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);
450 if ( _getch() != 'y' ) {
452 if ( tty_getchar() != 'y' ) {
454 printf("Aborting...");
458 for(UINT4 j = 1; j < diffSize; j++)
460 fwrite(&zero, 1, m_indexrowsizebytes, pFileIndex);
463 fwrite(&indexes[i].numchains, 1, m_indexrowsizebytes, pFileIndex);
464 lastPrefix = indexes[i].prefix;
469 printf("memory allocation fail\n");
474 printf("can't open file\n");
484 int main(int argc, char* argv[])
486 int argi = 1, i, argsUsed = 0;
487 unsigned int sptl = 40, eptl = 16;
488 int showDistribution = 0;
489 int usecp = 0;// How many bits to use from the index
491 vector<unsigned int> cppositions;
497 for (; argi < argc; argi++)
499 if(strcmp(argv[argi], "-d") == 0 && (argsUsed & 0x8) == 0) {
500 // Enable verbose mode
502 showDistribution = 1;
504 else if (strncmp(argv[argi], "-sptl=", 6) == 0 && (argsUsed & 0x1) == 0) {
505 // Maximum index for starting point
508 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++) {
510 sptl += ((int) argv[argi][i]) - 0x30;
512 if (argv[argi][i] != '\0') {
513 printf("Error: Invalid number.\n\n");
517 if (i > 23) { // i - 3 > 20
518 printf("Error: Number is too large.\n\n");
524 else if (strncmp(argv[argi], "-eptl=", 6) == 0 && (argsUsed & 0x2) == 0) {
525 // Maximum index for ending points
528 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++) {
530 eptl += ((int) argv[argi][i]) - 0x30;
532 if (argv[argi][i] != '\0') {
533 printf("Error: Invalid number.\n\n");
537 if (i > 23) { // i - 3 > 20
538 printf("Error: Number is too large.\n\n");
543 else if(strncmp(argv[argi], "-usecp=", 7) == 0 && (argsUsed & 0x4) == 0) {
547 unsigned int cppos = 0;
548 for(i = 7; argv[argi][i] != ' ' && argv[argi][i] != '\n' && argv[argi][i] != 0;) {
549 if(cppositions.size() > 0) i++;
550 for (; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
553 cppos += ((int) argv[argi][i]) - 0x30;
555 /* if(argv[argi][i] == ',')
557 cppositions.push_back(cppos);
562 if (argv[argi][i] != '\0') {
563 printf("Error: Invalid number.\n\n");
567 if (usecp > 16) { // i - 3 > 20
568 printf("Error: Number is too large.\n\n");
573 printf("Using %i bits of the checkpoints\n", usecp);
579 vector<string> vPathName;
581 string sWildCharPathName = argv[1];
582 GetTableList(sWildCharPathName, vPathName);
584 GetTableList(argc, argv, vPathName);
586 if (vPathName.size() == 0) {
587 printf("no rainbow table found\n");
590 for (UINT4 i = 0; i < vPathName.size(); i++) {
592 int n = vPathName[i].find_last_of('\\');
594 if(vPathName[i].substr(vPathName[i].length() - 3, vPathName[i].length()) == "rti") {
595 sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "2";
598 sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "i2";
602 if(vPathName[i].substr(vPathName[i].length() - 3, vPathName[i].length()) == "rti") {
603 sResultFile = vPathName[i] + "2";
605 sResultFile = vPathName[i] + "i2"; // Resulting file is .rt, not .rti
608 if(usecp == 0 && showDistribution == 0) {
609 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));
611 if(sptl + eptl + usecp > 64) {
614 ConvertRainbowTable(vPathName[i], sResultFile, sptl, eptl, showDistribution, hascp, usecp, cppositions);