2 * freerainbowtables is a project for generating, distributing, and using
3 * perfect rainbow tables
5 * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
6 * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
7 * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
8 * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
10 * This file is part of freerainbowtables.
12 * freerainbowtables is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation, either version 2 of the License, or
15 * (at your option) any later version.
17 * freerainbowtables is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
22 * You should have received a copy of the GNU General Public License
23 * along with freerainbowtables. If not, see <http://www.gnu.org/licenses/>.
26 #if defined(_WIN32) && !defined(__GNUC__)
27 #pragma warning(disable : 4786)
30 #include "ChainWalkSet.h"
32 CChainWalkSet::CChainWalkSet()
34 m_sHashRoutineName = "";
35 m_sPlainCharsetName = "";
38 m_nRainbowTableIndex = 0;
39 m_nRainbowChainLen = 0;
41 sPrecalcPathName = "";
45 CChainWalkSet::~CChainWalkSet()
50 void CChainWalkSet::DiscardAll()
52 //printf("debug: discarding all walk...\n");
54 list<ChainWalk>::iterator it;
55 for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
56 delete [] it->pIndexE;
60 string CChainWalkSet::CheckOrRotatePreCalcFile()
62 char sPreCalcFileName[255];
64 // 255 files limit to be sure
65 for (; preCalcPart < 255; preCalcPart++)
67 sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);
68 string sReturnPreCalcPath(sPreCalcFileName);
70 unsigned int fileLen = 0;
72 FILE* file = fopen(sReturnPreCalcPath.c_str(), "ab");
75 fileLen = GetFileLen(file);
76 long unsigned int nextFileLen = fileLen + (sizeof(uint64) * (m_nRainbowChainLen-1));
77 // Rotate to next file if we are going to pass 2GB filesize
78 if (nextFileLen < ((unsigned)2 * 1024 * 1024 * 1024))
80 // We might want to vPrecalcFiles.push_back(sReturnPreCalcPath) if we just created this file
81 // We don't as only newly generated chainwalksets will be stored to this new file, so we don't have to look there
82 if (debug) printf("Debug: Using for precalc: %s\n", sReturnPreCalcPath.c_str());
84 return sReturnPreCalcPath;
93 void CChainWalkSet::updateUsedPrecalcFiles()
95 // we might also use this function to search a wildcard path of precalc files
96 vPrecalcFiles.clear();
97 char sPreCalcFileName[255];
101 for (i = 0; i < 255; i++)
103 sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), i);
104 string sTryPreCalcPath(sPreCalcFileName);
105 FILE* file = fopen(sTryPreCalcPath.c_str(), "rb");
107 vPrecalcFiles.push_back(sTryPreCalcPath);
116 void CChainWalkSet::removePrecalcFiles()
118 if (debug) printf("Debug: Removing precalc files.\n");
119 updateUsedPrecalcFiles();
120 string sCurrentPrecalcPathName = "";
121 string sCurrentPrecalcIndexPathName = "";
124 for (i = 0; i < (int)vPrecalcFiles.size(); i++)
126 sCurrentPrecalcPathName = vPrecalcFiles[i];
127 sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
129 if (debug) printf("Debug: Removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
131 if (remove(sCurrentPrecalcPathName.c_str()) != 0)
132 if (debug) printf("Debug: Failed removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
134 if (debug) printf("Debug: Removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
136 if (remove(sCurrentPrecalcIndexPathName.c_str()) != 0)
137 if (debug) printf("Debug: Failed removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
142 bool CChainWalkSet::FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
144 int gotPrecalcOnLine = -1;
145 char precalculationLine[255];
146 sprintf(precalculationLine, "%s_%s#%d-%d_%d_%d:%s\n", m_sHashRoutineName.c_str(), m_sPlainCharsetName.c_str(), m_nPlainLenMin, m_nPlainLenMax, m_nRainbowTableIndex, m_nRainbowChainLen, HexToStr(pHash, nHashLen).c_str() );
147 string precalcString(precalculationLine);
149 string sCurrentPrecalcPathName = "";
150 string sCurrentPrecalcIndexPathName = "";
151 long unsigned int offset;
154 for (i = 0; i < (int)vPrecalcFiles.size() && gotPrecalcOnLine == -1; i++)
156 sCurrentPrecalcPathName = vPrecalcFiles[i];
157 sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
161 vector<string> precalcLines;
162 if (ReadLinesFromFile(sCurrentPrecalcIndexPathName.c_str(), precalcLines))
165 for (j = 0; j < (int)precalcLines.size(); j++)
167 if (precalcString.compare(0, precalcString.size()-1, precalcLines[j]) == 0)
169 gotPrecalcOnLine = j;
174 vector<string> vPart;
175 if (SeperateString(precalcLines[j], "___:", vPart))
178 offset += ((atoi(vPart[3].c_str())-1) * sizeof(uint64));
182 printf("Corrupted precalculation file!\n");
183 gotPrecalcOnLine = -1;
190 if (gotPrecalcOnLine > -1)
192 if (debug) printf("Debug: Reading pre calculations from file, line %d offset %lu\n", gotPrecalcOnLine, offset);
194 FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "rb");
197 fseek(fp, offset, SEEK_SET);
199 // We should do some verification here, for example by recalculating the middle chain, to catch corrupted files
200 if(fread(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1)
201 printf("File read error.");
205 printf("Cannot open precalculation file %s.\n", sCurrentPrecalcPathName.c_str());
207 //printf("\npIndexE[0]: %s\n", uint64tostr(pIndexE[0]).c_str());
208 //printf("\npIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pIndexE[m_nRainbowChainLen-2]).c_str());
216 void CChainWalkSet::StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
218 if (debug) printf("\nDebug: Storing precalc\n");
220 string sCurrentPrecalcPathName = CheckOrRotatePreCalcFile();
221 string sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
223 FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "ab");
226 if(fwrite(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1)
227 printf("File write error.");
230 FILE* file = fopen(sCurrentPrecalcIndexPathName.c_str(), "a");
233 char precalculationLine[255];
234 sprintf(precalculationLine, "%s_%s#%d-%d_%d_%d:%s\n", m_sHashRoutineName.c_str(), m_sPlainCharsetName.c_str(), m_nPlainLenMin, m_nPlainLenMax, m_nRainbowTableIndex, m_nRainbowChainLen, HexToStr(pHash, nHashLen).c_str() );
235 fputs (precalculationLine, file);
242 printf("Cannot open precalculation file %s\n", sCurrentPrecalcPathName.c_str());
245 uint64* CChainWalkSet::RequestWalk(unsigned char* pHash, int nHashLen,
246 string sHashRoutineName,
247 string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax,
248 int nRainbowTableIndex,
249 int nRainbowChainLen,
250 bool& fNewlyGenerated,
255 sPrecalcPathName = sPrecalc;
257 if ( m_sHashRoutineName != sHashRoutineName
258 || m_sPlainCharsetName != sPlainCharsetName
259 || m_nPlainLenMin != nPlainLenMin
260 || m_nPlainLenMax != nPlainLenMax
261 || m_nRainbowTableIndex != nRainbowTableIndex
262 || m_nRainbowChainLen != nRainbowChainLen)
266 m_sHashRoutineName = sHashRoutineName;
267 m_sPlainCharsetName = sPlainCharsetName;
268 m_nPlainLenMin = nPlainLenMin;
269 m_nPlainLenMax = nPlainLenMax;
270 m_nRainbowTableIndex = nRainbowTableIndex;
271 m_nRainbowChainLen = nRainbowChainLen;
274 memcpy(cw.Hash, pHash, nHashLen);
275 cw.pIndexE = new uint64[nRainbowChainLen - 1];
276 m_lChainWalk.push_back(cw);
278 // Only update this list when we search through another rainbow table
279 updateUsedPrecalcFiles();
281 if (!FindInFile(cw.pIndexE, pHash, nHashLen))
282 fNewlyGenerated = true;
284 fNewlyGenerated = false;
288 list<ChainWalk>::iterator it;
289 for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
291 if (memcmp(it->Hash, pHash, nHashLen) == 0)
293 fNewlyGenerated = false;
299 memcpy(cw.Hash, pHash, nHashLen);
300 cw.pIndexE = new uint64[nRainbowChainLen - 1];
301 m_lChainWalk.push_back(cw);
303 if (!FindInFile(cw.pIndexE, pHash, nHashLen))
304 fNewlyGenerated = true;
306 fNewlyGenerated = false;
310 void CChainWalkSet::DiscardWalk(uint64* pIndexE)
312 list<ChainWalk>::iterator it;
313 for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
315 if (it->pIndexE == pIndexE)
318 m_lChainWalk.erase(it);
323 printf("debug: pIndexE not found\n");