2 * rcracki_mt is a multithreaded implementation and fork of the original
\r
5 * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
\r
6 * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
\r
7 * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
\r
8 * Copyright 2009, 2010, 2011 James Nobis <frt@quelrod.net>
\r
10 * This file is part of rcracki_mt.
\r
12 * rcracki_mt is free software: you can redistribute it and/or modify
\r
13 * it under the terms of the GNU General Public License as published by
\r
14 * the Free Software Foundation, either version 2 of the License, or
\r
15 * (at your option) any later version.
\r
17 * rcracki_mt is distributed in the hope that it will be useful,
\r
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
20 * GNU General Public License for more details.
\r
22 * You should have received a copy of the GNU General Public License
\r
23 * along with rcracki_mt. If not, see <http://www.gnu.org/licenses/>.
\r
26 #if defined(_WIN32) && !defined(__GNUC__)
\r
27 #pragma warning(disable : 4786)
\r
30 #include "ChainWalkSet.h"
\r
32 CChainWalkSet::CChainWalkSet()
\r
34 m_sHashRoutineName = "";
\r
35 m_sPlainCharsetName = "";
\r
38 m_nRainbowTableIndex = 0;
\r
39 m_nRainbowChainLen = 0;
\r
41 sPrecalcPathName = "";
\r
45 CChainWalkSet::~CChainWalkSet()
\r
50 void CChainWalkSet::DiscardAll()
\r
52 //printf("debug: discarding all walk...\n");
\r
54 list<ChainWalk>::iterator it;
\r
55 for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
\r
56 delete [] it->pIndexE;
\r
57 m_lChainWalk.clear();
\r
60 int CChainWalkSet::CheckOrRotatePreCalcFile()
\r
62 char sPreCalcFileName[255];
\r
64 // 255 files limit to be sure
\r
65 for (; preCalcPart < 255; preCalcPart++)
\r
67 sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);
\r
68 string sReturnPreCalcPath(sPreCalcFileName);
\r
72 FILE* file = fopen(sReturnPreCalcPath.c_str(), "ab");
\r
75 fileLen = GetFileLen(file);
\r
76 long unsigned int nextFileLen = fileLen + (sizeof(uint64) * (m_nRainbowChainLen-1));
\r
77 // Rotate to next file if we are going to pass 2GB filesize
\r
78 if (nextFileLen < ((unsigned)2 * 1024 * 1024 * 1024))
\r
80 // We might want to vPrecalcFiles.push_back(sReturnPreCalcPath) if we just created this file
\r
81 // We don't as only newly generated chainwalksets will be stored to this new file, so we don't have to look there
\r
82 if (debug) printf("Debug: Using for precalc: %s\n", sReturnPreCalcPath.c_str());
\r
93 void CChainWalkSet::updateUsedPrecalcFiles()
\r
95 // we might also use this function to search a wildcard path of precalc files
\r
96 vPrecalcFiles.clear();
\r
97 mPrecalcIndex.clear();
\r
98 char sPreCalcFileName[255];
\r
102 for (i = 0; i < 255; i++)
\r
104 sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), i);
\r
105 string sTryPreCalcPath(sPreCalcFileName);
\r
106 FILE* file = fopen(sTryPreCalcPath.c_str(), "rb");
\r
111 vPrecalcFiles.push_back(sTryPreCalcPath);
\r
114 // Load the index file into our cache.
\r
115 string sCurrentPrecalcIndexPathName = sTryPreCalcPath + ".index";
\r
116 vector<string> precalcLines;
\r
117 if (!ReadLinesFromFile(sCurrentPrecalcIndexPathName.c_str(), precalcLines)) {
\r
121 long unsigned int offset = 0;
\r
122 for (int j = 0; j < (int)precalcLines.size(); j++)
\r
125 vector<string> vPart;
\r
126 if (!SeparateString(precalcLines[j], "___:", vPart))
\r
129 printf("Corrupted precalculation file!\n");
\r
133 mPrecalcIndex[precalcLines[j]] = make_pair(i, offset);
\r
134 offset += ((atoi(vPart[3].c_str())-1) * sizeof(uint64));
\r
139 void CChainWalkSet::removePrecalcFiles()
\r
141 if (debug) printf("Debug: Removing precalc files.\n");
\r
142 updateUsedPrecalcFiles();
\r
143 string sCurrentPrecalcPathName = "";
\r
144 string sCurrentPrecalcIndexPathName = "";
\r
147 for (i = 0; i < (int)vPrecalcFiles.size(); i++)
\r
149 sCurrentPrecalcPathName = vPrecalcFiles[i];
\r
150 sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
\r
152 if (debug) printf("Debug: Removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
\r
154 if (remove(sCurrentPrecalcPathName.c_str()) != 0)
\r
155 if (debug) printf("Debug: Failed removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
\r
157 if (debug) printf("Debug: Removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
\r
159 if (remove(sCurrentPrecalcIndexPathName.c_str()) != 0)
\r
160 if (debug) printf("Debug: Failed removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
\r
164 mPrecalcIndex.clear();
\r
167 bool CChainWalkSet::FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
\r
169 char precalculationLine[255];
\r
170 sprintf(precalculationLine, "%s_%s#%d-%d_%d_%d:%s", m_sHashRoutineName.c_str(), m_sPlainCharsetName.c_str(), m_nPlainLenMin, m_nPlainLenMax, m_nRainbowTableIndex, m_nRainbowChainLen, HexToStr(pHash, nHashLen).c_str() );
\r
172 map<string, pair<int, unsigned long int> >::const_iterator precalc_it =
\r
173 mPrecalcIndex.find(precalculationLine);
\r
174 if (precalc_it == mPrecalcIndex.end()) {
\r
178 int fileNumber = precalc_it->second.first;
\r
179 unsigned long int offset = precalc_it->second.second;
\r
180 if (debug) printf("Debug: Reading pre calculations from file, file %d offset %lu\n", fileNumber, offset);
\r
182 string sCurrentPrecalcPathName = vPrecalcFiles[fileNumber];
\r
183 FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "rb");
\r
186 printf("Cannot open precalculation file %s.\n", sCurrentPrecalcPathName.c_str());
\r
190 fseek(fp, offset, SEEK_SET);
\r
192 // We should do some verification here, for example by recalculating the middle chain, to catch corrupted files
\r
193 if(fread(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1) {
\r
194 printf("File read error.");
\r
202 void CChainWalkSet::StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
\r
204 if (debug) printf("\nDebug: Storing precalc\n");
\r
206 int iCurrentPrecalcPart = CheckOrRotatePreCalcFile();
\r
207 if (iCurrentPrecalcPart == -1) {
\r
210 char sCurrentPrecalcPathName[256];
\r
211 sprintf(sCurrentPrecalcPathName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);
\r
212 string sCurrentPrecalcIndexPathName = string(sCurrentPrecalcPathName) + ".index";
\r
214 FILE* fp = fopen(sCurrentPrecalcPathName, "ab");
\r
217 unsigned long int offset = GetFileLen(fp);
\r
219 if(fwrite(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1)
\r
220 printf("File write error.");
\r
223 FILE* file = fopen(sCurrentPrecalcIndexPathName.c_str(), "a");
\r
226 char precalculationLine[255];
\r
227 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() );
\r
228 fputs (precalculationLine, file);
\r
230 mPrecalcIndex[TrimString(precalculationLine)] = make_pair(iCurrentPrecalcPart, offset);
\r
236 printf("Cannot open precalculation file %s\n", sCurrentPrecalcPathName);
\r
239 uint64* CChainWalkSet::RequestWalk(unsigned char* pHash, int nHashLen,
\r
240 string sHashRoutineName,
\r
241 string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax,
\r
242 int nRainbowTableIndex,
\r
243 int nRainbowChainLen,
\r
244 bool& fNewlyGenerated,
\r
249 sPrecalcPathName = sPrecalc;
\r
251 if ( m_sHashRoutineName != sHashRoutineName
\r
252 || m_sPlainCharsetName != sPlainCharsetName
\r
253 || m_nPlainLenMin != nPlainLenMin
\r
254 || m_nPlainLenMax != nPlainLenMax
\r
255 || m_nRainbowTableIndex != nRainbowTableIndex
\r
256 || m_nRainbowChainLen != nRainbowChainLen)
\r
260 m_sHashRoutineName = sHashRoutineName;
\r
261 m_sPlainCharsetName = sPlainCharsetName;
\r
262 m_nPlainLenMin = nPlainLenMin;
\r
263 m_nPlainLenMax = nPlainLenMax;
\r
264 m_nRainbowTableIndex = nRainbowTableIndex;
\r
265 m_nRainbowChainLen = nRainbowChainLen;
\r
268 memcpy(cw.Hash, pHash, nHashLen);
\r
269 cw.pIndexE = new uint64[nRainbowChainLen - 1];
\r
270 m_lChainWalk.push_back(cw);
\r
272 // Only update this list when we search through another rainbow table
\r
273 updateUsedPrecalcFiles();
\r
275 if (!FindInFile(cw.pIndexE, pHash, nHashLen))
\r
276 fNewlyGenerated = true;
\r
278 fNewlyGenerated = false;
\r
282 list<ChainWalk>::iterator it;
\r
283 for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
\r
285 if (memcmp(it->Hash, pHash, nHashLen) == 0)
\r
287 fNewlyGenerated = false;
\r
288 return it->pIndexE;
\r
293 memcpy(cw.Hash, pHash, nHashLen);
\r
294 cw.pIndexE = new uint64[nRainbowChainLen - 1];
\r
295 m_lChainWalk.push_back(cw);
\r
297 if (!FindInFile(cw.pIndexE, pHash, nHashLen))
\r
298 fNewlyGenerated = true;
\r
300 fNewlyGenerated = false;
\r
304 void CChainWalkSet::DiscardWalk(uint64* pIndexE)
\r
306 list<ChainWalk>::iterator it;
\r
307 for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
\r
309 if (it->pIndexE == pIndexE)
\r
311 delete it->pIndexE;
\r
312 m_lChainWalk.erase(it);
\r
317 printf("debug: pIndexE not found\n");
\r