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