]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/ChainWalkSet.cpp
rcracki_mt updated to rti2
[freerainbowtables] / Client Applications / rcracki_mt / ChainWalkSet.cpp
1 /*
2    RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
3
4    Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
5 */
6
7 #ifdef _WIN32
8         #pragma warning(disable : 4786)
9 #endif
10
11 #include "ChainWalkSet.h"
12
13 CChainWalkSet::CChainWalkSet()
14 {
15         m_sHashRoutineName   = "";
16         m_sPlainCharsetName  = "";
17         m_nPlainLenMin       = 0;
18         m_nPlainLenMax       = 0;
19         m_nRainbowTableIndex = 0;
20         m_nRainbowChainLen   = 0;
21         debug = false;
22         sPrecalcPathName     = "";
23         preCalcPart          = 0;
24 }
25
26 CChainWalkSet::~CChainWalkSet()
27 {
28         DiscardAll();
29 }
30
31 void CChainWalkSet::DiscardAll()
32 {
33         //printf("debug: discarding all walk...\n");
34
35         list<ChainWalk>::iterator it;
36         for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
37                 delete it->pIndexE;
38         m_lChainWalk.clear();
39 }
40
41 string CChainWalkSet::CheckOrRotatePreCalcFile()
42 {
43         char sPreCalcFileName[255];
44
45         // 255 files limit to be sure
46         for (; preCalcPart < 255; preCalcPart++)
47         {
48                 sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);
49                 string sReturnPreCalcPath(sPreCalcFileName);
50
51                 unsigned int fileLen = 0;
52
53                 FILE* file = fopen(sReturnPreCalcPath.c_str(), "ab");
54                 if(file!=NULL)
55                 {
56                         fileLen = GetFileLen(file);
57                         unsigned int nextFileLen = fileLen + (sizeof(uint64) * (m_nRainbowChainLen-1));
58                         // Rotate to next file if we are going to pass 2GB filesize
59                         if (nextFileLen < ((unsigned)2 * 1024 * 1024 * 1024))
60                         {
61                                 // We might want to vPrecalcFiles.push_back(sReturnPreCalcPath) if we just created this file
62                                 // We don't as only newly generated chainwalksets will be stored to this new file, so we don't have to look there
63                                 if (debug) printf("Debug: Using for precalc: %s\n", sReturnPreCalcPath.c_str());
64                                 fclose(file);
65                                 return sReturnPreCalcPath;
66                         }
67                         fclose(file);
68                 }
69         }
70 }
71
72 void CChainWalkSet::updateUsedPrecalcFiles()
73 {
74         // we might also use this function to search a wildcard path of precalc files
75         vPrecalcFiles.clear();
76         char sPreCalcFileName[255];
77
78         int i;
79         // 255 files max
80         for (i = 0; i < 255; i++)
81         {
82                 sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), i);
83                 string sTryPreCalcPath(sPreCalcFileName);
84                 FILE* file = fopen(sTryPreCalcPath.c_str(), "rb");
85                 if(file!=NULL) {
86                         vPrecalcFiles.push_back(sTryPreCalcPath);
87                         fclose(file);
88                 }
89                 else {
90                         break;
91                 }
92         }
93 }
94
95 void CChainWalkSet::removePrecalcFiles()
96 {
97         if (debug) printf("Debug: Removing precalc files.\n");
98         updateUsedPrecalcFiles();
99         string sCurrentPrecalcPathName = "";
100         string sCurrentPrecalcIndexPathName = "";
101         
102         int i;
103         for (i = 0; i < (int)vPrecalcFiles.size(); i++)
104         {
105                 sCurrentPrecalcPathName = vPrecalcFiles[i];
106                 sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
107
108                 if (debug) printf("Debug: Removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
109
110                 if (remove(sCurrentPrecalcPathName.c_str()) != 0)
111                         if (debug) printf("Debug: Failed removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
112
113                 if (debug) printf("Debug: Removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
114
115                 if (remove(sCurrentPrecalcIndexPathName.c_str()) != 0)
116                         if (debug) printf("Debug: Failed removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
117
118         }
119 }
120
121 bool CChainWalkSet::FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
122 {
123         int gotPrecalcOnLine = -1;
124         char precalculationLine[255];
125         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() );
126         string precalcString(precalculationLine);
127
128         string sCurrentPrecalcPathName = "";
129         string sCurrentPrecalcIndexPathName = "";
130         int offset;
131
132         int i;
133         for (i = 0; i < (int)vPrecalcFiles.size() && gotPrecalcOnLine == -1; i++)
134         {
135                 sCurrentPrecalcPathName = vPrecalcFiles[i];
136                 sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
137
138                 offset = 0;
139
140                 vector<string> precalcLines;
141                 if (ReadLinesFromFile(sCurrentPrecalcIndexPathName.c_str(), precalcLines))
142                 {
143                         int j;
144                         for (j = 0; j < (int)precalcLines.size(); j++)
145                         {
146                                 if (precalcString.compare(0, precalcString.size()-1, precalcLines[j]) == 0)
147                                 {
148                                         gotPrecalcOnLine = j;
149                                         break;
150                                 }
151
152                                 // Parse
153                                 vector<string> vPart;
154                                 if (SeperateString(precalcLines[j], "___:", vPart))
155                                 {
156                                         // add to offset
157                                         offset += ((atoi(vPart[3].c_str())-1) * sizeof(uint64));
158                                 }
159                                 else {
160                                         // corrupt file
161                                         printf("Corrupted precalculation file!\n");
162                                         gotPrecalcOnLine = -1;
163                                         break;
164                                 }
165                         }
166                 }
167         }
168
169         if (gotPrecalcOnLine > -1)
170         {
171                 if (debug) printf("Debug: Reading pre calculations from file, line %d offset %d\n", gotPrecalcOnLine, offset);
172                 
173                 FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "rb");
174
175                 if (fp!=NULL) {
176                         fseek(fp, offset, SEEK_SET);
177
178                         // We should do some verification here, for example by recalculating the middle chain, to catch corrupted files
179                         if(fread(pIndexE, sizeof(uint64), m_nRainbowChainLen-1, fp) != m_nRainbowChainLen-1)
180                                 printf("File read error.");
181                         fclose(fp);
182                 }
183                 else
184                         printf("Cannot open precalculation file %s.\n", sCurrentPrecalcPathName.c_str());
185
186                 //printf("\npIndexE[0]: %s\n", uint64tostr(pIndexE[0]).c_str());
187                 //printf("\npIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pIndexE[m_nRainbowChainLen-2]).c_str());
188
189                 return true;
190         }
191
192         return false;
193
194 }
195
196 void CChainWalkSet::StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
197 {
198         if (debug) printf("\nDebug: Storing precalc\n");
199         
200         string sCurrentPrecalcPathName = CheckOrRotatePreCalcFile();
201         string sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
202
203         FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "ab");
204         if(fp!=NULL)
205         {
206                 if(fwrite(pIndexE, sizeof(uint64), m_nRainbowChainLen-1, fp) != m_nRainbowChainLen-1)
207                         printf("File write error.");
208                 else
209                 {
210                         FILE* file = fopen(sCurrentPrecalcIndexPathName.c_str(), "a");
211                         if (file!=NULL)
212                         {
213                                 char precalculationLine[255];
214                                 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() );
215                                 fputs (precalculationLine, file);
216                                 fclose (file);
217                         }
218                 }
219                 fclose(fp);
220                 }
221         else
222                 printf("Cannot open precalculation file %s\n", sCurrentPrecalcPathName.c_str());
223
224 }
225
226 uint64* CChainWalkSet::RequestWalk(unsigned char* pHash, int nHashLen,
227                                                                    string sHashRoutineName,
228                                                                    string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax, 
229                                                                    int nRainbowTableIndex, 
230                                                                    int nRainbowChainLen,
231                                                                    bool& fNewlyGenerated,
232                                                                    bool setDebug,
233                                                                    string sPrecalc)
234 {
235         debug = setDebug;
236         sPrecalcPathName = sPrecalc;
237
238         if (   m_sHashRoutineName   != sHashRoutineName
239                 || m_sPlainCharsetName  != sPlainCharsetName
240                 || m_nPlainLenMin       != nPlainLenMin
241                 || m_nPlainLenMax       != nPlainLenMax
242                 || m_nRainbowTableIndex != nRainbowTableIndex
243                 || m_nRainbowChainLen   != nRainbowChainLen)
244         {
245                 DiscardAll();
246
247                 m_sHashRoutineName   = sHashRoutineName;
248                 m_sPlainCharsetName  = sPlainCharsetName;
249                 m_nPlainLenMin       = nPlainLenMin;
250                 m_nPlainLenMax       = nPlainLenMax;
251                 m_nRainbowTableIndex = nRainbowTableIndex;
252                 m_nRainbowChainLen   = nRainbowChainLen;
253
254                 ChainWalk cw;
255                 memcpy(cw.Hash, pHash, nHashLen);
256                 cw.pIndexE = new uint64[nRainbowChainLen - 1];
257                 m_lChainWalk.push_back(cw);
258
259                 // Only update this list when we search through another rainbow table
260                 updateUsedPrecalcFiles();
261
262                 if (!FindInFile(cw.pIndexE, pHash, nHashLen))
263                         fNewlyGenerated = true;
264                 else
265                         fNewlyGenerated = false;
266                 return cw.pIndexE;
267         }
268
269         list<ChainWalk>::iterator it;
270         for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
271         {
272                 if (memcmp(it->Hash, pHash, nHashLen) == 0)
273                 {
274                         fNewlyGenerated = false;
275                         return it->pIndexE;
276                 }
277         }
278
279         ChainWalk cw;
280         memcpy(cw.Hash, pHash, nHashLen);
281         cw.pIndexE = new uint64[nRainbowChainLen - 1];
282         m_lChainWalk.push_back(cw);
283
284         if (!FindInFile(cw.pIndexE, pHash, nHashLen))
285                         fNewlyGenerated = true;
286                 else
287                         fNewlyGenerated = false;
288         return cw.pIndexE;
289 }
290
291 void CChainWalkSet::DiscardWalk(uint64* pIndexE)
292 {
293         list<ChainWalk>::iterator it;
294         for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
295         {
296                 if (it->pIndexE == pIndexE)
297                 {
298                         delete it->pIndexE;
299                         m_lChainWalk.erase(it);
300                         return;
301                 }
302         }
303
304         printf("debug: pIndexE not found\n");
305 }