]> git.sesse.net Git - freerainbowtables/blob - Client Applications/rcracki_mt/ChainWalkSet.cpp
Modify ChainWalkSet::FindInFile() to keep the precalc index in memory instead of...
[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, 2011 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 int 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                 long 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 preCalcPart;\r
85                         }\r
86                         fclose(file);\r
87                 }\r
88         }\r
89 \r
90         return -1;\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         mPrecalcIndex.clear();\r
98         char sPreCalcFileName[255];\r
99 \r
100         int i;\r
101         // 255 files max\r
102         for (i = 0; i < 255; i++)\r
103         {\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
107                 if(file==NULL) {\r
108                         break;\r
109                 }\r
110 \r
111                 vPrecalcFiles.push_back(sTryPreCalcPath);\r
112                 fclose(file);\r
113 \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
118                         continue;\r
119                 }\r
120 \r
121                 long unsigned int offset = 0;\r
122                 for (int j = 0; j < (int)precalcLines.size(); j++)\r
123                 {\r
124                         // Parse\r
125                         vector<string> vPart;\r
126                         if (!SeparateString(precalcLines[j], "___:", vPart))\r
127                         {\r
128                                 // corrupt file\r
129                                 printf("Corrupted precalculation file!\n");\r
130                                 break;\r
131                         }\r
132 \r
133                         mPrecalcIndex[precalcLines[j]] = make_pair(i, offset);\r
134                         offset += ((atoi(vPart[3].c_str())-1) * sizeof(uint64));\r
135                 }\r
136         }\r
137 }\r
138 \r
139 void CChainWalkSet::removePrecalcFiles()\r
140 {\r
141         if (debug) printf("Debug: Removing precalc files.\n");\r
142         updateUsedPrecalcFiles();\r
143         string sCurrentPrecalcPathName = "";\r
144         string sCurrentPrecalcIndexPathName = "";\r
145         \r
146         int i;\r
147         for (i = 0; i < (int)vPrecalcFiles.size(); i++)\r
148         {\r
149                 sCurrentPrecalcPathName = vPrecalcFiles[i];\r
150                 sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";\r
151 \r
152                 if (debug) printf("Debug: Removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());\r
153 \r
154                 if (remove(sCurrentPrecalcPathName.c_str()) != 0)\r
155                         if (debug) printf("Debug: Failed removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());\r
156 \r
157                 if (debug) printf("Debug: Removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());\r
158 \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
161 \r
162         }\r
163 \r
164         mPrecalcIndex.clear();\r
165 }\r
166 \r
167 bool CChainWalkSet::FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)\r
168 {\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
171 \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
175                 return false;\r
176         }\r
177 \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
181 \r
182         string sCurrentPrecalcPathName = vPrecalcFiles[fileNumber];\r
183         FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "rb");\r
184 \r
185         if (fp == NULL) {\r
186                 printf("Cannot open precalculation file %s.\n", sCurrentPrecalcPathName.c_str());\r
187                 return false;\r
188         }\r
189 \r
190         fseek(fp, offset, SEEK_SET);\r
191 \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
195                 return false;\r
196         }\r
197 \r
198         fclose(fp);\r
199         return true;\r
200 }\r
201 \r
202 void CChainWalkSet::StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)\r
203 {\r
204         if (debug) printf("\nDebug: Storing precalc\n");\r
205         \r
206         int iCurrentPrecalcPart = CheckOrRotatePreCalcFile();\r
207         if (iCurrentPrecalcPart == -1) {\r
208                 return;\r
209         }\r
210         char sCurrentPrecalcPathName[256];\r
211         sprintf(sCurrentPrecalcPathName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);\r
212         string sCurrentPrecalcIndexPathName = string(sCurrentPrecalcPathName) + ".index";\r
213 \r
214         FILE* fp = fopen(sCurrentPrecalcPathName, "ab");\r
215         if(fp!=NULL)\r
216         {\r
217                 unsigned long int offset = GetFileLen(fp);\r
218 \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
221                 else\r
222                 {\r
223                         FILE* file = fopen(sCurrentPrecalcIndexPathName.c_str(), "a");\r
224                         if (file!=NULL)\r
225                         {\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
229                                 fclose (file);\r
230                                 mPrecalcIndex[TrimString(precalculationLine)] = make_pair(iCurrentPrecalcPart, offset);\r
231                         }\r
232                 }\r
233                 fclose(fp);\r
234                 }\r
235         else\r
236                 printf("Cannot open precalculation file %s\n", sCurrentPrecalcPathName);\r
237 }\r
238 \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
245                                                                    bool setDebug,\r
246                                                                    string sPrecalc)\r
247 {\r
248         debug = setDebug;\r
249         sPrecalcPathName = sPrecalc;\r
250 \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
257         {\r
258                 DiscardAll();\r
259 \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
266 \r
267                 ChainWalk cw;\r
268                 memcpy(cw.Hash, pHash, nHashLen);\r
269                 cw.pIndexE = new uint64[nRainbowChainLen - 1];\r
270                 m_lChainWalk.push_back(cw);\r
271 \r
272                 // Only update this list when we search through another rainbow table\r
273                 updateUsedPrecalcFiles();\r
274 \r
275                 if (!FindInFile(cw.pIndexE, pHash, nHashLen))\r
276                         fNewlyGenerated = true;\r
277                 else\r
278                         fNewlyGenerated = false;\r
279                 return cw.pIndexE;\r
280         }\r
281 \r
282         list<ChainWalk>::iterator it;\r
283         for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)\r
284         {\r
285                 if (memcmp(it->Hash, pHash, nHashLen) == 0)\r
286                 {\r
287                         fNewlyGenerated = false;\r
288                         return it->pIndexE;\r
289                 }\r
290         }\r
291 \r
292         ChainWalk cw;\r
293         memcpy(cw.Hash, pHash, nHashLen);\r
294         cw.pIndexE = new uint64[nRainbowChainLen - 1];\r
295         m_lChainWalk.push_back(cw);\r
296 \r
297         if (!FindInFile(cw.pIndexE, pHash, nHashLen))\r
298                         fNewlyGenerated = true;\r
299                 else\r
300                         fNewlyGenerated = false;\r
301         return cw.pIndexE;\r
302 }\r
303 \r
304 void CChainWalkSet::DiscardWalk(uint64* pIndexE)\r
305 {\r
306         list<ChainWalk>::iterator it;\r
307         for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)\r
308         {\r
309                 if (it->pIndexE == pIndexE)\r
310                 {\r
311                         delete it->pIndexE;\r
312                         m_lChainWalk.erase(it);\r
313                         return;\r
314                 }\r
315         }\r
316 \r
317         printf("debug: pIndexE not found\n");\r
318 }\r