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 unsigned int chainsLeft;
331 while((chainsLeft = reader->GetChainsLeft()) > 0) {
333 /* if (ftell(file) == nFileLen)
335 printf("%u chains left to read\n", chainsLeft);
337 clock_t t1 = clock();
338 printf("reading...\n");
340 printf("Grabbing %i chains from file\n", nChains);
342 reader->ReadChains(nChains, pChain);
344 printf("Recieved %i chains from file\n", nChains);
346 clock_t t2 = clock();
347 float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
348 printf("reading time: %.2f s\n", fTime);
349 printf("converting %i chains...\n", nChains);
351 for(int i = 0; i < nChains; i++) {
352 if(showDistribution == 1) {
353 distribution[GetMaxBits(pChain[i].nIndexS)-1]++;
357 uint64 chainrow = pChain[i].nIndexS; // Insert the complete start point
358 chainrow |= ((uint64)pChain[i].nIndexE & (0xffffffff >> (32 - rti_endptlength))) << rti_startptlength; //
359 /* if(hascp == 1 && rti_cplength > 0) {
360 chainrow |= (uint64)pChain[i].nCheckPoint << rti_startptlength + rti_endptlength;
362 fwrite(&chainrow, 1, chainrowsizebytes, fileR);
363 uint64 prefix = pChain[i].nIndexE >> rti_endptlength;
364 if(i == 0) curPrefix = prefix;
365 if(prefix != curPrefix && numProcessedChains - prefixStart > 0) {
366 if(prefix < curPrefix) {
367 printf("**** Error writeChain(): Prefix is smaller than previous prefix. %llu < %llu****\n", prefix, curPrefix);
370 //unsigned char index[11] = {0}; // [0 - 10]
371 unsigned int numchains = numProcessedChains - prefixStart;
373 index.prefix = curPrefix;
374 // index.prefixstart = prefixStart;
375 index.numchains = numchains;
376 indexes.push_back(index);
377 prefixStart = numProcessedChains;
381 numProcessedChains++;
384 fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
385 printf("conversion time: %.2f s\n", fTime);
386 if(showDistribution == 1) {
387 for(int i = 0; i < 64; i++) {
388 printf("%u - %u\n", (i+1), distribution[i]);
398 // We need to write the last index down
400 index.prefix = curPrefix;
401 index.prefixstart = prefixStart;
402 index.numchains = numProcessedChains - prefixStart;
403 indexes.push_back(index);
405 IndexRow high = {0}; // Used to find the highest numbers. This tells us how much we can pack the index bits
406 for(UINT4 i = 0; i < indexes.size(); i++)
408 if(indexes[i].numchains > high.numchains)
409 high.numchains = indexes[i].numchains;
410 /* if(indexes[i].prefixstart > high.prefixstart)
411 high.prefixstart = indexes[i].prefixstart;
412 if(indexes[i].prefix > high.prefix)
413 high.prefix = indexes[i].prefix;
416 high.prefix = indexes[indexes.size()-1].prefix; // The last prefix is always the highest prefix
417 // unsigned int m_rti_index_prefixlength = GetMaxBits(high.prefix);
418 unsigned int m_rti_index_numchainslength = GetMaxBits(high.numchains);
419 // unsigned int m_rti_index_indexlength = GetMaxBits(high.prefixstart);
420 unsigned int m_indexrowsize = ceil((float)(/*m_rti_index_indexlength + */m_rti_index_numchainslength) / 8) * 8; // The size in bits (in whole bytes)
421 unsigned int m_indexrowsizebytes = m_indexrowsize / 8;
422 FILE *pFileIndex = fopen(sResultFileName.append(".index").c_str(), "wb");
423 fwrite("RTI2", 1, 4, pFileIndex);
424 fwrite(&rti_startptlength, 1, 1, pFileIndex);
425 fwrite(&rti_endptlength, 1, 1, pFileIndex);
426 fwrite(&rti_cplength, 1, 1, pFileIndex);
427 // fwrite(&m_rti_index_indexlength , 1, 1, pFileIndex);
429 fwrite(&m_rti_index_numchainslength, 1, 1, pFileIndex);
430 for(UINT4 i = 0; i < rti_cppos.size(); i++) {
431 fwrite(&rti_cppos[i], 1, 4, pFileIndex); // The position of the checkpoints
433 // fwrite(&m_rti_index_prefixlength, 1, 1, pFileIndex);
435 fwrite(&indexes[0].prefix, 1, 8, pFileIndex); // Write the first prefix
436 unsigned int lastPrefix = 0;
437 for(UINT4 i = 0; i < indexes.size(); i++) {
439 lastPrefix = indexes[0].prefix;
441 unsigned int indexrow = 0;
442 // Checks how big a distance there is between the current and the next prefix. eg cur is 3 and next is 10 = 7.
443 unsigned int diffSize = indexes[i].prefix - lastPrefix;
444 if(i > 0 && diffSize > 1) {
445 //indexrow |= indexes[i].prefixstart;
446 //printf("Diffsize is %u\n", diffSize);
448 // then write the distance amount of 00's
449 if(diffSize > 1000) {
450 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);
452 if ( _getch() != 'y' ) {
454 if ( tty_getchar() != 'y' ) {
456 printf("Aborting...");
460 for(UINT4 j = 1; j < diffSize; j++)
462 fwrite(&zero, 1, m_indexrowsizebytes, pFileIndex);
465 fwrite(&indexes[i].numchains, 1, m_indexrowsizebytes, pFileIndex);
466 lastPrefix = indexes[i].prefix;
471 printf("memory allocation fail\n");
476 printf("can't open file\n");
486 int main(int argc, char* argv[])
488 int argi = 1, i, argsUsed = 0;
489 unsigned int sptl = 40, eptl = 16;
490 int showDistribution = 0;
491 int usecp = 0;// How many bits to use from the index
493 vector<unsigned int> cppositions;
499 for (; argi < argc; argi++)
501 if(strcmp(argv[argi], "-d") == 0 && (argsUsed & 0x8) == 0) {
502 // Enable verbose mode
504 showDistribution = 1;
506 else if (strncmp(argv[argi], "-sptl=", 6) == 0 && (argsUsed & 0x1) == 0) {
507 // Maximum index for starting point
510 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++) {
512 sptl += ((int) argv[argi][i]) - 0x30;
514 if (argv[argi][i] != '\0') {
515 printf("Error: Invalid number.\n\n");
519 if (i > 23) { // i - 3 > 20
520 printf("Error: Number is too large.\n\n");
526 else if (strncmp(argv[argi], "-eptl=", 6) == 0 && (argsUsed & 0x2) == 0) {
527 // Maximum index for ending points
530 for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++) {
532 eptl += ((int) argv[argi][i]) - 0x30;
534 if (argv[argi][i] != '\0') {
535 printf("Error: Invalid number.\n\n");
539 if (i > 23) { // i - 3 > 20
540 printf("Error: Number is too large.\n\n");
545 else if(strncmp(argv[argi], "-usecp=", 7) == 0 && (argsUsed & 0x4) == 0) {
549 unsigned int cppos = 0;
550 for(i = 7; argv[argi][i] != ' ' && argv[argi][i] != '\n' && argv[argi][i] != 0;) {
551 if(cppositions.size() > 0) i++;
552 for (; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
555 cppos += ((int) argv[argi][i]) - 0x30;
557 /* if(argv[argi][i] == ',')
559 cppositions.push_back(cppos);
564 if (argv[argi][i] != '\0') {
565 printf("Error: Invalid number.\n\n");
569 if (usecp > 16) { // i - 3 > 20
570 printf("Error: Number is too large.\n\n");
575 printf("Using %i bits of the checkpoints\n", usecp);
581 vector<string> vPathName;
583 string sWildCharPathName = argv[1];
584 GetTableList(sWildCharPathName, vPathName);
586 GetTableList(argc, argv, vPathName);
588 if (vPathName.size() == 0) {
589 printf("no rainbow table found\n");
592 for (UINT4 i = 0; i < vPathName.size(); i++) {
594 int n = vPathName[i].find_last_of('\\');
596 if(vPathName[i].substr(vPathName[i].length() - 3, vPathName[i].length()) == "rti") {
597 sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "2";
600 sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "i2";
604 if(vPathName[i].substr(vPathName[i].length() - 3, vPathName[i].length()) == "rti") {
605 sResultFile = vPathName[i] + "2";
607 sResultFile = vPathName[i] + "i2"; // Resulting file is .rt, not .rti
610 if(usecp == 0 && showDistribution == 0) {
611 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));
613 if(sptl + eptl + usecp > 64) {
616 ConvertRainbowTable(vPathName[i], sResultFile, sptl, eptl, showDistribution, hascp, usecp, cppositions);