]> git.sesse.net Git - freerainbowtables/commitdiff
Merge branch 'master' of git@gitorious.org:freerainbowtables-applications/freerainbow...
authorJames Nobis <quel@quelrod.net>
Sun, 7 Nov 2010 01:19:23 +0000 (20:19 -0500)
committerJames Nobis <quel@quelrod.net>
Sun, 7 Nov 2010 01:19:23 +0000 (20:19 -0500)
Conflicts:

Client Applications/rcracki_mt/ChainWalkContext.cpp
Client Applications/rcracki_mt/ChainWalkContext.h
Client Applications/rcracki_mt/CrackEngine.cpp
Client Applications/rcracki_mt/HashAlgorithm.cpp
Client Applications/rcracki_mt/HashRoutine.cpp
Client Applications/rcracki_mt/HashSet.cpp
Client Applications/rcracki_mt/MemoryPool.cpp
Client Applications/rcracki_mt/MemoryPool.h
Client Applications/rcracki_mt/Public.cpp
Client Applications/rcracki_mt/Public.h
Client Applications/rcracki_mt/RTI2Reader.cpp
Client Applications/rcracki_mt/RTI2Reader.h
Client Applications/rcracki_mt/RainbowCrack.cpp
Client Applications/rcracki_mt/lm2ntlm.cpp
Client Applications/rcracki_mt/md4.cpp
Client Applications/rcracki_mt/rcrackiThread.cpp
Client Applications/rcracki_mt/sha1.cpp
Client Applications/rti2rto/rti2rto.cpp
Common/rt api/BaseRTReader.h
Common/rt api/MemoryPool.cpp
Common/rt api/RTI2Reader.cpp
Common/rt api/RTIReader.cpp

merging with PB's changes
UINT4 -> uint32 changes
misc fixes for rti2
misc fixes for long 64/32 compat

46 files changed:
Client Applications/converti2/Makefile
Client Applications/converti2/Public.cpp [deleted file]
Client Applications/converti2/Public.h [deleted file]
Client Applications/converti2/converti2.cpp [changed mode: 0644->0755]
Client Applications/converti2/converti2.suo [changed mode: 0644->0755]
Client Applications/rcracki_mt/BaseRTReader.cpp [new file with mode: 0644]
Client Applications/rcracki_mt/BaseRTReader.h [new file with mode: 0644]
Client Applications/rcracki_mt/ChainWalkContext.cpp
Client Applications/rcracki_mt/ChainWalkContext.h
Client Applications/rcracki_mt/ChainWalkSet.cpp
Client Applications/rcracki_mt/CrackEngine.cpp
Client Applications/rcracki_mt/HashAlgorithm.cpp
Client Applications/rcracki_mt/HashRoutine.cpp
Client Applications/rcracki_mt/HashSet.cpp
Client Applications/rcracki_mt/MemoryPool.cpp
Client Applications/rcracki_mt/MemoryPool.h
Client Applications/rcracki_mt/Public.cpp
Client Applications/rcracki_mt/Public.h
Client Applications/rcracki_mt/RTI2Reader.cpp [new file with mode: 0644]
Client Applications/rcracki_mt/RTI2Reader.h [new file with mode: 0644]
Client Applications/rcracki_mt/RainbowCrack.cpp
Client Applications/rcracki_mt/fast_md5.cpp
Client Applications/rcracki_mt/global.h
Client Applications/rcracki_mt/lm2ntlm.cpp
Client Applications/rcracki_mt/md4.cpp
Client Applications/rcracki_mt/rcrackiThread.cpp
Client Applications/rcracki_mt/sha1.cpp
Client Applications/rti2rto/Makefile
Client Applications/rti2rto/rti2rto.cpp
Common/rt api/BaseRTReader.cpp
Common/rt api/BaseRTReader.h
Common/rt api/ChainWalkContext.cpp
Common/rt api/ChainWalkContext.h
Common/rt api/ChainWalkSet.cpp
Common/rt api/ChainWalkSet.h
Common/rt api/HashAlgorithm.cpp
Common/rt api/HashRoutine.cpp
Common/rt api/HashRoutine.h
Common/rt api/MemoryPool.cpp
Common/rt api/MemoryPool.h
Common/rt api/Public.cpp
Common/rt api/Public.h
Common/rt api/RTI2Reader.cpp
Common/rt api/RTI2Reader.h
Common/rt api/RTIReader.cpp
Common/rt api/md4.cpp

index d3715df887e3b7ffc361adb2f59babe1375454ee..4886c1a12d5011194f4dd31f9265eb51d1a34189 100644 (file)
@@ -3,10 +3,10 @@ CC = g++
 OPTIMIZATION = -O3
 INCLUDES = -I../../Common/rt\ api
 # XXX todo currently only 32-bit targets work
-CFLAGS = -Wall -m32 -ansi $(INCLUDES) $(OPTIMIZATION) -c
-LFLAGS = -Wall -m32 -ansi $(INCLUDES) $(OPTIMIZATION)
+CFLAGS = -Wall -m32 -ansi $(INCLUDES) $(OPTIMIZATION) -c $(DEBUG)
+LFLAGS = -Wall -m32 -ansi $(INCLUDES) $(OPTIMIZATION) $(DEBUG)
 LIBS = 
-OBJS = MemoryPool.o Public.o
+OBJS = MemoryPool.o Public.o RTI2Reader.o RTIReader.o RTReader.o
 COMMON_API_PATH = ../../Common/rt\ api
 
 all: converti2
@@ -17,10 +17,25 @@ converti2: $(OBJS)
 clean:
        rm -f *.o converti2
 
+debug: DEBUG += -DDEBUG -g
+debug: all
+
+#m32: DEBUG += -m32
+#m32: converti2
+
 rebuild: clean all
 
-MemoryPool.o: $(COMMON_API_PATH)/MemoryPool.h $(COMMON_API_PATH)/MemoryPool.cpp Public.h
+MemoryPool.o: $(COMMON_API_PATH)/MemoryPool.h $(COMMON_API_PATH)/MemoryPool.cpp $(COMMON_API_PATH)/Public.h
        $(CC) $(CFLAGS) $(COMMON_API_PATH)/MemoryPool.cpp
 
-Public.o: Public.h Public.cpp
-       $(CC) $(CFLAGS) Public.cpp
+Public.o: $(COMMON_API_PATH)/Public.h $(COMMON_API_PATH)/Public.cpp
+       $(CC) $(CFLAGS) $(COMMON_API_PATH)/Public.cpp
+
+RTI2Reader.o: $(COMMON_API_PATH)/RTI2Reader.h $(COMMON_API_PATH)/RTI2Reader.cpp
+       $(CC) $(CFLAGS) $(COMMON_API_PATH)/RTI2Reader.cpp
+
+RTIReader.o: $(COMMON_API_PATH)/RTIReader.h $(COMMON_API_PATH)/RTIReader.cpp
+       $(CC) $(CFLAGS) $(COMMON_API_PATH)/RTIReader.cpp
+
+RTReader.o: $(COMMON_API_PATH)/RTReader.h $(COMMON_API_PATH)/RTReader.cpp
+       $(CC) $(CFLAGS) $(COMMON_API_PATH)/RTReader.cpp
diff --git a/Client Applications/converti2/Public.cpp b/Client Applications/converti2/Public.cpp
deleted file mode 100644 (file)
index 7e54203..0000000
+++ /dev/null
@@ -1,319 +0,0 @@
-/*
- * freerainbowtables is a project for generating, distributing, and using
- * perfect rainbow tables
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of freerainbowtables.
- *
- * freerainbowtables is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * freerainbowtables is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
-*/
-
-#ifdef _WIN32
-       #pragma warning(disable : 4786)
-#endif
-
-#ifdef _WIN32
-
-#else
-#include <cstdio>
-#include <cctype>
-#include <ctime>
-#include <cstring>
-#include <cstdlib>
-#include <csignal>
-#include <unistd.h>
-
-#endif
-
-#include "Public.h"
-
-#ifdef _WIN32
-       #include <windows.h>
-#elif defined(__APPLE__) || \
-       ((defined(__unix__) || defined(unix)) && !defined(USG))
-
-       #include <sys/param.h>
-
-       #if defined(BSD)
-               #include <sys/sysctl.h>
-       #elif defined(__linux__)
-               #include <sys/sysinfo.h>
-       #else
-               #error Unsupported Operating system
-       #endif
-#endif
-
-//////////////////////////////////////////////////////////////////////
-
-unsigned int GetFileLen(FILE* file)
-{
-       unsigned int pos = ftell(file);
-       fseek(file, 0, SEEK_END);
-       unsigned int len = ftell(file);
-       fseek(file, pos, SEEK_SET);
-
-       return len;
-}
-
-string TrimString(string s)
-{
-       while (s.size() > 0)
-       {
-               if (s[0] == ' ' || s[0] == '\t')
-                       s = s.substr(1);
-               else
-                       break;
-       }
-
-       while (s.size() > 0)
-       {
-               if (s[s.size() - 1] == ' ' || s[s.size() - 1] == '\t')
-                       s = s.substr(0, s.size() - 1);
-               else
-                       break;
-       }
-
-       return s;
-}
-bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset)
-{
-       // Example: hybrid(mixalpha-numeric-all-space#1-6,numeric#1-4)
-       if(sCharset.substr(0, 6) != "hybrid") // Not hybrid charset
-               return false;
-
-       UINT4 nEnd = (int) sCharset.rfind(')');
-       UINT4 nStart = (int) sCharset.rfind('(');
-       string sChar = sCharset.substr(nStart + 1, nEnd - nStart - 1);
-       vector<string> vParts;
-       SeperateString(sChar, ",", vParts);
-       for(UINT4 i = 0; i < vParts.size(); i++)
-       {
-               tCharset stCharset;
-               vector<string> vParts2;
-               SeperateString(vParts[i], "#", vParts2);
-               stCharset.sName = vParts2[0];
-               vector<string> vParts3;
-               SeperateString(vParts2[1], "-", vParts3);
-               stCharset.nPlainLenMin = atoi(vParts3[0].c_str());
-               stCharset.nPlainLenMax = atoi(vParts3[1].c_str());
-               vCharset.push_back(stCharset);
-       }
-       return true;
-}
-bool ReadLinesFromFile(string sPathName, vector<string>& vLine)
-{
-       vLine.clear();
-    FILE *file = fopen(sPathName.c_str(), "rb");
-       if (file != NULL)
-       {
-               unsigned int len = GetFileLen(file);
-               char* data = new char[len + 1];
-               fread(data, 1, len, file);
-               data[len] = '\0';
-               string content = data;
-               content += "\n";
-               delete [] data;
-
-               unsigned int i;
-               for (i = 0; i < content.size(); i++)
-               {
-                       if (content[i] == '\r')
-                               content[i] = '\n';
-               }
-
-               int n;
-               while ((n = content.find("\n", 0)) != -1)
-               {
-                       string line = content.substr(0, n);
-                       line = TrimString(line);
-                       if (line != "")
-                               vLine.push_back(line);
-                       content = content.substr(n + 1);
-               }
-
-               fclose(file);
-       }
-       else
-               return false;
-
-       return true;
-}
-
-bool SeperateString(string s, string sSeperator, vector<string>& vPart)
-{
-       vPart.clear();
-
-       unsigned int i;
-       for (i = 0; i < sSeperator.size(); i++)
-       {
-               int n = s.find(sSeperator[i]);
-               if (n != -1)
-               {
-                       vPart.push_back(s.substr(0, n));
-                       s = s.substr(n + 1);
-               }
-               else
-                       return false;
-       }
-       vPart.push_back(s);
-
-       return true;
-}
-
-string uint64tostr(uint64 n)
-{
-       char str[32];
-
-#ifdef _WIN32
-       sprintf(str, "%I64u", n);
-#else
-       sprintf(str, "%llu", n);
-#endif
-
-       return str;
-}
-
-string uint64tohexstr(uint64 n)
-{
-       char str[32];
-
-#ifdef _WIN32
-       sprintf(str, "%016I64x", n);
-#else
-       sprintf(str, "%016llx", n);
-#endif
-
-       return str;
-}
-
-string HexToStr(const unsigned char* pData, int nLen)
-{
-       string sRet;
-       int i;
-       for (i = 0; i < nLen; i++)
-       {
-               char szByte[3];
-               sprintf(szByte, "%02x", pData[i]);
-               sRet += szByte;
-       }
-
-       return sRet;
-}
-
-uint64 GetAvailPhysMemorySize()
-{
-#ifdef _WIN32
-       MEMORYSTATUS ms;
-       GlobalMemoryStatus(&ms);
-       return ms.dwAvailPhys;
-#elif defined(BSD)
-       int mib[2] = { CTL_HW, HW_PHYSMEM };
-       uint64 physMem;
-       //XXX warning size_t isn't portable
-       size_t len;
-       len = sizeof(physMem);
-       sysctl(mib, 2, &physMem, &len, NULL, 0);
-       return physMem;
-#elif defined(__linux__)
-       struct sysinfo info;
-       sysinfo(&info);
-       return ( info.freeram + info.bufferram ) * (unsigned long) info.mem_unit;
-#else
-       return 0;
-       #error Unsupported Operating System
-#endif
-}
-
-void ParseHash(string sHash, unsigned char* pHash, int& nHashLen)
-{
-       UINT4 i;
-       for (i = 0; i < sHash.size() / 2; i++)
-       {
-               string sSub = sHash.substr(i * 2, 2);
-               int nValue;
-               sscanf(sSub.c_str(), "%02x", &nValue);
-               pHash[i] = (unsigned char)nValue;
-       }
-
-       nHashLen = sHash.size() / 2;
-}
-
-void Logo()
-{
-       printf("RainbowCrack (improved) 2.0 - Making a Faster Cryptanalytic Time-Memory Trade-Off\n");
-       printf("by Martin Westergaard <martinwj2005@gmail.com>\n");
-       printf("http://www.freerainbowtables.com/\n");
-       printf("original code by Zhu Shuanglei <shuanglei@hotmail.com>\n");
-       printf("http://www.antsight.com/zsl/rainbowcrack/\n\n");
-}
-
-// XXX nmap is GPL2, will check newer releases regarding license
-// Code comes from nmap, used for the linux implementation of kbhit()
-#ifndef _WIN32
-
-static int tty_fd = 0;
-struct termios saved_ti;
-
-int tty_getchar()
-{
-       int c, numChars;
-
-       if (tty_fd && tcgetpgrp(tty_fd) == getpid()) {
-               c = 0;
-               numChars = read(tty_fd, &c, 1);
-               if (numChars > 0) return c;
-       }
-
-       return -1;
-}
-
-void tty_done()
-{
-       if (!tty_fd) return;
-
-       tcsetattr(tty_fd, TCSANOW, &saved_ti);
-
-       close(tty_fd);
-       tty_fd = 0;
-}
-
-void tty_init()
-{
-       struct termios ti;
-
-       if (tty_fd)
-               return;
-
-       if ((tty_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return;
-
-       tcgetattr(tty_fd, &ti);
-       saved_ti = ti;
-       ti.c_lflag &= ~(ICANON | ECHO);
-       ti.c_cc[VMIN] = 1;
-       ti.c_cc[VTIME] = 0;
-       tcsetattr(tty_fd, TCSANOW, &ti);
-
-       atexit(tty_done);
-}
-
-void tty_flush(void)
-{
-       tcflush(tty_fd, TCIFLUSH);
-}
-// end nmap code
-#endif
diff --git a/Client Applications/converti2/Public.h b/Client Applications/converti2/Public.h
deleted file mode 100644 (file)
index 6c15430..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * freerainbowtables is a project for generating, distributing, and using
- * perfect rainbow tables
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of freerainbowtables.
- *
- * freerainbowtables is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * freerainbowtables is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _PUBLIC_H
-#define _PUBLIC_H
-
-#include <stdio.h>
-
-#include <string>
-#include <vector>
-#include <list>
-
-#include "global.h"
-
-using namespace std;
-
-struct RainbowChain
-{
-       uint64 nIndexS;
-       uint64 nIndexE;
-};
-
-struct RainbowChainCP
-{
-       uint64 nIndexS;
-       uint64 nIndexE;
-       unsigned short nCheckPoint;
-};
-struct IndexChain
-{
-       uint64 nPrefix;
-       int nFirstChain;
-       unsigned int nChainCount;
-};
-struct FoundRainbowChain
-{
-       uint64 nIndexS;
-       int nIndexE;
-       int nCheckPoint;
-       int nGuessedPos;
-};
-struct ChainCheckChain
-{
-       uint64 nIndexS;
-       int nGuessedPos;
-};
-struct IndexRow
-{
-       uint64 prefix;
-       unsigned int prefixstart, numchains;
-};
-
-typedef struct
-{
-       string sName;
-       int nPlainLenMin;
-       int nPlainLenMax;
-} tCharset;
-
-#define MAX_PLAIN_LEN 256
-#define MIN_HASH_LEN  8
-#define MAX_HASH_LEN  256
-#define MAX_SALT_LEN  256
-
-// XXX nmap is GPL2, will check newer releases regarding license
-// Code comes from nmap, used for the linux implementation of kbhit()
-#ifndef _WIN32
-#include <unistd.h>
-#include <termios.h>
-#include <fcntl.h>
-
-int tty_getchar();
-void tty_done();
-void tty_init();
-void tty_flush(void);
-// end nmap code
-
-#endif
-
-unsigned int GetFileLen(FILE* file);
-string TrimString(string s);
-bool ReadLinesFromFile(string sPathName, vector<string>& vLine);
-bool SeperateString(string s, string sSeperator, vector<string>& vPart);
-string uint64tostr(uint64 n);
-string uint64tohexstr(uint64 n);
-string HexToStr(const unsigned char* pData, int nLen);
-uint64 GetAvailPhysMemorySize();
-void ParseHash(string sHash, unsigned char* pHash, int& nHashLen);
-bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset);
-void Logo();
-
-#endif
old mode 100644 (file)
new mode 100755 (executable)
index 1d8d5e7..da728c3
@@ -1,7 +1,8 @@
 #include <string>
 #include <vector>
 #ifdef _WIN32
-#include <io.h>
+       #include <io.h>
+       #include <conio.h>
 #else
        #include <sys/types.h>
        #include <sys/stat.h>
@@ -13,7 +14,6 @@
 #include <time.h>
 #include <math.h>
 #include <vector>
-#include <conio.h>
 #include <sstream>
 #include "Public.h"
 #include "MemoryPool.h"
@@ -319,7 +319,7 @@ void ConvertRainbowTable(string sPathName, string sResultFileName, unsigned int
                        static CMemoryPool mp;
                        unsigned int nAllocatedSize;
                        RainbowChain* pChain = (RainbowChain*)mp.Allocate(size, nAllocatedSize);                        
-                       unsigned int chainrowsize = ceil((float)(rti_startptlength + rti_endptlength + rti_cplength) / 8) * 8 ; // The size in bits (in whole bytes)
+                       uint32 chainrowsize = (uint32)ceil((float)(rti_startptlength + rti_endptlength + rti_cplength) / 8) * 8 ; // The size in bits (in whole bytes)
                        unsigned int chainrowsizebytes = chainrowsize / 8;
 
                        if (pChain != NULL)     {
@@ -333,7 +333,7 @@ void ConvertRainbowTable(string sPathName, string sResultFileName, unsigned int
 /*                                     if (ftell(file) == nFileLen)
                                                break;*/
                                        printf("%u chains left to read\n", chainsLeft);
-                                       int nReadThisRound;
+                                       //int nReadThisRound;
                                        clock_t t1 = clock();
                                        printf("reading...\n");
 #ifdef _MEMORYDEBUG
@@ -348,7 +348,7 @@ void ConvertRainbowTable(string sPathName, string sResultFileName, unsigned int
                                        printf("reading time: %.2f s\n", fTime);                
                                        printf("converting %i chains...\n", nChains);
                                        t1 = clock();
-                                       for(int i = 0; i < nChains; i++)        {
+                                       for(unsigned int i = 0; i < nChains; i++)       {
                                                if(showDistribution == 1) {
                                                        distribution[GetMaxBits(pChain[i].nIndexS)-1]++;
                                                }
@@ -417,7 +417,7 @@ void ConvertRainbowTable(string sPathName, string sResultFileName, unsigned int
 //                                     unsigned int m_rti_index_prefixlength = GetMaxBits(high.prefix);
                                unsigned int m_rti_index_numchainslength = GetMaxBits(high.numchains);
 //                                     unsigned int m_rti_index_indexlength = GetMaxBits(high.prefixstart);
-                               unsigned int m_indexrowsize = ceil((float)(/*m_rti_index_indexlength + */m_rti_index_numchainslength) / 8) * 8; // The size in bits (in whole bytes)    
+                               uint32 m_indexrowsize = (uint32)ceil((float)(/*m_rti_index_indexlength + */m_rti_index_numchainslength) / 8) * 8; // The size in bits (in whole bytes)  
                                unsigned int m_indexrowsizebytes = m_indexrowsize / 8;
                                FILE *pFileIndex = fopen(sResultFileName.append(".index").c_str(), "wb");
                                fwrite("RTI2", 1, 4, pFileIndex);
@@ -438,7 +438,7 @@ void ConvertRainbowTable(string sPathName, string sResultFileName, unsigned int
                                        if(i == 0) {
                                                lastPrefix = indexes[0].prefix;
                                        }
-                                       unsigned int indexrow = 0;
+                                       //unsigned int indexrow = 0;
                                        // Checks how big a distance there is between the current and the next prefix. eg cur is 3 and next is 10 = 7.
                                        unsigned int diffSize = indexes[i].prefix - lastPrefix; 
                                        if(i > 0 && diffSize > 1) {
@@ -617,4 +617,4 @@ int main(int argc, char* argv[])
                printf("\n");
        }
        return 0;
-}
\ No newline at end of file
+}
old mode 100644 (file)
new mode 100755 (executable)
index 969775d..8a63fa9
Binary files a/Client Applications/converti2/converti2.suo and b/Client Applications/converti2/converti2.suo differ
diff --git a/Client Applications/rcracki_mt/BaseRTReader.cpp b/Client Applications/rcracki_mt/BaseRTReader.cpp
new file mode 100644 (file)
index 0000000..9b797ec
--- /dev/null
@@ -0,0 +1,25 @@
+/*
+ * rcracki_mt is a multithreaded implementation and fork of the original 
+ * RainbowCrack
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of rcracki_mt.
+ *
+ * rcracki_mt is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * rcracki_mt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "BaseRTReader.h"
diff --git a/Client Applications/rcracki_mt/BaseRTReader.h b/Client Applications/rcracki_mt/BaseRTReader.h
new file mode 100644 (file)
index 0000000..a662ff4
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * rcracki_mt is a multithreaded implementation and fork of the original 
+ * RainbowCrack
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of rcracki_mt.
+ *
+ * rcracki_mt is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * rcracki_mt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __BASERTREADER_H__
+#define __BASERTREADER_H__
+
+#include "Public.h"
+#include <string>
+
+#if defined(_WIN32) && !defined(__GNUC__)
+       #include <io.h>
+#endif
+
+using namespace std;
+
+class BaseRTReader
+{
+public:
+       virtual int ReadChains(uint32 &numChains, RainbowChainO *pData) = 0;
+       virtual uint32 GetChainsLeft() = 0;
+       
+       virtual ~BaseRTReader()  { };
+};
+
+#endif
index 01a46e023e1d81f81019b8c28fba03480f8e4ba5..417d90013b4eee211aaedb431b90cd11bdd63e80 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- * Copyright 2010 Yngve AAdlandsvik
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "ChainWalkContext.h"
-
-#include <ctype.h>
-
-//////////////////////////////////////////////////////////////////////
-
-string CChainWalkContext::m_sHashRoutineName;
-HASHROUTINE CChainWalkContext::m_pHashRoutine;
-int CChainWalkContext::m_nHashLen;
-int CChainWalkContext::m_nPlainLenMinTotal = 0;
-int CChainWalkContext::m_nPlainLenMaxTotal = 0;
-int CChainWalkContext::m_nHybridCharset = 0;
-bool CChainWalkContext::isOldRtFormat = false;
-bool CChainWalkContext::isRti2RtFormat = false;
-vector<stCharset> CChainWalkContext::m_vCharset;
-uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];
-uint64 CChainWalkContext::m_nPlainSpaceTotal;
-unsigned char CChainWalkContext::m_Salt[MAX_SALT_LEN];
-int CChainWalkContext::m_nSaltLen = 0;
-int CChainWalkContext::m_nRainbowTableIndex;
-uint64 CChainWalkContext::m_nReduceOffset;
-
-//////////////////////////////////////////////////////////////////////
-
-CChainWalkContext::CChainWalkContext()
-{
-}
-
-CChainWalkContext::~CChainWalkContext()
-{
-}
-
-bool CChainWalkContext::LoadCharset(string sName)
-{
-       m_vCharset.clear();
-       if (sName == "byte")
-       {
-               stCharset tCharset;
-               int i;
-               for (i = 0x00; i <= 0xff; i++)
-                       tCharset.m_PlainCharset[i] = (unsigned char) i;
-               tCharset.m_nPlainCharsetLen = 256;
-               tCharset.m_sPlainCharsetName = sName;
-               tCharset.m_sPlainCharsetContent = "0x00, 0x01, ... 0xff";
-               m_vCharset.push_back(tCharset);
-               return true;
-       }
-       if(sName.substr(0, 6) == "hybrid") // Hybrid charset consisting of 2 charsets
-               m_nHybridCharset = 1;           
-       else
-               m_nHybridCharset = 0;
-       
-       bool readCharset = false;
-       vector<string> vLine;
-
-       if ( ReadLinesFromFile("charset.txt", vLine) )
-               readCharset = true;
-       else if ( ReadLinesFromFile(GetApplicationPath() + "charset.txt", vLine) )
-               readCharset = true;
-
-       if (readCharset)
-       {
-               UINT4 i;
-               for (i = 0; i < vLine.size(); i++)
-               {
-                       // Filter comment
-                       if (vLine[i][0] == '#')
-                               continue;
-
-                       vector<string> vPart;
-                       if (SeperateString(vLine[i], "=", vPart))
-                       {
-                               // sCharsetName
-                               string sCharsetName = TrimString(vPart[0]);
-                               if (sCharsetName == "")
-                                       continue;
-                                                               
-                               // sCharsetName charset check
-                               bool fCharsetNameCheckPass = true;
-                               UINT4 j;
-                               for (j = 0; j < sCharsetName.size(); j++)
-                               {
-                                       if (   !isalpha(sCharsetName[j])
-                                               && !isdigit(sCharsetName[j])
-                                               && (sCharsetName[j] != '-'))
-                                       {
-                                               fCharsetNameCheckPass = false;
-                                               break;
-                                       }
-                               }
-                               if (!fCharsetNameCheckPass)
-                               {
-                                       printf("invalid charset name %s in charset configuration file\n", sCharsetName.c_str());
-                                       continue;
-                               }
-
-                               // sCharsetContent
-                               string sCharsetContent = TrimString(vPart[1]);
-                               if (sCharsetContent == "" || sCharsetContent == "[]")
-                                       continue;
-                               if (sCharsetContent[0] != '[' || sCharsetContent[sCharsetContent.size() - 1] != ']')
-                               {
-                                       printf("invalid charset content %s in charset configuration file\n", sCharsetContent.c_str());
-                                       continue;
-                               }
-                               sCharsetContent = sCharsetContent.substr(1, sCharsetContent.size() - 2);
-                               if (sCharsetContent.size() > 256)
-                               {
-                                       printf("charset content %s too long\n", sCharsetContent.c_str());
-                                       continue;
-                               }
-
-                               //printf("%s = [%s]\n", sCharsetName.c_str(), sCharsetContent.c_str());
-
-                               // Is it the wanted charset?
-                               if(m_nHybridCharset == 1)
-                               {
-                                       vector<tCharset> vCharsets;
-                                       GetHybridCharsets(sName, vCharsets);
-                                       if(sCharsetName == vCharsets[m_vCharset.size()].sName)
-                                       {
-                                               stCharset tCharset;
-                                               tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   
-                                               memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);
-                                               tCharset.m_sPlainCharsetName = sCharsetName;
-                                               tCharset.m_sPlainCharsetContent = sCharsetContent;      
-                                               tCharset.m_nPlainLenMin = vCharsets[m_vCharset.size()].nPlainLenMin;
-                                               tCharset.m_nPlainLenMax = vCharsets[m_vCharset.size()].nPlainLenMax;
-                                               m_vCharset.push_back(tCharset);
-                                               if(vCharsets.size() == m_vCharset.size())
-                                                       return true;
-                                               i = 0; // Start the lookup over again for the next charset
-                                       }                                               
-                               }
-                               else if (sCharsetName == sName)
-                               {
-                                       stCharset tCharset;
-                                       tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   
-                                       memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);
-                                       tCharset.m_sPlainCharsetName = sCharsetName;
-                                       tCharset.m_sPlainCharsetContent = sCharsetContent;                                                      
-                                       m_vCharset.push_back(tCharset);
-                                       return true;
-                               }
-                       }
-               }
-               printf("charset %s not found in charset.txt\n", sName.c_str());
-       }
-       else
-               printf("can't open charset configuration file\n");
-       return false;
-}
-
-//////////////////////////////////////////////////////////////////////
-
-bool CChainWalkContext::SetHashRoutine(string sHashRoutineName)
-{
-       CHashRoutine hr;
-       hr.GetHashRoutine(sHashRoutineName, m_pHashRoutine, m_nHashLen);
-       if (m_pHashRoutine != NULL)
-       {
-               m_sHashRoutineName = sHashRoutineName;
-               return true;
-       }
-       else
-               return false;
-}
-
-bool CChainWalkContext::SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax)
-{
-       // m_PlainCharset, m_nPlainCharsetLen, m_sPlainCharsetName, m_sPlainCharsetContent
-       if (!LoadCharset(sCharsetName))
-               return false;
-
-       if(m_vCharset.size() == 1) // Not hybrid charset
-       {
-               // m_nPlainLenMin, m_nPlainLenMax
-               if (nPlainLenMin < 1 || nPlainLenMax > MAX_PLAIN_LEN || nPlainLenMin > nPlainLenMax)
-               {
-                       printf("invalid plaintext length range: %d - %d\n", nPlainLenMin, nPlainLenMax);
-                       return false;
-               }
-               m_vCharset[0].m_nPlainLenMin = nPlainLenMin;
-               m_vCharset[0].m_nPlainLenMax = nPlainLenMax;
-       }
-       // m_nPlainSpaceUpToX
-       m_nPlainSpaceUpToX[0] = 0;
-       m_nPlainLenMaxTotal = 0;
-       m_nPlainLenMinTotal = 0;
-       uint64 nTemp = 1;
-       UINT4 j, k = 1;
-       for(j = 0; j < m_vCharset.size(); j++)
-       {
-               int i;
-               m_nPlainLenMaxTotal += m_vCharset[j].m_nPlainLenMax;
-               m_nPlainLenMinTotal += m_vCharset[j].m_nPlainLenMin;
-               for (i = 1; i <= m_vCharset[j].m_nPlainLenMax; i++)
-               {                       
-                       nTemp *= m_vCharset[j].m_nPlainCharsetLen;
-                       if (i < m_vCharset[j].m_nPlainLenMin)
-                               m_nPlainSpaceUpToX[k] = 0;
-                       else
-                               m_nPlainSpaceUpToX[k] = m_nPlainSpaceUpToX[k - 1] + nTemp;
-                       k++;
-               }               
-       }
-       // m_nPlainSpaceTotal
-       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];
-
-       return true;
-}
-
-bool CChainWalkContext::SetRainbowTableIndex(int nRainbowTableIndex)
-{
-       if (nRainbowTableIndex < 0)
-               return false;
-       m_nRainbowTableIndex = nRainbowTableIndex;
-       m_nReduceOffset = 65536 * nRainbowTableIndex;
-
-       return true;
-}
-
-bool CChainWalkContext::SetSalt(unsigned char *Salt, int nSaltLength)
-{
-       memcpy(&m_Salt[0], Salt, nSaltLength);
-       
-       m_nSaltLen = nSaltLength;
-//     m_sSalt = sSalt;
-       return true;
-}
-
-bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount)
-{
-       // something like lm_alpha#1-7_0_100x16_test.rt
-
-#ifdef _WIN32
-       string::size_type nIndex = sPathName.find_last_of('\\');
-#else
-       string::size_type nIndex = sPathName.find_last_of('/');
-#endif
-       if (nIndex != string::npos)
-               sPathName = sPathName.substr(nIndex + 1);
-
-       if (sPathName.size() < 3)
-       {
-               printf("%s is not a rainbow table\n", sPathName.c_str());
-               return false;
-       }
-       if (sPathName.substr(sPathName.size() - 5) == ".rti2")
-       {
-               isRti2RtFormat = true;
-       }
-       else if (sPathName.substr(sPathName.size() - 4) == ".rti")
-       {
-               isOldRtFormat = false;
-       }
-       else if (sPathName.substr(sPathName.size() - 3) == ".rt")
-       {
-               isOldRtFormat = true;
-       }
-       else
-       {
-               printf("%s is not a rainbow table\n", sPathName.c_str());
-               return false;
-       }
-
-       // Parse
-       vector<string> vPart;
-       if (!SeperateString(sPathName, "___x_", vPart))
-       {
-               printf("filename %s not identified\n", sPathName.c_str());
-               return false;
-       }
-
-       string sHashRoutineName   = vPart[0];
-       int nRainbowTableIndex    = atoi(vPart[2].c_str());
-       nRainbowChainLen          = atoi(vPart[3].c_str());
-       nRainbowChainCount        = atoi(vPart[4].c_str());
-
-       // Parse charset definition
-       string sCharsetDefinition = vPart[1];
-       string sCharsetName;
-       int nPlainLenMin = 0, nPlainLenMax = 0;         
-
-//     printf("Charset: %s", sCharsetDefinition.c_str());
-       
-       if(sCharsetDefinition.substr(0, 6) == "hybrid") // Hybrid table
-       {
-               sCharsetName = sCharsetDefinition;
-       }
-       else
-       {
-               if ( sCharsetDefinition.find('#') == string::npos )             // For backward compatibility, "#1-7" is implied
-               {                       
-                       sCharsetName = sCharsetDefinition;
-                       nPlainLenMin = 1;
-                       nPlainLenMax = 7;
-               }
-               else
-               {
-                       vector<string> vCharsetDefinitionPart;
-                       if (!SeperateString(sCharsetDefinition, "#-", vCharsetDefinitionPart))
-                       {
-                               printf("filename %s not identified\n", sPathName.c_str());
-                               return false;   
-                       }
-                       else
-                       {
-                               sCharsetName = vCharsetDefinitionPart[0];
-                               nPlainLenMin = atoi(vCharsetDefinitionPart[1].c_str());
-                               nPlainLenMax = atoi(vCharsetDefinitionPart[2].c_str());
-                       }
-               }
-       }
-       // Setup
-       if (!SetHashRoutine(sHashRoutineName))
-       {
-               printf("hash routine %s not supported\n", sHashRoutineName.c_str());
-               return false;
-       }
-       if (!SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))
-               return false;
-       if (!SetRainbowTableIndex(nRainbowTableIndex))
-       {
-               printf("invalid rainbow table index %d\n", nRainbowTableIndex);
-               return false;
-       }
-       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];
-       return true;
-}
-
-string CChainWalkContext::GetHashRoutineName()
-{
-       return m_sHashRoutineName;
-}
-
-int CChainWalkContext::GetHashLen()
-{
-       return m_nHashLen;
-}
-
-string CChainWalkContext::GetPlainCharsetName()
-{
-       return m_vCharset[0].m_sPlainCharsetName;
-}
-
-string CChainWalkContext::GetPlainCharsetContent()
-{
-       return m_vCharset[0].m_sPlainCharsetContent;
-}
-
-int CChainWalkContext::GetPlainLenMin()
-{
-       return m_vCharset[0].m_nPlainLenMin;
-}
-
-int CChainWalkContext::GetPlainLenMax()
-{
-       return m_vCharset[0].m_nPlainLenMax;
-}
-
-uint64 CChainWalkContext::GetPlainSpaceTotal()
-{
-       return m_nPlainSpaceTotal;
-}
-
-int CChainWalkContext::GetRainbowTableIndex()
-{
-       return m_nRainbowTableIndex;
-}
-
-void CChainWalkContext::Dump()
-{
-       printf("hash routine: %s\n", m_sHashRoutineName.c_str());
-       printf("hash length: %d\n", m_nHashLen);
-
-       printf("plain charset: ");
-       unsigned int i;
-       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)
-       {
-               if (isprint(m_vCharset[0].m_PlainCharset[i]))
-                       printf("%c", m_vCharset[0].m_PlainCharset[i]);
-               else
-                       printf("?");
-       }
-       printf("\n");
-
-       printf("plain charset in hex: ");
-       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)
-               printf("%02x ", m_vCharset[0].m_PlainCharset[i]);
-       printf("\n");
-
-       printf("plain length range: %d - %d\n", m_vCharset[0].m_nPlainLenMin, m_vCharset[0].m_nPlainLenMax);
-       printf("plain charset name: %s\n", m_vCharset[0].m_sPlainCharsetName.c_str());
-       //printf("plain charset content: %s\n", m_sPlainCharsetContent.c_str());
-       //for (i = 0; i <= m_nPlainLenMax; i++)
-       //      printf("plain space up to %d: %s\n", i, uint64tostr(m_nPlainSpaceUpToX[i]).c_str());
-       printf("plain space total: %s\n", uint64tostr(m_nPlainSpaceTotal).c_str());
-
-       printf("rainbow table index: %d\n", m_nRainbowTableIndex);
-       printf("reduce offset: %s\n", uint64tostr(m_nReduceOffset).c_str());
-       printf("\n");
-}
-
-void CChainWalkContext::SetIndex(uint64 nIndex)
-{
-       m_nIndex = nIndex;
-}
-
-void CChainWalkContext::SetHash(unsigned char* pHash)
-{
-       memcpy(m_Hash, pHash, m_nHashLen);
-}
-
-void CChainWalkContext::IndexToPlain()
-{
-       int i;
-       m_nPlainLen = 0;
-///*
-       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1; i--)
-       {
-               if (m_nIndex >= m_nPlainSpaceUpToX[i])
-               {
-                       m_nPlainLen = i + 1;
-                       break;
-               }
-       }
-
-       // this is an optimized version of the above
-/*
-       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1
-               && m_nIndex < m_nPlainSpaceUpToX[i]; i--)
-       { }
-       
-       m_nPlainLen = i + 1;
-*/
-
-       if(m_nPlainLen == 0)
-               m_nPlainLen = m_nPlainLenMinTotal;
-       uint64 nIndexOfX = m_nIndex - m_nPlainSpaceUpToX[m_nPlainLen - 1];
-
-// this is the generic code for non x86/x86_64 platforms
-#if !defined(_M_X64) && !defined(_M_IX86) && !defined(__i386__) && !defined(__x86_64__)
-       
-       // generic version (slow for non 64-bit platforms and gcc < 4.5.x)
-       for (i = m_nPlainLen - 1; i >= 0; i--)
-       {
-               int nCharsetLen = 0;
-               for(UINT4 j = 0; j < m_vCharset.size(); j++)
-               {
-                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;
-                       if(i < nCharsetLen) // We found the correct charset
-                       {
-                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];
-                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;
-                               break;
-                       }
-               }
-       }
-
-#elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)
-
-       // Fast ia32 version
-       for (i = m_nPlainLen - 1; i >= 0; i--)
-       {
-               // 0x100000000 = 2^32
-#ifdef _M_IX86
-               if (nIndexOfX < 0x100000000I64)
-                       break;
-#else
-               if (nIndexOfX < 0x100000000llu)
-                       break;
-#endif
-
-               int nCharsetLen = 0;
-               for(UINT4 j = 0; j < m_vCharset.size(); j++)
-               {
-                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;
-                       if(i < nCharsetLen) // We found the correct charset
-                       {
-                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];
-                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;
-                               break;
-                       }
-               }
-       }
-
-       UINT4 nIndexOfX32 = (UINT4)nIndexOfX;
-       for (; i >= 0; i--)
-       {
-               int nCharsetLen = 0;
-               for(UINT4 j = 0; j < m_vCharset.size(); j++)
-               {
-                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;
-                       if(i < nCharsetLen) // We found the correct charset
-                       {
-
-//             m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX32 % m_vCharset[j].m_nPlainCharsetLen];
-//             nIndexOfX32 /= m_vCharset[j].m_nPlainCharsetLen;
-
-
-//     moving nPlainCharsetLen into the asm body and avoiding the extra temp
-//     variable results in a performance gain
-//                             unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;
-                               unsigned int nTemp;
-
-#if defined(_WIN32) && !defined(__GNUC__)
-
-               // VC++ still needs this
-               unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;
-
-               __asm
-               {
-                       mov eax, nIndexOfX32
-                       xor edx, edx
-                       div nPlainCharsetLen
-                       mov nIndexOfX32, eax
-                       mov nTemp, edx
-               }
-               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];
-#else
-               __asm__ __volatile__ (  "mov %2, %%eax;"
-                                                               "xor %%edx, %%edx;"
-                                                               "divl %3;"
-                                                               "mov %%eax, %0;"
-                                                               "mov %%edx, %1;"
-                                                               : "=m"(nIndexOfX32), "=m"(nTemp)
-                                                               : "m"(nIndexOfX32), "m"(m_vCharset[j].m_nPlainCharsetLen)
-                                                               : "%eax", "%edx"
-                                                        );
-               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];
-#endif
-               break;
-                       }
-               }
-       }
-#endif
-}
-
-void CChainWalkContext::PlainToHash()
-{      
-       m_pHashRoutine(m_Plain, m_nPlainLen, m_Hash);
-}
-
-void CChainWalkContext::HashToIndex(int nPos)
-{
-       m_nIndex = (*(uint64*)m_Hash + m_nReduceOffset + nPos) % m_nPlainSpaceTotal;
-}
-
-uint64 CChainWalkContext::GetIndex()
-{
-       return m_nIndex;
-}
-const uint64 *CChainWalkContext::GetIndexPtr()
-{
-       return &m_nIndex;
-}
-
-string CChainWalkContext::GetPlain()
-{
-       string sRet;
-       int i;
-       for (i = 0; i < m_nPlainLen; i++)
-       {
-               char c = m_Plain[i];
-               sRet += c;
-       }
-       
-       return sRet;
-}
-
-string CChainWalkContext::GetBinary()
-{
-       return HexToStr(m_Plain, m_nPlainLen);
-}
-
-string CChainWalkContext::GetHash()
-{
-       return HexToStr(m_Hash, m_nHashLen);
-}
-
-bool CChainWalkContext::CheckHash(unsigned char* pHash)
-{
-       if (memcmp(m_Hash, pHash, m_nHashLen) == 0)
-               return true;
-
-       return false;
-}
-
-bool CChainWalkContext::isOldFormat()
-{
-       return isOldRtFormat;
-}
-
-bool CChainWalkContext::isRti2Format()
-{
-       return isRti2RtFormat;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ * Copyright 2010 Yngve AAdlandsvik\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "ChainWalkContext.h"\r
+\r
+#include <ctype.h>\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+string CChainWalkContext::m_sHashRoutineName;\r
+HASHROUTINE CChainWalkContext::m_pHashRoutine;\r
+int CChainWalkContext::m_nHashLen;\r
+int CChainWalkContext::m_nPlainLenMinTotal = 0;\r
+int CChainWalkContext::m_nPlainLenMaxTotal = 0;\r
+int CChainWalkContext::m_nHybridCharset = 0;\r
+bool CChainWalkContext::isOldRtFormat = false;\r
+bool CChainWalkContext::isRti2RtFormat = false;\r
+vector<stCharset> CChainWalkContext::m_vCharset;\r
+uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];\r
+uint64 CChainWalkContext::m_nPlainSpaceTotal;\r
+unsigned char CChainWalkContext::m_Salt[MAX_SALT_LEN];\r
+int CChainWalkContext::m_nSaltLen = 0;\r
+int CChainWalkContext::m_nRainbowTableIndex;\r
+uint64 CChainWalkContext::m_nReduceOffset;\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CChainWalkContext::CChainWalkContext()\r
+{\r
+}\r
+\r
+CChainWalkContext::~CChainWalkContext()\r
+{\r
+}\r
+\r
+bool CChainWalkContext::LoadCharset(string sName)\r
+{\r
+       m_vCharset.clear();\r
+       if (sName == "byte")\r
+       {\r
+               stCharset tCharset;\r
+               int i;\r
+               for (i = 0x00; i <= 0xff; i++)\r
+                       tCharset.m_PlainCharset[i] = (unsigned char) i;\r
+               tCharset.m_nPlainCharsetLen = 256;\r
+               tCharset.m_sPlainCharsetName = sName;\r
+               tCharset.m_sPlainCharsetContent = "0x00, 0x01, ... 0xff";\r
+               m_vCharset.push_back(tCharset);\r
+               return true;\r
+       }\r
+       if(sName.substr(0, 6) == "hybrid") // Hybrid charset consisting of 2 charsets\r
+               m_nHybridCharset = 1;           \r
+       else\r
+               m_nHybridCharset = 0;\r
+       \r
+       bool readCharset = false;\r
+       vector<string> vLine;\r
+\r
+       #ifdef BOINC\r
+               if ( boinc_ReadLinesFromFile( "charset.txt", vLine ) )\r
+                       readCharset = true;\r
+       #else\r
+               if ( ReadLinesFromFile("charset.txt", vLine) )\r
+                       readCharset = true;\r
+               else if ( ReadLinesFromFile(GetApplicationPath() + "charset.txt", vLine) )\r
+                       readCharset = true;\r
+       #endif\r
+\r
+       if ( readCharset )\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vLine.size(); i++)\r
+               {\r
+                       // Filter comment\r
+                       if (vLine[i][0] == '#')\r
+                               continue;\r
+\r
+                       vector<string> vPart;\r
+                       if (SeperateString(vLine[i], "=", vPart))\r
+                       {\r
+                               // sCharsetName\r
+                               string sCharsetName = TrimString(vPart[0]);\r
+                               if (sCharsetName == "")\r
+                                       continue;\r
+                                                               \r
+                               // sCharsetName charset check\r
+                               bool fCharsetNameCheckPass = true;\r
+                               uint32 j;\r
+                               for (j = 0; j < sCharsetName.size(); j++)\r
+                               {\r
+                                       if (   !isalpha(sCharsetName[j])\r
+                                               && !isdigit(sCharsetName[j])\r
+                                               && (sCharsetName[j] != '-'))\r
+                                       {\r
+                                               fCharsetNameCheckPass = false;\r
+                                               break;\r
+                                       }\r
+                               }\r
+                               if (!fCharsetNameCheckPass)\r
+                               {\r
+                                       printf("invalid charset name %s in charset configuration file\n", sCharsetName.c_str());\r
+                                       continue;\r
+                               }\r
+\r
+                               // sCharsetContent\r
+                               string sCharsetContent = TrimString(vPart[1]);\r
+                               if (sCharsetContent == "" || sCharsetContent == "[]")\r
+                                       continue;\r
+                               if (sCharsetContent[0] != '[' || sCharsetContent[sCharsetContent.size() - 1] != ']')\r
+                               {\r
+                                       printf("invalid charset content %s in charset configuration file\n", sCharsetContent.c_str());\r
+                                       continue;\r
+                               }\r
+                               sCharsetContent = sCharsetContent.substr(1, sCharsetContent.size() - 2);\r
+                               if (sCharsetContent.size() > 256)\r
+                               {\r
+                                       printf("charset content %s too long\n", sCharsetContent.c_str());\r
+                                       continue;\r
+                               }\r
+\r
+                               //printf("%s = [%s]\n", sCharsetName.c_str(), sCharsetContent.c_str());\r
+\r
+                               // Is it the wanted charset?\r
+                               if(m_nHybridCharset == 1)\r
+                               {\r
+                                       vector<tCharset> vCharsets;\r
+                                       GetHybridCharsets(sName, vCharsets);\r
+                                       if(sCharsetName == vCharsets[m_vCharset.size()].sName)\r
+                                       {\r
+                                               stCharset tCharset;\r
+                                               tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   \r
+                                               memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);\r
+                                               tCharset.m_sPlainCharsetName = sCharsetName;\r
+                                               tCharset.m_sPlainCharsetContent = sCharsetContent;      \r
+                                               tCharset.m_nPlainLenMin = vCharsets[m_vCharset.size()].nPlainLenMin;\r
+                                               tCharset.m_nPlainLenMax = vCharsets[m_vCharset.size()].nPlainLenMax;\r
+                                               m_vCharset.push_back(tCharset);\r
+                                               if(vCharsets.size() == m_vCharset.size())\r
+                                                       return true;\r
+                                               i = 0; // Start the lookup over again for the next charset\r
+                                       }                                               \r
+                               }\r
+                               else if (sCharsetName == sName)\r
+                               {\r
+                                       stCharset tCharset;\r
+                                       tCharset.m_nPlainCharsetLen = sCharsetContent.size();                                                   \r
+                                       memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen);\r
+                                       tCharset.m_sPlainCharsetName = sCharsetName;\r
+                                       tCharset.m_sPlainCharsetContent = sCharsetContent;                                                      \r
+                                       m_vCharset.push_back(tCharset);\r
+                                       return true;\r
+                               }\r
+                       }\r
+               }\r
+               printf("charset %s not found in charset.txt\n", sName.c_str());\r
+       }\r
+       else\r
+               printf("can't open charset configuration file\n");\r
+\r
+       return false;\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+bool CChainWalkContext::SetHashRoutine(string sHashRoutineName)\r
+{\r
+       CHashRoutine hr;\r
+       hr.GetHashRoutine(sHashRoutineName, m_pHashRoutine, m_nHashLen);\r
+       if (m_pHashRoutine != NULL)\r
+       {\r
+               m_sHashRoutineName = sHashRoutineName;\r
+               return true;\r
+       }\r
+       else\r
+               return false;\r
+}\r
+\r
+bool CChainWalkContext::SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax)\r
+{\r
+       // m_PlainCharset, m_nPlainCharsetLen, m_sPlainCharsetName, m_sPlainCharsetContent\r
+       if (!LoadCharset(sCharsetName))\r
+               return false;\r
+\r
+       if(m_vCharset.size() == 1) // Not hybrid charset\r
+       {\r
+               // m_nPlainLenMin, m_nPlainLenMax\r
+               if (nPlainLenMin < 1 || nPlainLenMax > MAX_PLAIN_LEN || nPlainLenMin > nPlainLenMax)\r
+               {\r
+                       printf("invalid plaintext length range: %d - %d\n", nPlainLenMin, nPlainLenMax);\r
+                       return false;\r
+               }\r
+               m_vCharset[0].m_nPlainLenMin = nPlainLenMin;\r
+               m_vCharset[0].m_nPlainLenMax = nPlainLenMax;\r
+       }\r
+       // m_nPlainSpaceUpToX\r
+       m_nPlainSpaceUpToX[0] = 0;\r
+       m_nPlainLenMaxTotal = 0;\r
+       m_nPlainLenMinTotal = 0;\r
+       uint64 nTemp = 1;\r
+       uint32 j, k = 1;\r
+       for(j = 0; j < m_vCharset.size(); j++)\r
+       {\r
+               int i;\r
+               m_nPlainLenMaxTotal += m_vCharset[j].m_nPlainLenMax;\r
+               m_nPlainLenMinTotal += m_vCharset[j].m_nPlainLenMin;\r
+               for (i = 1; i <= m_vCharset[j].m_nPlainLenMax; i++)\r
+               {                       \r
+                       nTemp *= m_vCharset[j].m_nPlainCharsetLen;\r
+                       if (i < m_vCharset[j].m_nPlainLenMin)\r
+                               m_nPlainSpaceUpToX[k] = 0;\r
+                       else\r
+                               m_nPlainSpaceUpToX[k] = m_nPlainSpaceUpToX[k - 1] + nTemp;\r
+                       k++;\r
+               }               \r
+       }\r
+       // m_nPlainSpaceTotal\r
+       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];\r
+\r
+       return true;\r
+}\r
+\r
+bool CChainWalkContext::SetRainbowTableIndex(int nRainbowTableIndex)\r
+{\r
+       if (nRainbowTableIndex < 0)\r
+               return false;\r
+       m_nRainbowTableIndex = nRainbowTableIndex;\r
+       m_nReduceOffset = 65536 * nRainbowTableIndex;\r
+\r
+       return true;\r
+}\r
+\r
+bool CChainWalkContext::SetSalt(unsigned char *Salt, int nSaltLength)\r
+{\r
+       memcpy(&m_Salt[0], Salt, nSaltLength);\r
+       \r
+       m_nSaltLen = nSaltLength;\r
+//     m_sSalt = sSalt;\r
+       return true;\r
+}\r
+\r
+bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount)\r
+{\r
+       // something like lm_alpha#1-7_0_100x16_test.rt\r
+\r
+#ifdef _WIN32\r
+       string::size_type nIndex = sPathName.find_last_of('\\');\r
+#else\r
+       string::size_type nIndex = sPathName.find_last_of('/');\r
+#endif\r
+       if (nIndex != string::npos)\r
+               sPathName = sPathName.substr(nIndex + 1);\r
+\r
+       if (sPathName.size() < 3)\r
+       {\r
+               printf("%s is not a rainbow table\n", sPathName.c_str());\r
+               return false;\r
+       }\r
+       if (sPathName.substr(sPathName.size() - 5) == ".rti2")\r
+       {\r
+               isRti2RtFormat = true;\r
+       }\r
+       else if (sPathName.substr(sPathName.size() - 4) == ".rti")\r
+       {\r
+               isOldRtFormat = false;\r
+       }\r
+       else if (sPathName.substr(sPathName.size() - 3) == ".rt")\r
+       {\r
+               isOldRtFormat = true;\r
+       }\r
+       else\r
+       {\r
+               printf("%s is not a rainbow table\n", sPathName.c_str());\r
+               return false;\r
+       }\r
+\r
+       // Parse\r
+       vector<string> vPart;\r
+       if (!SeperateString(sPathName, "___x_", vPart))\r
+       {\r
+               printf("filename %s not identified\n", sPathName.c_str());\r
+               return false;\r
+       }\r
+\r
+       string sHashRoutineName   = vPart[0];\r
+       int nRainbowTableIndex    = atoi(vPart[2].c_str());\r
+       nRainbowChainLen          = atoi(vPart[3].c_str());\r
+       nRainbowChainCount        = atoi(vPart[4].c_str());\r
+\r
+       // Parse charset definition\r
+       string sCharsetDefinition = vPart[1];\r
+       string sCharsetName;\r
+       int nPlainLenMin = 0, nPlainLenMax = 0;         \r
+\r
+//     printf("Charset: %s", sCharsetDefinition.c_str());\r
+       \r
+       if(sCharsetDefinition.substr(0, 6) == "hybrid") // Hybrid table\r
+       {\r
+               sCharsetName = sCharsetDefinition;\r
+       }\r
+       else\r
+       {\r
+               if ( sCharsetDefinition.find('#') == string::npos )             // For backward compatibility, "#1-7" is implied\r
+               {                       \r
+                       sCharsetName = sCharsetDefinition;\r
+                       nPlainLenMin = 1;\r
+                       nPlainLenMax = 7;\r
+               }\r
+               else\r
+               {\r
+                       vector<string> vCharsetDefinitionPart;\r
+                       if (!SeperateString(sCharsetDefinition, "#-", vCharsetDefinitionPart))\r
+                       {\r
+                               printf("filename %s not identified\n", sPathName.c_str());\r
+                               return false;   \r
+                       }\r
+                       else\r
+                       {\r
+                               sCharsetName = vCharsetDefinitionPart[0];\r
+                               nPlainLenMin = atoi(vCharsetDefinitionPart[1].c_str());\r
+                               nPlainLenMax = atoi(vCharsetDefinitionPart[2].c_str());\r
+                       }\r
+               }\r
+       }\r
+       // Setup\r
+       if (!SetHashRoutine(sHashRoutineName))\r
+       {\r
+               printf("hash routine %s not supported\n", sHashRoutineName.c_str());\r
+               return false;\r
+       }\r
+       if (!SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax))\r
+               return false;\r
+       if (!SetRainbowTableIndex(nRainbowTableIndex))\r
+       {\r
+               printf("invalid rainbow table index %d\n", nRainbowTableIndex);\r
+               return false;\r
+       }\r
+       m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal];\r
+       return true;\r
+}\r
+\r
+string CChainWalkContext::GetHashRoutineName()\r
+{\r
+       return m_sHashRoutineName;\r
+}\r
+\r
+int CChainWalkContext::GetHashLen()\r
+{\r
+       return m_nHashLen;\r
+}\r
+\r
+string CChainWalkContext::GetPlainCharsetName()\r
+{\r
+       return m_vCharset[0].m_sPlainCharsetName;\r
+}\r
+\r
+string CChainWalkContext::GetPlainCharsetContent()\r
+{\r
+       return m_vCharset[0].m_sPlainCharsetContent;\r
+}\r
+\r
+int CChainWalkContext::GetPlainLenMin()\r
+{\r
+       return m_vCharset[0].m_nPlainLenMin;\r
+}\r
+\r
+int CChainWalkContext::GetPlainLenMax()\r
+{\r
+       return m_vCharset[0].m_nPlainLenMax;\r
+}\r
+\r
+uint64 CChainWalkContext::GetPlainSpaceTotal()\r
+{\r
+       return m_nPlainSpaceTotal;\r
+}\r
+\r
+int CChainWalkContext::GetRainbowTableIndex()\r
+{\r
+       return m_nRainbowTableIndex;\r
+}\r
+\r
+void CChainWalkContext::Dump()\r
+{\r
+       printf("hash routine: %s\n", m_sHashRoutineName.c_str());\r
+       printf("hash length: %d\n", m_nHashLen);\r
+\r
+       printf("plain charset: ");\r
+       unsigned int i;\r
+       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)\r
+       {\r
+               if (isprint(m_vCharset[0].m_PlainCharset[i]))\r
+                       printf("%c", m_vCharset[0].m_PlainCharset[i]);\r
+               else\r
+                       printf("?");\r
+       }\r
+       printf("\n");\r
+\r
+       printf("plain charset in hex: ");\r
+       for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++)\r
+               printf("%02x ", m_vCharset[0].m_PlainCharset[i]);\r
+       printf("\n");\r
+\r
+       printf("plain length range: %d - %d\n", m_vCharset[0].m_nPlainLenMin, m_vCharset[0].m_nPlainLenMax);\r
+       printf("plain charset name: %s\n", m_vCharset[0].m_sPlainCharsetName.c_str());\r
+       //printf("plain charset content: %s\n", m_sPlainCharsetContent.c_str());\r
+       //for (i = 0; i <= m_nPlainLenMax; i++)\r
+       //      printf("plain space up to %d: %s\n", i, uint64tostr(m_nPlainSpaceUpToX[i]).c_str());\r
+       printf("plain space total: %s\n", uint64tostr(m_nPlainSpaceTotal).c_str());\r
+\r
+       printf("rainbow table index: %d\n", m_nRainbowTableIndex);\r
+       printf("reduce offset: %s\n", uint64tostr(m_nReduceOffset).c_str());\r
+       printf("\n");\r
+}\r
+\r
+void CChainWalkContext::SetIndex(uint64 nIndex)\r
+{\r
+       m_nIndex = nIndex;\r
+}\r
+\r
+void CChainWalkContext::SetHash(unsigned char* pHash)\r
+{\r
+       memcpy(m_Hash, pHash, m_nHashLen);\r
+}\r
+\r
+void CChainWalkContext::IndexToPlain()\r
+{\r
+       int i;\r
+       m_nPlainLen = 0;\r
+///*\r
+       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1; i--)\r
+       {\r
+               if (m_nIndex >= m_nPlainSpaceUpToX[i])\r
+               {\r
+                       m_nPlainLen = i + 1;\r
+                       break;\r
+               }\r
+       }\r
+\r
+       // this is an optimized version of the above\r
+/*\r
+       for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1\r
+               && m_nIndex < m_nPlainSpaceUpToX[i]; i--)\r
+       { }\r
+       \r
+       m_nPlainLen = i + 1;\r
+*/\r
+\r
+       if(m_nPlainLen == 0)\r
+               m_nPlainLen = m_nPlainLenMinTotal;\r
+       uint64 nIndexOfX = m_nIndex - m_nPlainSpaceUpToX[m_nPlainLen - 1];\r
+\r
+// this is the generic code for non x86/x86_64 platforms\r
+#if !defined(_M_X64) && !defined(_M_IX86) && !defined(__i386__) && !defined(__x86_64__)\r
+       \r
+       // generic version (slow for non 64-bit platforms and gcc < 4.5.x)\r
+       for (i = m_nPlainLen - 1; i >= 0; i--)\r
+       {\r
+               int nCharsetLen = 0;\r
+               for(uint32 j = 0; j < m_vCharset.size(); j++)\r
+               {\r
+                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
+                       if(i < nCharsetLen) // We found the correct charset\r
+                       {\r
+                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];\r
+                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+#elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)\r
+\r
+       // Fast ia32 version\r
+       for (i = m_nPlainLen - 1; i >= 0; i--)\r
+       {\r
+               // 0x100000000 = 2^32\r
+#ifdef _M_IX86\r
+               if (nIndexOfX < 0x100000000I64)\r
+                       break;\r
+#else\r
+               if (nIndexOfX < 0x100000000llu)\r
+                       break;\r
+#endif\r
+\r
+               int nCharsetLen = 0;\r
+               for(uint32 j = 0; j < m_vCharset.size(); j++)\r
+               {\r
+                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
+                       if(i < nCharsetLen) // We found the correct charset\r
+                       {\r
+                               m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen];\r
+                               nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen;\r
+                               break;\r
+                       }\r
+               }\r
+       }\r
+\r
+       uint32 nIndexOfX32 = (uint32)nIndexOfX;\r
+       for (; i >= 0; i--)\r
+       {\r
+               int nCharsetLen = 0;\r
+               for(uint32 j = 0; j < m_vCharset.size(); j++)\r
+               {\r
+                       nCharsetLen += m_vCharset[j].m_nPlainLenMax;\r
+                       if(i < nCharsetLen) // We found the correct charset\r
+                       {\r
+\r
+//             m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX32 % m_vCharset[j].m_nPlainCharsetLen];\r
+//             nIndexOfX32 /= m_vCharset[j].m_nPlainCharsetLen;\r
+\r
+//     moving nPlainCharsetLen into the asm body and avoiding the extra temp\r
+//     variable results in a performance gain\r
+//                             unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;\r
+                               unsigned int nTemp;\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+               // VC++ still needs this\r
+               unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen;\r
+\r
+               __asm\r
+               {\r
+                       mov eax, nIndexOfX32\r
+                       xor edx, edx\r
+                       div nPlainCharsetLen\r
+                       mov nIndexOfX32, eax\r
+                       mov nTemp, edx\r
+               }\r
+               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];\r
+#else\r
+               __asm__ __volatile__ (  "mov %2, %%eax;"\r
+                                                               "xor %%edx, %%edx;"\r
+                                                               "divl %3;"\r
+                                                               "mov %%eax, %0;"\r
+                                                               "mov %%edx, %1;"\r
+                                                               : "=m"(nIndexOfX32), "=m"(nTemp)\r
+                                                               : "m"(nIndexOfX32), "m"(m_vCharset[j].m_nPlainCharsetLen)\r
+                                                               : "%eax", "%edx"\r
+                                                        );\r
+               m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp];\r
+#endif\r
+               break;\r
+                       }\r
+               }\r
+       }\r
+#endif\r
+}\r
+\r
+void CChainWalkContext::PlainToHash()\r
+{      \r
+       m_pHashRoutine(m_Plain, m_nPlainLen, m_Hash);\r
+}\r
+\r
+void CChainWalkContext::HashToIndex(int nPos)\r
+{\r
+       m_nIndex = (*(uint64*)m_Hash + m_nReduceOffset + nPos) % m_nPlainSpaceTotal;\r
+}\r
+\r
+uint64 CChainWalkContext::GetIndex()\r
+{\r
+       return m_nIndex;\r
+}\r
+const uint64 *CChainWalkContext::GetIndexPtr()\r
+{\r
+       return &m_nIndex;\r
+}\r
+\r
+string CChainWalkContext::GetPlain()\r
+{\r
+       string sRet;\r
+       int i;\r
+       for (i = 0; i < m_nPlainLen; i++)\r
+       {\r
+               char c = m_Plain[i];\r
+               sRet += c;\r
+       }\r
+       \r
+       return sRet;\r
+}\r
+\r
+string CChainWalkContext::GetBinary()\r
+{\r
+       return HexToStr(m_Plain, m_nPlainLen);\r
+}\r
+\r
+string CChainWalkContext::GetHash()\r
+{\r
+       return HexToStr(m_Hash, m_nHashLen);\r
+}\r
+\r
+bool CChainWalkContext::CheckHash(unsigned char* pHash)\r
+{\r
+       if (memcmp(m_Hash, pHash, m_nHashLen) == 0)\r
+               return true;\r
+\r
+       return false;\r
+}\r
+\r
+bool CChainWalkContext::isOldFormat()\r
+{\r
+       return isOldRtFormat;\r
+}\r
+\r
+bool CChainWalkContext::isRti2Format()\r
+{\r
+       return isRti2RtFormat;\r
+}\r
index 3c8f27661ad8a15092b31ec7a63d81829445cb85..7262fffb437ad80979e08a1b78c61a0c3c92a82d 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _CHAINWALKCONTEXT_H
-#define _CHAINWALKCONTEXT_H
-
-#include "HashRoutine.h"
-#include "Public.h"
-
-typedef struct 
-{
-       unsigned char m_PlainCharset[255];
-       unsigned int m_nPlainCharsetLen;
-       int m_nPlainLenMin;
-       int m_nPlainLenMax;
-       string m_sPlainCharsetName;
-       string m_sPlainCharsetContent;
-} stCharset;
-class CChainWalkContext 
-{
-public:
-       CChainWalkContext();
-       virtual ~CChainWalkContext();
-
-private:
-       static string m_sHashRoutineName;       
-       static HASHROUTINE m_pHashRoutine;                                                      // Configuration
-       static int m_nHashLen;                                                                          // Configuration
-       static bool isOldRtFormat;
-       static bool isRti2RtFormat;
-       static vector<stCharset> m_vCharset;
-       static int m_nPlainLenMinTotal, m_nPlainLenMaxTotal;
-       static uint64 m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];            // Performance consideration
-       static uint64 m_nPlainSpaceTotal;                                                       // Performance consideration
-       static int m_nHybridCharset;
-       static int m_nRainbowTableIndex;                                                        // Configuration
-       static uint64 m_nReduceOffset;                                                          // Performance consideration
-
-       // Context
-       uint64 m_nIndex;
-       unsigned char m_Plain[MAX_PLAIN_LEN];
-       int m_nPlainLen;
-       unsigned char m_Hash[MAX_HASH_LEN];
-       static unsigned char m_Salt[MAX_SALT_LEN];
-       static int m_nSaltLen;
-private:
-       static bool LoadCharset(string sCharset);
-
-public:
-       static bool SetHashRoutine(string sHashRoutineName);                                                                                            // Configuration
-       static bool SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax);                           // Configuration
-       static bool SetRainbowTableIndex(int nRainbowTableIndex);       
-       static bool SetSalt(unsigned char *Salt, int nSaltLength);// Configuration
-       static bool SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount);        // Wrapper
-       static string GetHashRoutineName();
-       static int GetHashLen();
-       static string GetPlainCharsetName();
-       static string GetPlainCharsetContent();
-       static int GetPlainLenMin();
-       static int GetPlainLenMax();
-       static uint64 GetPlainSpaceTotal();
-       static int GetRainbowTableIndex();
-       static void Dump();
-       static bool isOldFormat();
-       static bool isRti2Format();
-
-
-       void SetIndex(uint64 nIndex);
-       void SetHash(unsigned char* pHash);             // The length should be m_nHashLen
-
-       void IndexToPlain();
-       void PlainToHash();
-       void HashToIndex(int nPos);
-
-       uint64 GetIndex();
-       const uint64* GetIndexPtr();
-       string GetPlain();
-       string GetBinary();
-       string GetHash();
-       bool CheckHash(unsigned char* pHash);   // The length should be m_nHashLen
-};
-
-#endif
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#ifndef _CHAINWALKCONTEXT_H\r
+#define _CHAINWALKCONTEXT_H\r
+\r
+#include "HashRoutine.h"\r
+#include "Public.h"\r
+\r
+typedef struct \r
+{\r
+       unsigned char m_PlainCharset[255];\r
+       unsigned int m_nPlainCharsetLen;\r
+       int m_nPlainLenMin;\r
+       int m_nPlainLenMax;\r
+       string m_sPlainCharsetName;\r
+       string m_sPlainCharsetContent;\r
+} stCharset;\r
+class CChainWalkContext \r
+{\r
+public:\r
+       CChainWalkContext();\r
+       virtual ~CChainWalkContext();\r
+\r
+private:\r
+       static string m_sHashRoutineName;       \r
+       static HASHROUTINE m_pHashRoutine;                                                      // Configuration\r
+       static int m_nHashLen;                                                                          // Configuration\r
+       static bool isOldRtFormat;\r
+       static bool isRti2RtFormat;\r
+       static vector<stCharset> m_vCharset;\r
+       static int m_nPlainLenMinTotal, m_nPlainLenMaxTotal;\r
+       static uint64 m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];            // Performance consideration\r
+       static uint64 m_nPlainSpaceTotal;                                                       // Performance consideration\r
+       static int m_nHybridCharset;\r
+       static int m_nRainbowTableIndex;                                                        // Configuration\r
+       static uint64 m_nReduceOffset;                                                          // Performance consideration\r
+\r
+       // Context\r
+       uint64 m_nIndex;\r
+       unsigned char m_Plain[MAX_PLAIN_LEN];\r
+       int m_nPlainLen;\r
+       unsigned char m_Hash[MAX_HASH_LEN];\r
+       static unsigned char m_Salt[MAX_SALT_LEN];\r
+       static int m_nSaltLen;\r
+private:\r
+       static bool LoadCharset(string sCharset);\r
+\r
+public:\r
+       static bool SetHashRoutine(string sHashRoutineName);                                                                                            // Configuration\r
+       static bool SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax);                           // Configuration\r
+       static bool SetRainbowTableIndex(int nRainbowTableIndex);       \r
+       static bool SetSalt(unsigned char *Salt, int nSaltLength);// Configuration\r
+       static bool SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount);        // Wrapper\r
+       static string GetHashRoutineName();\r
+       static int GetHashLen();\r
+       static string GetPlainCharsetName();\r
+       static string GetPlainCharsetContent();\r
+       static int GetPlainLenMin();\r
+       static int GetPlainLenMax();\r
+       static uint64 GetPlainSpaceTotal();\r
+       static int GetRainbowTableIndex();\r
+       static void Dump();\r
+       static bool isOldFormat();\r
+       static bool isRti2Format();\r
+\r
+       void SetIndex(uint64 nIndex);\r
+       void SetHash(unsigned char* pHash);             // The length should be m_nHashLen\r
+\r
+       void IndexToPlain();\r
+       void PlainToHash();\r
+       void HashToIndex(int nPos);\r
+\r
+       uint64 GetIndex();\r
+       const uint64* GetIndexPtr();\r
+       string GetPlain();\r
+       string GetBinary();\r
+       string GetHash();\r
+       bool CheckHash(unsigned char* pHash);   // The length should be m_nHashLen\r
+};\r
+\r
+#endif\r
index cab23a12dad70ba13c0c8b2d779e0615364d2c82..b80b4ab60a3e0eacac6ecb431e0e37f5af93c2a2 100644 (file)
@@ -67,7 +67,7 @@ string CChainWalkSet::CheckOrRotatePreCalcFile()
                sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);
                string sReturnPreCalcPath(sPreCalcFileName);
 
-               unsigned int fileLen = 0;
+               long fileLen = 0;
 
                FILE* file = fopen(sReturnPreCalcPath.c_str(), "ab");
                if(file!=NULL)
index 0a4b1818bb9eb889771e94017cc28fb0ee9302c2..0343588f38015dcead7af0a10818659b97a01cc4 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- * Copyright 2010 uroskn
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "CrackEngine.h"
-#include "RTI2Reader.h"
-
-#ifndef _WIN32
-       #include <sys/resource.h>
-#endif
-
-CCrackEngine::CCrackEngine()
-{
-       ResetStatistics();
-       writeOutput = false;
-       resumeSession = false;
-       debug = false;
-       keepPrecalcFiles = false;
-
-       sSessionPathName = "";
-       sProgressPathName = "";
-}
-
-CCrackEngine::~CCrackEngine()
-{
-}
-
-//////////////////////////////////////////////////////////////////////
-
-void CCrackEngine::ResetStatistics()
-{
-       m_fTotalDiskAccessTime               = 0.0f;
-       m_fTotalCryptanalysisTime            = 0.0f;
-       m_fTotalPrecalculationTime           = 0.0f;
-       m_nTotalChainWalkStep                = 0;
-       m_nTotalFalseAlarm                   = 0;
-       m_nTotalChainWalkStepDueToFalseAlarm = 0;
-//     m_nTotalFalseAlarmSkipped                        = 0;
-}
-
-int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)
-{
-       int nLow = 0;
-       int nHigh = nRainbowChainCount - 1;
-       while (nLow <= nHigh)
-       {
-               int nMid = (nLow + nHigh) / 2;
-               if (nIndex == pChain[nMid].nIndexE)
-                       return nMid;
-               else if (nIndex < pChain[nMid].nIndexE)
-                       nHigh = nMid - 1;
-               else
-                       nLow = nMid + 1;
-       }
-
-       return -1;
-}
-
-RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)
-{
-       uint64 nPrefix = nIndex >> 16;
-       int nLow, nHigh;        
-       bool found = false;
-       //int nChains = 0;
-       
-       if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file
-       {
-               return NULL;
-       }
-
-       int nBLow = 0;
-       int nBHigh = nIndexSize - 1;
-       while (nBLow <= nBHigh)
-       {
-               int nBMid = (nBLow + nBHigh) / 2;
-               if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
-               {
-                       //nLow = nChains;
-                       //int nChains = 0;
-
-                       nLow = pIndex[nBMid].nFirstChain;
-                       nHigh = nLow + pIndex[nBMid].nChainCount;
-                       if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead) 
-                       {                                       
-                               if(nHigh > nIndexStart + nChainCountRead)
-                                       nHigh = nIndexStart + nChainCountRead;
-                       }
-                       else if(nLow < nIndexStart && nHigh >= nIndexStart)
-                       {
-                               nLow = nIndexStart;
-                       }
-                       else break;                                     
-                       found = true;
-                       break;
-               }
-               else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))
-                       nBHigh = nBMid - 1;
-               else
-                       nBLow = nBMid + 1;
-       }
-       if(found == true)
-       {
-               for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)
-               {
-                       int nSIndex = ((int)nIndex) & 0x0000FFFF;
-
-                       if (nSIndex == pChain[i].nIndexE)
-                       {
-                               return &pChain[i];
-                       }                               
-                       else if(pChain[i].nIndexE > nSIndex)
-                               break;
-               }
-       }       
-       return NULL;
-}
-
-// not used currently, leaving code for future checkpoints
-//bool CCrackEngine::CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
-//{
-//     CChainWalkContext cwc;
-//     //uint64 nIndexS = pChain->nIndexS >> 16;
-//     uint64 nIndexS = pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
-//     cwc.SetIndex(nIndexS);
-//     int nPos;
-//     for (nPos = 0; nPos < nGuessedPos; nPos++)
-//     {
-//             cwc.IndexToPlain();
-//             cwc.PlainToHash();
-//             cwc.HashToIndex(nPos);
-//             // Not using checkpoints atm
-//             /*
-//             switch(nPos)
-//             {
-//             case 5000:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)
-//                             {
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 5000;
-////                                   printf("CheckPoint caught false alarm at position 7600\n");
-//                                     return false;
-//                             }
-//                             break;
-//             case 6000:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)
-//                             {
-////                                   printf("CheckPoint caught false alarm at position 8200\n");
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 6000;
-//                                     return false;
-//                             }
-//                             break;
-//
-//             case 7600:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)
-//                             {
-////                                   printf("CheckPoint caught false alarm at position 8700\n");
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 7600;
-//                                     return false;
-//                             }
-//                             break;
-//
-//             case 8200:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)
-//                             {
-////                                   printf("CheckPoint caught false alarm at position 9000\n");
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 8200;
-//                                     return false;
-//                             }
-//                             break;
-//
-//                     case 8700:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)
-//                             {
-////                                   printf("CheckPoint caught false alarm at position 9300\n");
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 8700;
-//                                     return false;
-//                             }
-//
-//                             break;
-//                     case 9000:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)
-//                             {
-////                                   printf("CheckPoint caught false alarm at position 9600\n");
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 9000;
-//                                     return false;
-//                             }
-//
-//                             break;
-//                     case 9300:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)
-//                             {
-////                                   printf("CheckPoint caught false alarm at position 9600\n");
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 9300;
-//                                     return false;
-//                             }
-//                             break;
-//                     case 9600:
-//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))
-//                             {
-////                                   printf("CheckPoint caught false alarm at position 9600\n");
-//                                     m_nTotalFalseAlarmSkipped += 10000 - 9600;
-//                                     return false;
-//                             }
-//                             break;
-//
-//             }*/
-//     }
-//     cwc.IndexToPlain();
-//     cwc.PlainToHash();
-//     if (cwc.CheckHash(pHash))
-//     {
-//             printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
-//             hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
-//             return true;
-//     }
-//
-//     return false;
-//}
-
-//bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)
-//{
-//     CChainWalkContext cwc;
-//     cwc.SetIndex(pChain->nIndexS);
-//     int nPos;
-//     for (nPos = 0; nPos < nGuessedPos; nPos++)
-//     {
-//             cwc.IndexToPlain();
-//             cwc.PlainToHash();
-//             cwc.HashToIndex(nPos);
-//     }
-//     cwc.IndexToPlain();
-//     cwc.PlainToHash();
-//     if (cwc.CheckHash(pHash))
-//     {
-//             printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());
-//             hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());
-//             return true;
-//     }
-//
-//     return false;
-//}
-
-void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,
-                                                                                                         int nRainbowChainCount,
-                                                                                                         int nMatchingIndexE,
-                                                                                                         int& nMatchingIndexEFrom,
-                                                                                                         int& nMatchingIndexETo)
-{
-       nMatchingIndexEFrom = nMatchingIndexE;
-       nMatchingIndexETo   = nMatchingIndexE;
-       while (nMatchingIndexEFrom > 0)
-       {
-               if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
-                       nMatchingIndexEFrom--;
-               else
-                       break;
-       }
-       while (nMatchingIndexETo < nRainbowChainCount - 1)
-       {
-               if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)
-                       nMatchingIndexETo++;
-               else
-                       break;
-       }
-}
-
-void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)
-{
-       vector<string> vHash;
-       hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
-       printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
-                                                                                  vHash.size() > 1 ? "es" : "");
-
-       int nChainWalkStep = 0;
-       int nFalseAlarm = 0;
-       int nChainWalkStepDueToFalseAlarm = 0;
-
-       vector<rcrackiThread*> threadPool;
-       vector<pthread_t> pThreads;
-
-       #ifndef _WIN32
-               /*
-                * On linux you cannot set the priority of a thread in the non real time
-                * scheduling groups.  You can set the priority of the process.  In
-                * windows BELOW_NORMAL represents a 1/8th drop in priority and this would
-                * be 20 * 1/8 on linux or about 2.5
-                */
-               setpriority( PRIO_PROCESS, 0, 2 );
-       #endif
-
-       pthread_attr_t attr;
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-       #ifdef _WIN32
-       sched_param param;
-       /*
-        * windows scheduling is 0 to 32 (low to high) with 8 as normal and 7 as
-        * BELOW_NORMAL
-        */
-       param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
-       pthread_attr_setschedparam (&attr, &param);
-       #endif
-
-       bool pausing = false;
-
-       UINT4 nHashIndex;
-       for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
-       {
-               #ifdef _WIN32
-               if (_kbhit())
-               {
-                       int ch = _getch();
-                       ch = toupper(ch);
-                       if (ch == 'P')
-                       {
-                               pausing = true;
-                               printf( "\nPausing, press P again to continue... ");
-
-                               timeval tv;
-                               timeval tv2;
-                               timeval final;
-                               gettimeofday( &tv, NULL );
-
-                               while (pausing)
-                               {
-                                       if (_kbhit())
-                                       {
-                                               ch = _getch();
-                                               ch = toupper(ch);
-                                               if (ch == 'P')
-                                               {
-                                                       printf( " [Continuing]\n");
-                                                       pausing = false;
-                                                       gettimeofday( &tv2, NULL );
-                                                       final = sub_timeofday( tv2, tv );
-                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                                       m_fTotalCryptanalysisTime -= fTime;
-                                               }
-                                       }
-                                       Sleep(500);
-                               }
-                       }
-                       else
-                       {
-                               printf( "\nPress 'P' to pause...\n");
-                       }
-               }
-               #else
-               int c = tty_getchar();
-               if (c >= 0) {
-                       tty_flush();
-                       if (c==112) { // = p
-                               pausing = true;
-                               printf( "\nPausing, press 'p' again to continue... ");
-                               
-                               timeval tv;
-                               timeval tv2;
-                               timeval final;
-                               gettimeofday( &tv, NULL );
-                               
-                               while (pausing)
-                               {
-                                       if ((c = tty_getchar()) >= 0)
-                                       {
-                                               tty_flush();
-                                               if (c == 112)
-                                               {
-                                                       printf( " [Continuing]\n");
-                                                       pausing = false;
-                                                       gettimeofday( &tv2, NULL );
-                                                       final = sub_timeofday( tv2, tv );
-                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                                       m_fTotalCryptanalysisTime -= fTime;
-                                               }
-                                       }
-                                       usleep(500*1000);
-                               }
-                       }
-                       else {
-                               printf( "\nPress 'p' to pause...\n");
-                       }
-               }
-               #endif
-               unsigned char TargetHash[MAX_HASH_LEN];
-               int nHashLen;
-               ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
-               if (nHashLen != CChainWalkContext::GetHashLen())
-                       printf("debug: nHashLen mismatch\n");
-
-               // Rqeuest ChainWalk
-               bool fNewlyGenerated;
-               uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
-                                                                                                       nHashLen,
-                                                                                                       CChainWalkContext::GetHashRoutineName(),
-                                                                                                       CChainWalkContext::GetPlainCharsetName(),
-                                                                                                       CChainWalkContext::GetPlainLenMin(),
-                                                                                                       CChainWalkContext::GetPlainLenMax(),
-                                                                                                       CChainWalkContext::GetRainbowTableIndex(),
-                                                                                                       nRainbowChainLen,
-                                                                                                       fNewlyGenerated,
-                                                                                                       debug,
-                                                                                                       sPrecalcPathName);
-               //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
-               //                                                                              vHash[nHashIndex].c_str());
-
-               // Walk
-               if (fNewlyGenerated)
-               {
-                       timeval tv;
-                       timeval tv2;
-                       timeval final;
-
-                       gettimeofday( &tv, NULL );
-
-                       printf("Pre-calculating hash %lu of %lu.%-20s\r",
-                               (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
-                       threadPool.clear();
-                       pThreads.clear();
-                       
-                       UINT4 thread_ID;
-                       for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
-                       {
-                               rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
-                               if (r_Thread)
-                               {
-                                       pthread_t pThread;
-                                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
-                                       if( returnValue != 0 )
-                                       {
-                                               printf("pThread creation failed, returnValue: %d\n", returnValue);
-                                       }
-                                       else
-                                       {
-                                               pThreads.push_back(pThread);
-                                       }
-
-                                       threadPool.push_back(r_Thread);
-                               }
-                               else 
-                               {
-                                       printf("r_Thread creation failed!\n");
-                               }
-                       }
-                       
-                       //printf("%d r_Threads created\t\t\n", threadPool.size());
-                       
-                       for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
-                       {
-                               pthread_t pThread = pThreads[thread_ID];
-                               int returnValue = pthread_join(pThread, NULL);
-                               if( returnValue != 0 )
-                               {
-                                       printf("pThread join failed, returnValue: %d\n", returnValue);
-                               }
-                                       
-                               rcrackiThread* rThread = threadPool[thread_ID];
-                               nChainWalkStep += rThread->GetChainWalkStep();
-                       }
-
-                       gettimeofday( &tv2, NULL );
-                       final = sub_timeofday( tv2, tv );
-                       
-                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-
-                       m_fTotalPrecalculationTime += fTime;
-                       m_fTotalCryptanalysisTime -= fTime;
-
-                       printf("%-50s\r", "");
-
-                       if ( debug )
-                               printf("pre-calculation time: %.2f s\n", fTime);
-               }
-
-               //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
-               printf("Checking false alarms for hash %lu of %lu.%-20s\r", 
-                       (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
-
-               threadPool.clear();
-               pThreads.clear();
-
-               int i;
-               for (i = 0; i < maxThreads; i++)
-               {
-                       rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);
-                       threadPool.push_back(r_Thread);
-               }
-
-               UINT4 thread_ID = 0;
-               int nPos;
-               for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
-               {
-                       uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
-               
-                       // Search matching nIndexE
-                       int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);
-                       if (nMatchingIndexE != -1)
-                       {
-                               int nMatchingIndexEFrom, nMatchingIndexETo;
-                               GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,
-                                                                                                  nMatchingIndexE,
-                                                                                                  nMatchingIndexEFrom, nMatchingIndexETo);
-                               int i;
-                               for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)
-                               {
-                                       rcrackiThread* rThread = threadPool[thread_ID];
-                                       rThread->AddAlarmCheckO(pChain + i, nPos);
-                                       if (thread_ID < (unsigned long)maxThreads - 1 ) {
-                                               thread_ID++;
-                                       } else {
-                                               thread_ID = 0;
-                                       }
-                               }
-                       }
-               }
-
-               for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
-               {
-                       rcrackiThread* r_Thread = threadPool[thread_ID];
-                       pthread_t pThread;
-
-                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
-                       if( returnValue != 0 )
-                       {
-                               printf("pThread creation failed, returnValue: %d\n", returnValue);
-                       }
-                       else
-                       {
-                               pThreads.push_back(pThread);
-                       }
-               }
-               
-               //printf("%d r_Threads created\t\t\n", threadPool.size());
-
-               bool foundHashInThread = false;
-               for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
-               {
-                       rcrackiThread* rThread = threadPool[thread_ID];
-                       pthread_t pThread = pThreads[thread_ID];
-
-                       int returnValue = pthread_join(pThread, NULL);
-                       if( returnValue != 0 )
-                       {
-                               printf("pThread join failed, returnValue: %d\n", returnValue);
-                       }
-
-                       nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
-                       nFalseAlarm += rThread->GetnFalseAlarm();
-
-                       if (rThread->FoundHash() && !foundHashInThread) {
-                               //printf("\t\t\t\t\t\t\r");
-                               printf("%-50s\r", "");
-
-                               printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
-                               if (writeOutput)
-                               {
-                                       if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
-                                               printf("Couldn't write this result to file!\n");
-                               }
-                               hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
-
-                               FILE* file = fopen(sSessionPathName.c_str(), "a");
-                               if (file!=NULL)
-                               {
-                                       string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
-                                       fputs (buffer.c_str(), file);
-                                       fclose (file);
-                               }
-
-                               m_cws.DiscardWalk(pStartPosIndexE);
-                               foundHashInThread = true;
-                       }
-               }
-
-               pThreads.clear();
-               threadPool.clear();
-       }
-
-       //printf("\t\t\t\t\t\t\t\r");
-       printf("%-50s\r", "");
-       pThreads.clear();
-       threadPool.clear();
-       pthread_attr_destroy(&attr);
-
-       //printf("debug: chain walk step: %d\n", nChainWalkStep);
-       //printf("debug: false alarm: %d\n", nFalseAlarm);
-       //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
-
-       m_nTotalChainWalkStep += nChainWalkStep;
-       m_nTotalFalseAlarm += nFalseAlarm;
-       m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
-}
-
-void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)
-{
-       vector<string> vHash;
-       //vector<uint64 *> vIndices;
-       //vector<RainbowChain *> vChains;
-       hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());
-       printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),
-                                                                                  vHash.size() > 1 ? "es" : "");
-
-       int nChainWalkStep = 0;
-       int nFalseAlarm = 0;
-       int nChainWalkStepDueToFalseAlarm = 0;
-
-       vector<rcrackiThread*> threadPool;
-       vector<pthread_t> pThreads;
-       
-       #ifndef _WIN32
-               /*
-                * On linux you cannot set the priority of a thread in the non real time
-                * scheduling groups.  You can set the priority of the process.  In
-                * windows BELOW_NORMAL represents a 1/8th drop in priority and this would
-                * be 20 * 1/8 on linux or about 2.5
-                */
-               setpriority( PRIO_PROCESS, 0, 2 );
-       #endif
-
-       pthread_attr_t attr;
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-       #ifdef _WIN32
-       sched_param param;
-       param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;
-       pthread_attr_setschedparam (&attr, &param);
-       #endif
-       // else set it to 5 or something (for linux)?
-
-       bool pausing = false;
-
-       UINT4 nHashIndex;
-       for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)
-       {
-               #ifdef _WIN32
-               if (_kbhit())
-               {
-                       int ch = _getch();
-                       ch = toupper(ch);
-                       if (ch == 'P')
-                       {
-                               pausing = true;
-                               printf( "\nPausing, press P again to continue... ");
-                               
-                               timeval tv;
-                               timeval tv2;
-                               timeval final;
-                               gettimeofday( &tv, NULL );
-
-                               while (pausing)
-                               {
-                                       if (_kbhit())
-                                       {
-                                               ch = _getch();
-                                               ch = toupper(ch);
-                                               if (ch == 'P')
-                                               {
-                                                       printf( " [Continuing]\n");
-                                                       pausing = false;
-                                                       gettimeofday( &tv2, NULL );
-                                                       final = sub_timeofday( tv2, tv );
-                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                                       m_fTotalCryptanalysisTime -= fTime;
-                                               }
-                                       }
-                                       Sleep(500);
-                               }
-                       }
-                       else
-                       {
-                               printf( "\nPress 'P' to pause...\n");
-                       }
-               }
-               #else
-               int c = tty_getchar();
-               if (c >= 0) {
-                       tty_flush();
-                       if (c==112) { // = p
-                               pausing = true;
-                               printf( "\nPausing, press 'p' again to continue... ");
-
-                               timeval tv;
-                               timeval tv2;
-                               timeval final;
-                               gettimeofday( &tv, NULL );
-
-                               while (pausing)
-                               {
-                                       if ((c = tty_getchar()) >= 0)
-                                       {
-                                               tty_flush();
-                                               if (c == 112)
-                                               {
-                                                       printf( " [Continuing]\n");
-                                                       pausing = false;
-                                                       gettimeofday( &tv2, NULL );
-                                                       final = sub_timeofday( tv2, tv );
-                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                                       m_fTotalCryptanalysisTime -= fTime;
-                                               }
-                                       }
-                                       usleep(500*1000);
-                               }
-                       }
-                       else {
-                               printf( "\nPress 'p' to pause...\n");
-                       }
-               }
-               #endif
-               unsigned char TargetHash[MAX_HASH_LEN];
-               int nHashLen;
-               ParseHash(vHash[nHashIndex], TargetHash, nHashLen);
-               if (nHashLen != CChainWalkContext::GetHashLen())
-                       printf("debug: nHashLen mismatch\n");
-
-               // Request ChainWalk
-               bool fNewlyGenerated;
-//             printf("Requesting walk...");
-                
-
-               uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,
-                                                                                                       nHashLen,
-                                                                                                       CChainWalkContext::GetHashRoutineName(),
-                                                                                                       CChainWalkContext::GetPlainCharsetName(),
-                                                                                                       CChainWalkContext::GetPlainLenMin(),
-                                                                                                       CChainWalkContext::GetPlainLenMax(),
-                                                                                                       CChainWalkContext::GetRainbowTableIndex(),
-                                                                                                       nRainbowChainLen,
-                                                                                                       fNewlyGenerated,
-                                                                                                       debug,
-                                                                                                       sPrecalcPathName);
-//             printf("done!\n");
-//             printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",
-//                                                                                             vHash[nHashIndex].c_str());
-
-               if (fNewlyGenerated)
-               {
-                       timeval tv;
-                       timeval tv2;
-                       timeval final;
-
-                       gettimeofday( &tv, NULL );
-
-                       printf("Pre-calculating hash %lu of %lu.%-20s\r", 
-                               (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
-                       threadPool.clear();
-                       pThreads.clear();
-                       
-                       UINT4 thread_ID;
-                       for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
-                       {
-                               rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);
-                               if (r_Thread)
-                               {
-                                       pthread_t pThread;
-                                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
-                                       if( returnValue != 0 )
-                                       {
-                                               printf("pThread creation failed, returnValue: %d\n", returnValue);
-                                       }
-                                       else
-                                       {
-                                               pThreads.push_back(pThread);
-                                       }
-
-                                       threadPool.push_back(r_Thread);
-                               }
-                               else 
-                               {
-                                       printf("r_Thread creation failed!\n");
-                               }
-                       }
-                       
-                       //printf("%d r_Threads created\t\t\n", threadPool.size());
-                       
-                       for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
-                       {
-                               pthread_t pThread = pThreads[thread_ID];
-                               int returnValue = pthread_join(pThread, NULL);
-                               if( returnValue != 0 )
-                               {
-                                       printf("pThread join failed, returnValue: %d\n", returnValue);
-                               }
-                                       
-                               rcrackiThread* rThread = threadPool[thread_ID];
-                               nChainWalkStep += rThread->GetChainWalkStep();
-                               delete rThread;
-                       }
-
-                       m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);
-                       gettimeofday( &tv2, NULL );
-                       final = sub_timeofday( tv2, tv );
-                       
-                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-
-                       m_fTotalPrecalculationTime += fTime;
-                       m_fTotalCryptanalysisTime -= fTime;
-
-                       //printf("\npStartPosIndexE[0]: %s\n", uint64tostr(pStartPosIndexE[0]).c_str());
-                       //printf("\npStartPosIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pStartPosIndexE[nRainbowChainLen-2]).c_str());
-
-                       printf("%-50s\r", "");
-
-                       if ( debug )
-                               printf("pre-calculation time: %.2f s\n", fTime);
-               }
-
-               threadPool.clear();
-               pThreads.clear();
-
-               //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());
-               printf("Checking false alarms for hash %lu of %lu.%-20s\r",
-                       (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");
-
-               int i;
-               for (i = 0; i < maxThreads; i++)
-               {
-                       rcrackiThread* r_Thread = new rcrackiThread(TargetHash);
-                       threadPool.push_back(r_Thread);
-               }
-
-               UINT4 thread_ID = 0;
-               int nPos;
-               for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)
-               {
-                       uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];
-               
-                       // Search matching nIndexE
-                       RainbowChain *pChainFound = BinarySearch(pChain, nRainbowChainCount, nIndexEOfCurPos, pIndex, nIndexSize, nChainStart);
-                       if (pChainFound != NULL) // For perfected indexed tables we only recieve 1 result (huge speed increase!)
-                       {
-                               rcrackiThread* rThread = threadPool[thread_ID];
-                               rThread->AddAlarmCheck(pChainFound, nPos);
-                               if (thread_ID < (unsigned long)maxThreads - 1 ) {
-                                       thread_ID++;
-                               } else {
-                                       thread_ID = 0;
-                               }
-                       }
-               }
-
-               for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)
-               {
-                       rcrackiThread* r_Thread = threadPool[thread_ID];
-                       pthread_t pThread;
-
-                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);
-
-                       if( returnValue != 0 )
-                       {
-                               printf("pThread creation failed, returnValue: %d\n", returnValue);
-                       }
-                       else
-                       {
-                               pThreads.push_back(pThread);
-                       }
-               }
-               
-               //printf("%d r_Threads created\t\t\n", threadPool.size());
-
-               bool foundHashInThread = false;
-               for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)
-               {
-                       rcrackiThread* rThread = threadPool[thread_ID];
-                       pthread_t pThread = pThreads[thread_ID];
-
-                       int returnValue = pthread_join(pThread, NULL);
-                       if( returnValue != 0 )
-                       {
-                               printf("pThread join failed, returnValue: %d\n", returnValue);
-                       }
-
-                       nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();
-                       nFalseAlarm += rThread->GetnFalseAlarm();
-
-                       if (rThread->FoundHash() && !foundHashInThread) {
-                               //printf("\t\t\t\t\t\t\r");
-                               printf("%-50s\r", "");
-                               printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());
-                               if (writeOutput)
-                               {
-                                       if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))
-                                               printf("Couldn't write this result to file!\n");
-                               }
-                               hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());
-                               
-                               FILE* file = fopen(sSessionPathName.c_str(), "a");
-                               if (file!=NULL)
-                               {
-                                       string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";
-                                       fputs (buffer.c_str(), file);
-                                       fclose (file);
-                               }
-
-                               m_cws.DiscardWalk(pStartPosIndexE);
-                               foundHashInThread = true;
-                       }
-                       //pthread
-                       delete rThread;
-               }
-
-               pThreads.clear();
-               threadPool.clear();
-
-               //printf("\t\t\t\t\r");
-               //printf("pChainFounds: %d\n", pChainsFound.size());
-//NEXT_HASH:;
-       }
-       //printf("\t\t\t\t\t\t\t\r");
-       printf("%-50s\r", "");
-       pThreads.clear();
-       threadPool.clear();
-       pthread_attr_destroy(&attr);
-
-       //printf("debug: chain walk step: %d\n", nChainWalkStep);
-       //printf("debug: false alarm: %d\n", nFalseAlarm);
-       //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);
-
-       m_nTotalChainWalkStep += nChainWalkStep;
-       m_nTotalFalseAlarm += nFalseAlarm;
-       m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;
-}
-
-void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)
-{
-       // Did we already go through this file in this session?
-       if (resumeSession)
-       {
-               vector<string> sessionFinishedPathNames;
-               if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))
-               {
-                       UINT4 i;
-                       for (i = 0; i < sessionFinishedPathNames.size(); i++)
-                       {
-                               if (sessionFinishedPathNames[i] == sPathName)
-                               {
-                                       printf("Skipping %s\n", sPathName.c_str());
-                                       return;
-                               }
-                       }
-               }
-       }
-
-       // FileName
-#ifdef _WIN32
-       string::size_type nIndex = sPathName.find_last_of('\\');
-#else
-       string::size_type nIndex = sPathName.find_last_of('/');
-#endif
-       string sFileName;
-       if (nIndex != string::npos)
-               sFileName = sPathName.substr(nIndex + 1);
-       else
-               sFileName = sPathName;
-
-       // Info
-       printf("%s:\n", sFileName.c_str());
-
-       // Setup
-       int nRainbowChainLen, nRainbowChainCount;
-       if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))
-               return;
-       //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());
-       // Already finished?
-       if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
-       {
-               printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());
-               return;
-       }
-
-       // Open
-       FILE* file = fopen(sPathName.c_str(), "rb");
-       if (file != NULL)
-       {
-               // File length check
-               bool doOldFormat = CChainWalkContext::isOldFormat();
-               bool doRti2Format = CChainWalkContext::isRti2Format();
-               UINT4 sizeOfChain;
-               bool fVerified = false;
-               UINT4 nFileLen = GetFileLen(file);
-
-               if (doOldFormat)
-                       sizeOfChain = 16;
-               else
-                       sizeOfChain = 8;
-
-               //if (nFileLen % 8 != 0 || nRainbowChainCount * 8 != nFileLen)
-               if ( (nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != nFileLen) && doRti2Format == false )
-                       printf("file length mismatch\n");
-               else
-               {
-                       fseek(file, 0, SEEK_SET);
-                       timeval tv;
-                       timeval tv2;
-                       timeval final;
-
-                       unsigned int bytesForChainWalkSet = hs.GetStatHashTotal() * (nRainbowChainLen-1) * 8;
-                       if (debug) printf("Debug: Saving %u bytes of memory for chainwalkset.\n", bytesForChainWalkSet);
-
-                       uint64 nAllocatedSize;
-
-                       if (doRti2Format || doOldFormat)
-                       {
-                               RTI2Reader *pReader = NULL;
-
-                               if(doRti2Format) {
-                                       pReader = new RTI2Reader(sPathName);
-
-                               }
-
-                               if (debug)
-                               {
-                                       if ( doOldFormat )
-                                               printf("Debug: This is a table in the old .rt format.\n");
-                                       else if ( doRti2Format )
-                                               printf("Debug: This is a table in the .rti2 format.\n");
-                               }
-
-                               static CMemoryPool mp(bytesForChainWalkSet, debug, maxMem);
-                               RainbowChainO* pChain = NULL;
-                               if(doRti2Format) {
-                                       pChain = (RainbowChainO*)mp.Allocate(pReader->GetChainsLeft() * 16, nAllocatedSize);
-                               } else {
-                                       pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);
-                               }
-                               #ifdef _WIN32
-                                       if (debug) printf("Allocated %I64u bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);
-                               #else
-                                       if (debug) printf("Allocated %llu bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);
-                               #endif
-
-                               if (pChain != NULL)
-                               {
-                                       nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary
-
-                                       //fseek(file, 0, SEEK_SET);
-                                       //bool fVerified = false;
-                                       while (true)    // Chunk read loop
-                                       {
-                                               if ((unsigned long)ftell(file) == nFileLen)
-                                                       break;
-
-                                               // Load table chunk
-                                               if (debug) printf("reading...\n");
-                                               unsigned int nDataRead = 0;
-                                               gettimeofday( &tv, NULL );
-                                               if ( doRti2Format )
-                                               {
-                                                       nDataRead = nAllocatedSize / 16;
-                                                       if(pReader->GetChainsLeft() <= 0) // No more data
-                                                               break; 
-                                                       pReader->ReadChains(nDataRead, (RainbowChain*)pChain);
-
-                                                       nDataRead *= 8; // Convert from chains read to bytes
-                                               }
-                                               else
-                                               {
-                                                       nDataRead = fread(pChain, 1, nAllocatedSize, file);
-                                               }
-                                               gettimeofday( &tv2, NULL );
-                                               final = sub_timeofday( tv2, tv );
-
-                                               float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                               printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
-                                               m_fTotalDiskAccessTime += fTime;
-
-                                               int nRainbowChainCountRead = nDataRead / 16;
-
-                                               if(doRti2Format) {
-                                                       nRainbowChainCountRead = nDataRead / 8;
-                                               }
-
-                                               // Verify table chunk
-                                               if (!fVerified)
-                                               {
-                                                       printf("verifying the file...\n");
-
-                                                       // Chain length test
-                                                       int nIndexToVerify = nRainbowChainCountRead / 2;
-                                                       CChainWalkContext cwc;
-                                                       cwc.SetIndex(pChain[nIndexToVerify].nIndexS);
-                                                       int nPos;
-                                                       for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
-                                                       {
-                                                               cwc.IndexToPlain();
-                                                               cwc.PlainToHash();
-                                                               cwc.HashToIndex(nPos);
-                                                       }
-                                                       if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)
-                                                       {
-                                                               printf("rainbow chain length verify fail\n");
-                                                               break;
-                                                       }
-
-                                                       // Chain sort test
-                                                       int i;
-                                                       for (i = 0; i < nRainbowChainCountRead - 1; i++)
-                                                       {
-                                                               if (pChain[i].nIndexE > pChain[i + 1].nIndexE)
-                                                                       break;
-                                                       }
-                                                       if (i != nRainbowChainCountRead - 1)
-                                                       {
-                                                               printf("this file is not sorted\n");
-                                                               break;
-                                                       }
-
-                                                       fVerified = true;
-                                               }
-
-                                               // Search table chunk
-                                               gettimeofday( &tv, NULL );
-                                               SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);
-                                               gettimeofday( &tv2, NULL );
-                                               final = sub_timeofday( tv2, tv );
-                                               fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                               printf("cryptanalysis time: %.2f s\n", fTime);
-                                               m_fTotalCryptanalysisTime += fTime;
-
-                                               // Already finished?
-                                               if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
-                                                       break;
-                                       }
-                               }
-                               else
-                                       printf("memory allocation fail\n");
-                               
-                               //delete pChain;
-                       }
-                       else
-                       {
-                               static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);
-                               uint64 nAllocatedSizeIndex;
-
-                               //int nIndexSize = 0;
-                               //IndexChain *pIndex = NULL;
-
-                               FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");
-                               if(fIndex != NULL)
-                               {
-                                       // File length check
-                                       unsigned int nFileLenIndex = GetFileLen(fIndex);
-                                       //unsigned int nRows = nFileLenIndex / 11;
-                                       //unsigned int nSize = nRows * sizeof(IndexChain);
-                                       //printf("Debug: 8\n");
-                                       if (nFileLenIndex % 11 != 0)
-                                               printf("index file length mismatch (%u bytes)\n", nFileLenIndex);
-                                       else
-                                       {
-                                               //printf("index nSize: %d\n", nSize);
-                                               //pIndex = (IndexChain*)new unsigned char[nSize];
-                                               IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);
-                                               #ifdef _WIN32
-                                                       if (debug) printf("Debug: Allocated %I64u bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
-                                               #else
-                                                       if (debug) printf("Debug: Allocated %llu bytes for index with filelen %u\n", nAllocatedSizeIndex, nFileLenIndex);
-                                               #endif
-                               
-                                               static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);
-                                               
-                                               if (pIndex != NULL && nAllocatedSizeIndex > 0)
-                                               {
-                                                       nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain);            // Round to sizeOfIndexChain boundary
-                                               
-                                                       fseek(fIndex, 0, SEEK_SET);
-
-                                                       while ( (unsigned long)ftell(fIndex) != nFileLenIndex ) // Index chunk read loop
-                                                       {
-                                                               // Load index chunk
-#ifdef _WIN32
-                                                               if (debug) printf("Debug: Setting index to 0x00 in memory, %I64u bytes\n", nAllocatedSizeIndex);
-#else
-                                                               if (debug) printf("Debug: Setting index to 0x00 in memory, %llu bytes\n", nAllocatedSizeIndex);
-#endif
-                                                               memset(pIndex, 0x00, nAllocatedSizeIndex);
-                                                               printf("reading index... ");
-                                                               gettimeofday( &tv, NULL );
-                                                               unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);
-                                                               gettimeofday( &tv2, NULL );
-                                                               final = sub_timeofday( tv2, tv );
-
-                                                               float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                                               printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
-                                                               m_fTotalDiskAccessTime += fTime;
-                                                       
-                                                               //nIndexSize = nFileLenIndex / 11;
-                                                               int nIndexChainCountRead = nDataRead / sizeof(IndexChain);
-                                                               //fclose(fIndex);
-                                                               unsigned int nCoveredRainbowTableChains = 0;
-                                                               for(int i = 0; i < nIndexChainCountRead; i++)
-                                                               {
-                                                                       nCoveredRainbowTableChains += pIndex[i].nChainCount;
-                                                               }
-
-                                                               //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);
-                                                               RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);
-                                                               #ifdef _WIN32
-                                                                       if (debug) printf("Debug: Allocated %I64u bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);
-                                                               #else
-                                                                       if (debug) printf("Debug: Allocated %llu bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);
-                                                               #endif
-
-                                                               if (pChain != NULL && nAllocatedSize > 0)
-                                                               {
-                                                                       nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary
-
-                                                                       //fseek(file, 0, SEEK_SET);
-                                                                       //bool fVerified = false;
-                                                                       UINT4 nProcessedChains = 0;
-                                                                       while ( (unsigned long)ftell(file) != nFileLen 
-                                                                               && nProcessedChains < nCoveredRainbowTableChains )      // Chunk read loop
-                                                                       {
-                                                                               // Load table chunk
-                                                                               if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");
-                                                                               memset(pChain, 0x00, nAllocatedSize);
-                                                                               printf("reading table... ");
-                                                                               gettimeofday( &tv, NULL );
-                                                                               unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);
-                                                                               gettimeofday( &tv2, NULL );
-                                                                               final = sub_timeofday( tv2, tv );
-
-                                                                               float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                                                               printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);
-                                                                               m_fTotalDiskAccessTime += fTime;
-                                                                               int nRainbowChainCountRead = nDataRead / sizeOfChain;
-                                                                               // Verify table chunk (Too lazy to implement this)
-                                                                               
-                                                                               if (!fVerified)
-                                                                               {
-                                                                                       printf("verifying the file... ");
-
-                                                                                       // Chain length test
-                                                                                       int nIndexToVerify = nRainbowChainCountRead / 2;
-                                                                                       CChainWalkContext cwc;
-                                                                                       uint64 nIndexS;
-                                                                                       nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
-
-                                                                                       //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());
-                                                                                       cwc.SetIndex(nIndexS);
-                                                                                       
-                                                                                       int nPos;
-                                                                                       for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)
-                                                                                       {
-                                                                                               cwc.IndexToPlain();
-                                                                                               cwc.PlainToHash();
-                                                                                               cwc.HashToIndex(nPos);
-                                                                                       }
-
-                                                                                       uint64 nEndPoint = 0;
-
-                                                                                       //for(int i = 0; i < nIndexSize; i++)
-                                                                                       for(int i = 0; i < nIndexChainCountRead; i++)
-                                                                                       {
-                                                                                               if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index
-                                                                                               { // Now we need to seek nIndexToVerify into the chains
-                                                                                                       nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes
-                                                                                                       //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());
-                                                                                                       //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);
-                                                                                                       //printf("nChainCount: %d\n", pIndex[i].nChainCount);
-                                                                                                       nEndPoint += pChain[nIndexToVerify].nIndexE;
-                                                                                                       break;
-                                                                                               }
-                                                                                       }
-
-                                                                                       if (cwc.GetIndex() != nEndPoint)
-                                                                                       {
-                                                                                               printf("rainbow chain length verify fail\n");
-                                                                                               break;
-                                                                                       }
-
-                                                                                       fVerified = true;
-                                                                                       printf("ok\n");
-                                                                               }
-
-                                                                               // Search table chunk
-                                                                               gettimeofday( &tv, NULL );
-                                                                               float preTime = m_fTotalCryptanalysisTime;
-
-                                                                               SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);
-                                                                               float postTime = m_fTotalCryptanalysisTime;
-                                                                               gettimeofday( &tv2, NULL );
-                                                                               final = sub_timeofday( tv2, tv );
-
-                                                                               fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;
-                                                                               printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);
-                                                                               m_fTotalCryptanalysisTime += fTime;
-                                                                               nProcessedChains += nRainbowChainCountRead;
-                                                                               // Already finished?
-                                                                               if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))
-                                                                                       break;
-                                                                       }
-                                                               }
-                                                               else printf("memory allocation failed for rainbow table\n");
-
-                                                               //delete pChain;
-                                                       }
-                                               }
-                                               else printf("memory allocation failed for index\n");
-                                       }               
-                               }
-                               else 
-                               {
-                                       printf("Can't load index\n");
-                                       return;
-                               }
-                               fclose(fIndex);
-                               
-                               //delete pIndex;
-                       }
-               }
-               fclose(file);
-
-               if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());
-               FILE* file = fopen(sProgressPathName.c_str(), "a");
-               if (file!=NULL)
-               {
-                       string buffer = sPathName + "\n";
-                       fputs (buffer.c_str(), file);
-                       fclose (file);
-               }
-       }
-       else
-               printf("can't open file\n");
-}
-
-void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)
-{
-#ifndef _WIN32
-       tty_init();
-#endif
-       resumeSession = resume;
-       debug = bDebug;
-
-       maxThreads = i_maxThreads;
-       maxMem = i_maxMem;
-       // Reset statistics
-       ResetStatistics();
-
-       // Sort vPathName (CChainWalkSet need it)
-       UINT4 i, j;
-       for (i = 0; i < vPathName.size() - 1; i++)
-               for (j = 0; j < vPathName.size() - i - 1; j++)
-               {
-                       if (vPathName[j] > vPathName[j + 1])
-                       {
-                               string sTemp;
-                               sTemp = vPathName[j];
-                               vPathName[j] = vPathName[j + 1];
-                               vPathName[j + 1] = sTemp;
-                       }
-               }
-
-       // Run
-       for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)
-       {
-               SearchRainbowTable(vPathName[i], hs);
-               printf("\n");
-       }
-
-       // delete precalc files
-       if (!keepPrecalcFiles)
-               m_cws.removePrecalcFiles();
-
-#ifndef _WIN32
-       tty_done();
-#endif
-}
-
-void CCrackEngine::setOutputFile(string sPathName)
-{
-       writeOutput = true;
-       outputFile = sPathName;
-}
-
-void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)
-{
-       sSessionPathName = sSession;
-       sProgressPathName = sProgress;
-       sPrecalcPathName = sPrecalc;
-       keepPrecalcFiles = keepPrecalc;
-}
-
-float CCrackEngine::GetStatTotalDiskAccessTime()
-{
-       return m_fTotalDiskAccessTime;
-}
-/*float CCrackEngine::GetWastedTime()
-{
-       return m_fIndexTime;
-}*/
-float CCrackEngine::GetStatTotalCryptanalysisTime()
-{
-       return m_fTotalCryptanalysisTime;
-}
-
-float CCrackEngine::GetStatTotalPrecalculationTime()
-{
-       return m_fTotalPrecalculationTime;
-}
-
-int CCrackEngine::GetStatTotalChainWalkStep()
-{
-       return m_nTotalChainWalkStep;
-}
-
-int CCrackEngine::GetStatTotalFalseAlarm()
-{
-       return m_nTotalFalseAlarm;
-}
-
-int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()
-{
-       return m_nTotalChainWalkStepDueToFalseAlarm;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright 2009, 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ * Copyright 2010 uroskn\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "CrackEngine.h"\r
+#include "RTI2Reader.h"\r
+\r
+#ifndef _WIN32\r
+       #include <sys/resource.h>\r
+#endif\r
+\r
+CCrackEngine::CCrackEngine()\r
+{\r
+       ResetStatistics();\r
+       writeOutput = false;\r
+       resumeSession = false;\r
+       debug = false;\r
+       keepPrecalcFiles = false;\r
+\r
+       sSessionPathName = "";\r
+       sProgressPathName = "";\r
+}\r
+\r
+CCrackEngine::~CCrackEngine()\r
+{\r
+}\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+void CCrackEngine::ResetStatistics()\r
+{\r
+       m_fTotalDiskAccessTime               = 0.0f;\r
+       m_fTotalCryptanalysisTime            = 0.0f;\r
+       m_fTotalPrecalculationTime           = 0.0f;\r
+       m_nTotalChainWalkStep                = 0;\r
+       m_nTotalFalseAlarm                   = 0;\r
+       m_nTotalChainWalkStepDueToFalseAlarm = 0;\r
+//     m_nTotalFalseAlarmSkipped                        = 0;\r
+}\r
+\r
+int CCrackEngine::BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex)\r
+{\r
+       int nLow = 0;\r
+       int nHigh = nRainbowChainCount - 1;\r
+       while (nLow <= nHigh)\r
+       {\r
+               int nMid = (nLow + nHigh) / 2;\r
+               if (nIndex == pChain[nMid].nIndexE)\r
+                       return nMid;\r
+               else if (nIndex < pChain[nMid].nIndexE)\r
+                       nHigh = nMid - 1;\r
+               else\r
+                       nLow = nMid + 1;\r
+       }\r
+\r
+       return -1;\r
+}\r
+\r
+RainbowChain *CCrackEngine::BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart)\r
+{\r
+       uint64 nPrefix = nIndex >> 16;\r
+       int nLow, nHigh;        \r
+       bool found = false;\r
+       //int nChains = 0;\r
+       \r
+       if(nPrefix > (pIndex[nIndexSize-1].nPrefix & 0x000000FFFFFFFFFFULL)) // check if its in the index file\r
+       {\r
+               return NULL;\r
+       }\r
+\r
+       int nBLow = 0;\r
+       int nBHigh = nIndexSize - 1;\r
+       while (nBLow <= nBHigh)\r
+       {\r
+               int nBMid = (nBLow + nBHigh) / 2;\r
+               if (nPrefix == (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
+               {\r
+                       //nLow = nChains;\r
+                       //int nChains = 0;\r
+\r
+                       nLow = pIndex[nBMid].nFirstChain;\r
+                       nHigh = nLow + pIndex[nBMid].nChainCount;\r
+                       if(nLow >= nIndexStart && nLow <= nIndexStart + nChainCountRead) \r
+                       {                                       \r
+                               if(nHigh > nIndexStart + nChainCountRead)\r
+                                       nHigh = nIndexStart + nChainCountRead;\r
+                       }\r
+                       else if(nLow < nIndexStart && nHigh >= nIndexStart)\r
+                       {\r
+                               nLow = nIndexStart;\r
+                       }\r
+                       else break;                                     \r
+                       found = true;\r
+                       break;\r
+               }\r
+               else if (nPrefix < (pIndex[nBMid].nPrefix & 0x000000FFFFFFFFFFULL))\r
+                       nBHigh = nBMid - 1;\r
+               else\r
+                       nBLow = nBMid + 1;\r
+       }\r
+       if(found == true)\r
+       {\r
+               for(int i = nLow - nIndexStart; i < nHigh - nIndexStart; i++)\r
+               {\r
+                       int nSIndex = ((int)nIndex) & 0x0000FFFF;\r
+\r
+                       if (nSIndex == pChain[i].nIndexE)\r
+                       {\r
+                               return &pChain[i];\r
+                       }                               \r
+                       else if(pChain[i].nIndexE > nSIndex)\r
+                               break;\r
+               }\r
+       }       \r
+       return NULL;\r
+}\r
+\r
+// not used currently, leaving code for future checkpoints\r
+//bool CCrackEngine::CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)\r
+//{\r
+//     CChainWalkContext cwc;\r
+//     //uint64 nIndexS = pChain->nIndexS >> 16;\r
+//     uint64 nIndexS = pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes\r
+//     cwc.SetIndex(nIndexS);\r
+//     int nPos;\r
+//     for (nPos = 0; nPos < nGuessedPos; nPos++)\r
+//     {\r
+//             cwc.IndexToPlain();\r
+//             cwc.PlainToHash();\r
+//             cwc.HashToIndex(nPos);\r
+//             // Not using checkpoints atm\r
+//             /*\r
+//             switch(nPos)\r
+//             {\r
+//             case 5000:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000080) >> 7)\r
+//                             {\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 5000;\r
+////                                   printf("CheckPoint caught false alarm at position 7600\n");\r
+//                                     return false;\r
+//                             }\r
+//                             break;\r
+//             case 6000:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000040) >> 6)\r
+//                             {\r
+////                                   printf("CheckPoint caught false alarm at position 8200\n");\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 6000;\r
+//                                     return false;\r
+//                             }\r
+//                             break;\r
+//\r
+//             case 7600:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000020) >> 5)\r
+//                             {\r
+////                                   printf("CheckPoint caught false alarm at position 8700\n");\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 7600;\r
+//                                     return false;\r
+//                             }\r
+//                             break;\r
+//\r
+//             case 8200:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000010) >> 4)\r
+//                             {\r
+////                                   printf("CheckPoint caught false alarm at position 9000\n");\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 8200;\r
+//                                     return false;\r
+//                             }\r
+//                             break;\r
+//\r
+//                     case 8700:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000008) >> 3)\r
+//                             {\r
+////                                   printf("CheckPoint caught false alarm at position 9300\n");\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 8700;\r
+//                                     return false;\r
+//                             }\r
+//\r
+//                             break;\r
+//                     case 9000:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000004) >> 2)\r
+//                             {\r
+////                                   printf("CheckPoint caught false alarm at position 9600\n");\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 9000;\r
+//                                     return false;\r
+//                             }\r
+//\r
+//                             break;\r
+//                     case 9300:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000002) >> 1)\r
+//                             {\r
+////                                   printf("CheckPoint caught false alarm at position 9600\n");\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 9300;\r
+//                                     return false;\r
+//                             }\r
+//                             break;\r
+//                     case 9600:\r
+//                             if((cwc.GetIndex() & 0x00000001) != (pChain->nCheckPoint & 0x00000001))\r
+//                             {\r
+////                                   printf("CheckPoint caught false alarm at position 9600\n");\r
+//                                     m_nTotalFalseAlarmSkipped += 10000 - 9600;\r
+//                                     return false;\r
+//                             }\r
+//                             break;\r
+//\r
+//             }*/\r
+//     }\r
+//     cwc.IndexToPlain();\r
+//     cwc.PlainToHash();\r
+//     if (cwc.CheckHash(pHash))\r
+//     {\r
+//             printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());\r
+//             hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());\r
+//             return true;\r
+//     }\r
+//\r
+//     return false;\r
+//}\r
+\r
+//bool CCrackEngine::CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs)\r
+//{\r
+//     CChainWalkContext cwc;\r
+//     cwc.SetIndex(pChain->nIndexS);\r
+//     int nPos;\r
+//     for (nPos = 0; nPos < nGuessedPos; nPos++)\r
+//     {\r
+//             cwc.IndexToPlain();\r
+//             cwc.PlainToHash();\r
+//             cwc.HashToIndex(nPos);\r
+//     }\r
+//     cwc.IndexToPlain();\r
+//     cwc.PlainToHash();\r
+//     if (cwc.CheckHash(pHash))\r
+//     {\r
+//             printf("plaintext of %s is %s\n", cwc.GetHash().c_str(), cwc.GetPlain().c_str());\r
+//             hs.SetPlain(cwc.GetHash(), cwc.GetPlain(), cwc.GetBinary());\r
+//             return true;\r
+//     }\r
+//\r
+//     return false;\r
+//}\r
+\r
+void CCrackEngine::GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain,\r
+                                                                                                         int nRainbowChainCount,\r
+                                                                                                         int nMatchingIndexE,\r
+                                                                                                         int& nMatchingIndexEFrom,\r
+                                                                                                         int& nMatchingIndexETo)\r
+{\r
+       nMatchingIndexEFrom = nMatchingIndexE;\r
+       nMatchingIndexETo   = nMatchingIndexE;\r
+       while (nMatchingIndexEFrom > 0)\r
+       {\r
+               if (pChain[nMatchingIndexEFrom - 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
+                       nMatchingIndexEFrom--;\r
+               else\r
+                       break;\r
+       }\r
+       while (nMatchingIndexETo < nRainbowChainCount - 1)\r
+       {\r
+               if (pChain[nMatchingIndexETo + 1].nIndexE == pChain[nMatchingIndexE].nIndexE)\r
+                       nMatchingIndexETo++;\r
+               else\r
+                       break;\r
+       }\r
+}\r
+\r
+void CCrackEngine::SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs)\r
+{\r
+       vector<string> vHash;\r
+       hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());\r
+       printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),\r
+                                                                                  vHash.size() > 1 ? "es" : "");\r
+\r
+       int nChainWalkStep = 0;\r
+       int nFalseAlarm = 0;\r
+       int nChainWalkStepDueToFalseAlarm = 0;\r
+\r
+       vector<rcrackiThread*> threadPool;\r
+       vector<pthread_t> pThreads;\r
+\r
+       #ifndef _WIN32\r
+               /*\r
+                * On linux you cannot set the priority of a thread in the non real time\r
+                * scheduling groups.  You can set the priority of the process.  In\r
+                * windows BELOW_NORMAL represents a 1/8th drop in priority and this would\r
+                * be 20 * 1/8 on linux or about 2.5\r
+                */\r
+               setpriority( PRIO_PROCESS, 0, 2 );\r
+       #endif\r
+\r
+       pthread_attr_t attr;\r
+       pthread_attr_init(&attr);\r
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
+       #ifdef _WIN32\r
+       sched_param param;\r
+       /*\r
+        * windows scheduling is 0 to 32 (low to high) with 8 as normal and 7 as\r
+        * BELOW_NORMAL\r
+        */\r
+       param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
+       pthread_attr_setschedparam (&attr, &param);\r
+       #endif\r
+\r
+       bool pausing = false;\r
+\r
+       uint32 nHashIndex;\r
+       for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
+       {\r
+               #ifdef _WIN32\r
+               if (_kbhit())\r
+               {\r
+                       int ch = _getch();\r
+                       ch = toupper(ch);\r
+                       if (ch == 'P')\r
+                       {\r
+                               pausing = true;\r
+                               printf( "\nPausing, press P again to continue... ");\r
+\r
+                               timeval tv;\r
+                               timeval tv2;\r
+                               timeval final;\r
+                               gettimeofday( &tv, NULL );\r
+\r
+                               while (pausing)\r
+                               {\r
+                                       if (_kbhit())\r
+                                       {\r
+                                               ch = _getch();\r
+                                               ch = toupper(ch);\r
+                                               if (ch == 'P')\r
+                                               {\r
+                                                       printf( " [Continuing]\n");\r
+                                                       pausing = false;\r
+                                                       gettimeofday( &tv2, NULL );\r
+                                                       final = sub_timeofday( tv2, tv );\r
+                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                                       m_fTotalCryptanalysisTime -= fTime;\r
+                                               }\r
+                                       }\r
+                                       Sleep(500);\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               printf( "\nPress 'P' to pause...\n");\r
+                       }\r
+               }\r
+               #else\r
+               int c = tty_getchar();\r
+               if (c >= 0) {\r
+                       tty_flush();\r
+                       if (c==112) { // = p\r
+                               pausing = true;\r
+                               printf( "\nPausing, press 'p' again to continue... ");\r
+                               \r
+                               timeval tv;\r
+                               timeval tv2;\r
+                               timeval final;\r
+                               gettimeofday( &tv, NULL );\r
+                               \r
+                               while (pausing)\r
+                               {\r
+                                       if ((c = tty_getchar()) >= 0)\r
+                                       {\r
+                                               tty_flush();\r
+                                               if (c == 112)\r
+                                               {\r
+                                                       printf( " [Continuing]\n");\r
+                                                       pausing = false;\r
+                                                       gettimeofday( &tv2, NULL );\r
+                                                       final = sub_timeofday( tv2, tv );\r
+                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                                       m_fTotalCryptanalysisTime -= fTime;\r
+                                               }\r
+                                       }\r
+                                       usleep(500*1000);\r
+                               }\r
+                       }\r
+                       else {\r
+                               printf( "\nPress 'p' to pause...\n");\r
+                       }\r
+               }\r
+               #endif\r
+               unsigned char TargetHash[MAX_HASH_LEN];\r
+               int nHashLen;\r
+               ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
+               if (nHashLen != CChainWalkContext::GetHashLen())\r
+                       printf("debug: nHashLen mismatch\n");\r
+\r
+               // Rqeuest ChainWalk\r
+               bool fNewlyGenerated;\r
+               uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
+                                                                                                       nHashLen,\r
+                                                                                                       CChainWalkContext::GetHashRoutineName(),\r
+                                                                                                       CChainWalkContext::GetPlainCharsetName(),\r
+                                                                                                       CChainWalkContext::GetPlainLenMin(),\r
+                                                                                                       CChainWalkContext::GetPlainLenMax(),\r
+                                                                                                       CChainWalkContext::GetRainbowTableIndex(),\r
+                                                                                                       nRainbowChainLen,\r
+                                                                                                       fNewlyGenerated,\r
+                                                                                                       debug,\r
+                                                                                                       sPrecalcPathName);\r
+               //printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",\r
+               //                                                                              vHash[nHashIndex].c_str());\r
+\r
+               // Walk\r
+               if (fNewlyGenerated)\r
+               {\r
+                       timeval tv;\r
+                       timeval tv2;\r
+                       timeval final;\r
+\r
+                       gettimeofday( &tv, NULL );\r
+\r
+                       printf("Pre-calculating hash %lu of %lu.%-20s\r",\r
+                               (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+                       threadPool.clear();\r
+                       pThreads.clear();\r
+                       \r
+                       uint32 thread_ID;\r
+                       for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+                       {\r
+                               rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
+                               if (r_Thread)\r
+                               {\r
+                                       pthread_t pThread;\r
+                                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+                                       if( returnValue != 0 )\r
+                                       {\r
+                                               printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               pThreads.push_back(pThread);\r
+                                       }\r
+\r
+                                       threadPool.push_back(r_Thread);\r
+                               }\r
+                               else \r
+                               {\r
+                                       printf("r_Thread creation failed!\n");\r
+                               }\r
+                       }\r
+                       \r
+                       //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+                       \r
+                       for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+                       {\r
+                               pthread_t pThread = pThreads[thread_ID];\r
+                               int returnValue = pthread_join(pThread, NULL);\r
+                               if( returnValue != 0 )\r
+                               {\r
+                                       printf("pThread join failed, returnValue: %d\n", returnValue);\r
+                               }\r
+                                       \r
+                               rcrackiThread* rThread = threadPool[thread_ID];\r
+                               nChainWalkStep += rThread->GetChainWalkStep();\r
+                       }\r
+\r
+                       gettimeofday( &tv2, NULL );\r
+                       final = sub_timeofday( tv2, tv );\r
+                       \r
+                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+\r
+                       m_fTotalPrecalculationTime += fTime;\r
+                       m_fTotalCryptanalysisTime -= fTime;\r
+\r
+                       printf("%-50s\r", "");\r
+\r
+                       if ( debug )\r
+                               printf("pre-calculation time: %.2f s\n", fTime);\r
+               }\r
+\r
+               //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());\r
+               printf("Checking false alarms for hash %lu of %lu.%-20s\r", \r
+                       (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+\r
+               threadPool.clear();\r
+               pThreads.clear();\r
+\r
+               int i;\r
+               for (i = 0; i < maxThreads; i++)\r
+               {\r
+                       rcrackiThread* r_Thread = new rcrackiThread(TargetHash, true);\r
+                       threadPool.push_back(r_Thread);\r
+               }\r
+\r
+               uint32 thread_ID = 0;\r
+               int nPos;\r
+               for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
+               {\r
+                       uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
+               \r
+                       // Search matching nIndexE\r
+                       int nMatchingIndexE = BinarySearchOld(pChain, nRainbowChainCount, nIndexEOfCurPos);\r
+                       if (nMatchingIndexE != -1)\r
+                       {\r
+                               int nMatchingIndexEFrom, nMatchingIndexETo;\r
+                               GetChainIndexRangeWithSameEndpoint(pChain, nRainbowChainCount,\r
+                                                                                                  nMatchingIndexE,\r
+                                                                                                  nMatchingIndexEFrom, nMatchingIndexETo);\r
+                               int i;\r
+                               for (i = nMatchingIndexEFrom; i <= nMatchingIndexETo; i++)\r
+                               {\r
+                                       rcrackiThread* rThread = threadPool[thread_ID];\r
+                                       rThread->AddAlarmCheckO(pChain + i, nPos);\r
+                                       if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
+                                               thread_ID++;\r
+                                       } else {\r
+                                               thread_ID = 0;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+               {\r
+                       rcrackiThread* r_Thread = threadPool[thread_ID];\r
+                       pthread_t pThread;\r
+\r
+                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+                       if( returnValue != 0 )\r
+                       {\r
+                               printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+                       }\r
+                       else\r
+                       {\r
+                               pThreads.push_back(pThread);\r
+                       }\r
+               }\r
+               \r
+               //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+\r
+               bool foundHashInThread = false;\r
+               for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+               {\r
+                       rcrackiThread* rThread = threadPool[thread_ID];\r
+                       pthread_t pThread = pThreads[thread_ID];\r
+\r
+                       int returnValue = pthread_join(pThread, NULL);\r
+                       if( returnValue != 0 )\r
+                       {\r
+                               printf("pThread join failed, returnValue: %d\n", returnValue);\r
+                       }\r
+\r
+                       nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
+                       nFalseAlarm += rThread->GetnFalseAlarm();\r
+\r
+                       if (rThread->FoundHash() && !foundHashInThread) {\r
+                               //printf("\t\t\t\t\t\t\r");\r
+                               printf("%-50s\r", "");\r
+\r
+                               printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());\r
+                               if (writeOutput)\r
+                               {\r
+                                       if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
+                                               printf("Couldn't write this result to file!\n");\r
+                               }\r
+                               hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
+\r
+                               FILE* file = fopen(sSessionPathName.c_str(), "a");\r
+                               if (file!=NULL)\r
+                               {\r
+                                       string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
+                                       fputs (buffer.c_str(), file);\r
+                                       fclose (file);\r
+                               }\r
+\r
+                               m_cws.DiscardWalk(pStartPosIndexE);\r
+                               foundHashInThread = true;\r
+                       }\r
+               }\r
+\r
+               pThreads.clear();\r
+               threadPool.clear();\r
+       }\r
+\r
+       //printf("\t\t\t\t\t\t\t\r");\r
+       printf("%-50s\r", "");\r
+       pThreads.clear();\r
+       threadPool.clear();\r
+       pthread_attr_destroy(&attr);\r
+\r
+       //printf("debug: chain walk step: %d\n", nChainWalkStep);\r
+       //printf("debug: false alarm: %d\n", nFalseAlarm);\r
+       //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);\r
+\r
+       m_nTotalChainWalkStep += nChainWalkStep;\r
+       m_nTotalFalseAlarm += nFalseAlarm;\r
+       m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
+}\r
+\r
+void CCrackEngine::SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart)\r
+{\r
+       vector<string> vHash;\r
+       //vector<uint64 *> vIndices;\r
+       //vector<RainbowChain *> vChains;\r
+       hs.GetLeftHashWithLen(vHash, CChainWalkContext::GetHashLen());\r
+       printf("searching for %lu hash%s...\n", (unsigned long)vHash.size(),\r
+                                                                                  vHash.size() > 1 ? "es" : "");\r
+\r
+       int nChainWalkStep = 0;\r
+       int nFalseAlarm = 0;\r
+       int nChainWalkStepDueToFalseAlarm = 0;\r
+\r
+       vector<rcrackiThread*> threadPool;\r
+       vector<pthread_t> pThreads;\r
+       \r
+       #ifndef _WIN32\r
+               /*\r
+                * On linux you cannot set the priority of a thread in the non real time\r
+                * scheduling groups.  You can set the priority of the process.  In\r
+                * windows BELOW_NORMAL represents a 1/8th drop in priority and this would\r
+                * be 20 * 1/8 on linux or about 2.5\r
+                */\r
+               setpriority( PRIO_PROCESS, 0, 2 );\r
+       #endif\r
+\r
+       pthread_attr_t attr;\r
+       pthread_attr_init(&attr);\r
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);\r
+       #ifdef _WIN32\r
+       sched_param param;\r
+       param.sched_priority = THREAD_PRIORITY_BELOW_NORMAL;\r
+       pthread_attr_setschedparam (&attr, &param);\r
+       #endif\r
+       // else set it to 5 or something (for linux)?\r
+\r
+       bool pausing = false;\r
+\r
+       uint32 nHashIndex;\r
+       for (nHashIndex = 0; nHashIndex < vHash.size(); nHashIndex++)\r
+       {\r
+               #ifdef _WIN32\r
+               if (_kbhit())\r
+               {\r
+                       int ch = _getch();\r
+                       ch = toupper(ch);\r
+                       if (ch == 'P')\r
+                       {\r
+                               pausing = true;\r
+                               printf( "\nPausing, press P again to continue... ");\r
+                               \r
+                               timeval tv;\r
+                               timeval tv2;\r
+                               timeval final;\r
+                               gettimeofday( &tv, NULL );\r
+\r
+                               while (pausing)\r
+                               {\r
+                                       if (_kbhit())\r
+                                       {\r
+                                               ch = _getch();\r
+                                               ch = toupper(ch);\r
+                                               if (ch == 'P')\r
+                                               {\r
+                                                       printf( " [Continuing]\n");\r
+                                                       pausing = false;\r
+                                                       gettimeofday( &tv2, NULL );\r
+                                                       final = sub_timeofday( tv2, tv );\r
+                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                                       m_fTotalCryptanalysisTime -= fTime;\r
+                                               }\r
+                                       }\r
+                                       Sleep(500);\r
+                               }\r
+                       }\r
+                       else\r
+                       {\r
+                               printf( "\nPress 'P' to pause...\n");\r
+                       }\r
+               }\r
+               #else\r
+               int c = tty_getchar();\r
+               if (c >= 0) {\r
+                       tty_flush();\r
+                       if (c==112) { // = p\r
+                               pausing = true;\r
+                               printf( "\nPausing, press 'p' again to continue... ");\r
+\r
+                               timeval tv;\r
+                               timeval tv2;\r
+                               timeval final;\r
+                               gettimeofday( &tv, NULL );\r
+\r
+                               while (pausing)\r
+                               {\r
+                                       if ((c = tty_getchar()) >= 0)\r
+                                       {\r
+                                               tty_flush();\r
+                                               if (c == 112)\r
+                                               {\r
+                                                       printf( " [Continuing]\n");\r
+                                                       pausing = false;\r
+                                                       gettimeofday( &tv2, NULL );\r
+                                                       final = sub_timeofday( tv2, tv );\r
+                                                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                                       m_fTotalCryptanalysisTime -= fTime;\r
+                                               }\r
+                                       }\r
+                                       usleep(500*1000);\r
+                               }\r
+                       }\r
+                       else {\r
+                               printf( "\nPress 'p' to pause...\n");\r
+                       }\r
+               }\r
+               #endif\r
+               unsigned char TargetHash[MAX_HASH_LEN];\r
+               int nHashLen;\r
+               ParseHash(vHash[nHashIndex], TargetHash, nHashLen);\r
+               if (nHashLen != CChainWalkContext::GetHashLen())\r
+                       printf("debug: nHashLen mismatch\n");\r
+\r
+               // Request ChainWalk\r
+               bool fNewlyGenerated;\r
+//             printf("Requesting walk...");\r
+                \r
+\r
+               uint64* pStartPosIndexE = m_cws.RequestWalk(TargetHash,\r
+                                                                                                       nHashLen,\r
+                                                                                                       CChainWalkContext::GetHashRoutineName(),\r
+                                                                                                       CChainWalkContext::GetPlainCharsetName(),\r
+                                                                                                       CChainWalkContext::GetPlainLenMin(),\r
+                                                                                                       CChainWalkContext::GetPlainLenMax(),\r
+                                                                                                       CChainWalkContext::GetRainbowTableIndex(),\r
+                                                                                                       nRainbowChainLen,\r
+                                                                                                       fNewlyGenerated,\r
+                                                                                                       debug,\r
+                                                                                                       sPrecalcPathName);\r
+//             printf("done!\n");\r
+//             printf("debug: using %s walk for %s\n", fNewlyGenerated ? "newly generated" : "existing",\r
+//                                                                                             vHash[nHashIndex].c_str());\r
+\r
+               if (fNewlyGenerated)\r
+               {\r
+                       timeval tv;\r
+                       timeval tv2;\r
+                       timeval final;\r
+\r
+                       gettimeofday( &tv, NULL );\r
+\r
+                       printf("Pre-calculating hash %lu of %lu.%-20s\r", \r
+                               (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+                       threadPool.clear();\r
+                       pThreads.clear();\r
+                       \r
+                       uint32 thread_ID;\r
+                       for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+                       {\r
+                               rcrackiThread* r_Thread = new rcrackiThread(TargetHash, thread_ID, nRainbowChainLen, maxThreads, pStartPosIndexE);\r
+                               if (r_Thread)\r
+                               {\r
+                                       pthread_t pThread;\r
+                                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+                                       if( returnValue != 0 )\r
+                                       {\r
+                                               printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               pThreads.push_back(pThread);\r
+                                       }\r
+\r
+                                       threadPool.push_back(r_Thread);\r
+                               }\r
+                               else \r
+                               {\r
+                                       printf("r_Thread creation failed!\n");\r
+                               }\r
+                       }\r
+                       \r
+                       //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+                       \r
+                       for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+                       {\r
+                               pthread_t pThread = pThreads[thread_ID];\r
+                               int returnValue = pthread_join(pThread, NULL);\r
+                               if( returnValue != 0 )\r
+                               {\r
+                                       printf("pThread join failed, returnValue: %d\n", returnValue);\r
+                               }\r
+                                       \r
+                               rcrackiThread* rThread = threadPool[thread_ID];\r
+                               nChainWalkStep += rThread->GetChainWalkStep();\r
+                               delete rThread;\r
+                       }\r
+\r
+                       m_cws.StoreToFile(pStartPosIndexE, TargetHash, nHashLen);\r
+                       gettimeofday( &tv2, NULL );\r
+                       final = sub_timeofday( tv2, tv );\r
+                       \r
+                       float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+\r
+                       m_fTotalPrecalculationTime += fTime;\r
+                       m_fTotalCryptanalysisTime -= fTime;\r
+\r
+                       //printf("\npStartPosIndexE[0]: %s\n", uint64tostr(pStartPosIndexE[0]).c_str());\r
+                       //printf("\npStartPosIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pStartPosIndexE[nRainbowChainLen-2]).c_str());\r
+\r
+                       printf("%-50s\r", "");\r
+\r
+                       if ( debug )\r
+                               printf("pre-calculation time: %.2f s\n", fTime);\r
+               }\r
+\r
+               threadPool.clear();\r
+               pThreads.clear();\r
+\r
+               //printf("Checking false alarms for hash %d of %d.\t\t\r", nHashIndex+1, vHash.size());\r
+               printf("Checking false alarms for hash %lu of %lu.%-20s\r",\r
+                       (unsigned long)nHashIndex+1, (unsigned long)vHash.size(), "");\r
+\r
+               int i;\r
+               for (i = 0; i < maxThreads; i++)\r
+               {\r
+                       rcrackiThread* r_Thread = new rcrackiThread(TargetHash);\r
+                       threadPool.push_back(r_Thread);\r
+               }\r
+\r
+               uint32 thread_ID = 0;\r
+               int nPos;\r
+               for (nPos = nRainbowChainLen - 2; nPos >= 0; nPos--)\r
+               {\r
+                       uint64 nIndexEOfCurPos = pStartPosIndexE[nPos];\r
+               \r
+                       // Search matching nIndexE\r
+                       RainbowChain *pChainFound = BinarySearch(pChain, nRainbowChainCount, nIndexEOfCurPos, pIndex, nIndexSize, nChainStart);\r
+                       if (pChainFound != NULL) // For perfected indexed tables we only recieve 1 result (huge speed increase!)\r
+                       {\r
+                               rcrackiThread* rThread = threadPool[thread_ID];\r
+                               rThread->AddAlarmCheck(pChainFound, nPos);\r
+                               if (thread_ID < (unsigned long)maxThreads - 1 ) {\r
+                                       thread_ID++;\r
+                               } else {\r
+                                       thread_ID = 0;\r
+                               }\r
+                       }\r
+               }\r
+\r
+               for (thread_ID = 0; thread_ID < (unsigned long)maxThreads; thread_ID++)\r
+               {\r
+                       rcrackiThread* r_Thread = threadPool[thread_ID];\r
+                       pthread_t pThread;\r
+\r
+                       int returnValue = pthread_create( &pThread, &attr, rcrackiThread::rcrackiThreadStaticEntryPointPthread, (void *) r_Thread);\r
+\r
+                       if( returnValue != 0 )\r
+                       {\r
+                               printf("pThread creation failed, returnValue: %d\n", returnValue);\r
+                       }\r
+                       else\r
+                       {\r
+                               pThreads.push_back(pThread);\r
+                       }\r
+               }\r
+               \r
+               //printf("%d r_Threads created\t\t\n", threadPool.size());\r
+\r
+               bool foundHashInThread = false;\r
+               for (thread_ID = 0; thread_ID < threadPool.size(); thread_ID++)\r
+               {\r
+                       rcrackiThread* rThread = threadPool[thread_ID];\r
+                       pthread_t pThread = pThreads[thread_ID];\r
+\r
+                       int returnValue = pthread_join(pThread, NULL);\r
+                       if( returnValue != 0 )\r
+                       {\r
+                               printf("pThread join failed, returnValue: %d\n", returnValue);\r
+                       }\r
+\r
+                       nChainWalkStepDueToFalseAlarm += rThread->GetChainWalkStepDueToFalseAlarm();\r
+                       nFalseAlarm += rThread->GetnFalseAlarm();\r
+\r
+                       if (rThread->FoundHash() && !foundHashInThread) {\r
+                               //printf("\t\t\t\t\t\t\r");\r
+                               printf("%-50s\r", "");\r
+                               printf("plaintext of %s is %s\n", rThread->GetHash().c_str(), rThread->GetPlain().c_str());\r
+                               if (writeOutput)\r
+                               {\r
+                                       if (!writeResultLineToFile(outputFile, rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary()))\r
+                                               printf("Couldn't write this result to file!\n");\r
+                               }\r
+                               hs.SetPlain(rThread->GetHash(), rThread->GetPlain(), rThread->GetBinary());\r
+                               \r
+                               FILE* file = fopen(sSessionPathName.c_str(), "a");\r
+                               if (file!=NULL)\r
+                               {\r
+                                       string buffer = "sHash=" + rThread->GetHash() + ":" + rThread->GetBinary() + ":" + rThread->GetPlain() + "\n";\r
+                                       fputs (buffer.c_str(), file);\r
+                                       fclose (file);\r
+                               }\r
+\r
+                               m_cws.DiscardWalk(pStartPosIndexE);\r
+                               foundHashInThread = true;\r
+                       }\r
+                       //pthread\r
+                       delete rThread;\r
+               }\r
+\r
+               pThreads.clear();\r
+               threadPool.clear();\r
+\r
+               //printf("\t\t\t\t\r");\r
+               //printf("pChainFounds: %d\n", pChainsFound.size());\r
+//NEXT_HASH:;\r
+       }\r
+       //printf("\t\t\t\t\t\t\t\r");\r
+       printf("%-50s\r", "");\r
+       pThreads.clear();\r
+       threadPool.clear();\r
+       pthread_attr_destroy(&attr);\r
+\r
+       //printf("debug: chain walk step: %d\n", nChainWalkStep);\r
+       //printf("debug: false alarm: %d\n", nFalseAlarm);\r
+       //printf("debug: chain walk step due to false alarm: %d\n", nChainWalkStepDueToFalseAlarm);\r
+\r
+       m_nTotalChainWalkStep += nChainWalkStep;\r
+       m_nTotalFalseAlarm += nFalseAlarm;\r
+       m_nTotalChainWalkStepDueToFalseAlarm += nChainWalkStepDueToFalseAlarm;\r
+}\r
+\r
+void CCrackEngine::SearchRainbowTable(string sPathName, CHashSet& hs)\r
+{\r
+       // Did we already go through this file in this session?\r
+       if (resumeSession)\r
+       {\r
+               vector<string> sessionFinishedPathNames;\r
+               if (ReadLinesFromFile(sProgressPathName.c_str(), sessionFinishedPathNames))\r
+               {\r
+                       uint32 i;\r
+                       for (i = 0; i < sessionFinishedPathNames.size(); i++)\r
+                       {\r
+                               if (sessionFinishedPathNames[i] == sPathName)\r
+                               {\r
+                                       printf("Skipping %s\n", sPathName.c_str());\r
+                                       return;\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       // FileName\r
+#ifdef _WIN32\r
+       string::size_type nIndex = sPathName.find_last_of('\\');\r
+#else\r
+       string::size_type nIndex = sPathName.find_last_of('/');\r
+#endif\r
+       string sFileName;\r
+       if (nIndex != string::npos)\r
+               sFileName = sPathName.substr(nIndex + 1);\r
+       else\r
+               sFileName = sPathName;\r
+\r
+       // Info\r
+       printf("%s:\n", sFileName.c_str());\r
+\r
+       // Setup\r
+       int nRainbowChainLen, nRainbowChainCount;\r
+       if (!CChainWalkContext::SetupWithPathName(sPathName, nRainbowChainLen, nRainbowChainCount))\r
+               return;\r
+       //printf("keyspace: %llu\n", CChainWalkContext::GetPlainSpaceTotal());\r
+       // Already finished?\r
+       if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
+       {\r
+               printf("this table contains hashes with length %d only\n", CChainWalkContext::GetHashLen());\r
+               return;\r
+       }\r
+\r
+       // Open\r
+       FILE* file = fopen(sPathName.c_str(), "rb");\r
+       if (file != NULL)\r
+       {\r
+               // File length check\r
+               bool doOldFormat = CChainWalkContext::isOldFormat();\r
+               bool doRti2Format = CChainWalkContext::isRti2Format();\r
+               uint32 sizeOfChain;\r
+               bool fVerified = false;\r
+               long nFileLen = GetFileLen(file);\r
+\r
+               if (doOldFormat)\r
+                       sizeOfChain = 16;\r
+               else\r
+                       sizeOfChain = 8;\r
+\r
+               //if (nFileLen % 8 != 0 || nRainbowChainCount * 8 != nFileLen)\r
+               if ( ( (unsigned long)nFileLen % sizeOfChain != 0 || nRainbowChainCount * sizeOfChain != (unsigned long)nFileLen) && doRti2Format == false )\r
+                       printf("file length mismatch\n");\r
+               else\r
+               {\r
+                       fseek(file, 0, SEEK_SET);\r
+                       timeval tv;\r
+                       timeval tv2;\r
+                       timeval final;\r
+\r
+                       unsigned int bytesForChainWalkSet = hs.GetStatHashTotal() * (nRainbowChainLen-1) * 8;\r
+                       if (debug) printf("Debug: Saving %u bytes of memory for chainwalkset.\n", bytesForChainWalkSet);\r
+\r
+                       uint64 nAllocatedSize;\r
+\r
+                       if (doRti2Format || doOldFormat)\r
+                       {\r
+                               RTI2Reader *pReader = NULL;\r
+\r
+                               if(doRti2Format) {\r
+                                       pReader = new RTI2Reader(sPathName);\r
+\r
+                               }\r
+\r
+                               if (debug)\r
+                               {\r
+                                       if ( doOldFormat )\r
+                                               printf("Debug: This is a table in the old .rt format.\n");\r
+                                       else if ( doRti2Format )\r
+                                               printf("Debug: This is a table in the .rti2 format.\n");\r
+                               }\r
+\r
+                               static CMemoryPool mp(bytesForChainWalkSet, debug, maxMem);\r
+                               RainbowChainO* pChain = NULL;\r
+                               if(doRti2Format) {\r
+                                       pChain = (RainbowChainO*)mp.Allocate(pReader->GetChainsLeft() * 16, nAllocatedSize);\r
+                               } else {\r
+                                       pChain = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);\r
+                               }\r
+                               #if defined(_WIN32) && !defined(__GNUC__)\r
+                                       if (debug) printf("Allocated %I64 bytes, filelen %ld\n", nAllocatedSize, nFileLen);\r
+                               #else\r
+                                       if (debug) printf("Allocated %llu bytes, filelen %ld\n", nAllocatedSize, nFileLen);\r
+                               #endif\r
+\r
+                               if (pChain != NULL)\r
+                               {\r
+                                       nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary\r
+\r
+                                       //fseek(file, 0, SEEK_SET);\r
+                                       //bool fVerified = false;\r
+                                       while (true)    // Chunk read loop\r
+                                       {\r
+                                               if (ftell(file) == nFileLen)\r
+                                                       break;\r
+\r
+                                               // Load table chunk\r
+                                               if (debug) printf("reading...\n");\r
+                                               unsigned int nDataRead = 0;\r
+                                               gettimeofday( &tv, NULL );\r
+                                               if ( doRti2Format )\r
+                                               {\r
+                                                       nDataRead = nAllocatedSize / 16;\r
+                                                       if(pReader->GetChainsLeft() <= 0) // No more data\r
+                                                               break; \r
+                                                       pReader->ReadChains(nDataRead, pChain);\r
+\r
+                                                       nDataRead *= 8; // Convert from chains read to bytes\r
+                                               }\r
+                                               else\r
+                                               {\r
+                                                       nDataRead = fread(pChain, 1, nAllocatedSize, file);\r
+                                               }\r
+                                               gettimeofday( &tv2, NULL );\r
+                                               final = sub_timeofday( tv2, tv );\r
+\r
+                                               float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                               printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
+                                               m_fTotalDiskAccessTime += fTime;\r
+\r
+                                               int nRainbowChainCountRead = nDataRead / 16;\r
+\r
+                                               if(doRti2Format) {\r
+                                                       nRainbowChainCountRead = nDataRead / 8;\r
+                                               }\r
+\r
+                                               // Verify table chunk\r
+                                               if (!fVerified)\r
+                                               {\r
+                                                       printf("verifying the file...\n");\r
+\r
+                                                       // Chain length test\r
+                                                       int nIndexToVerify = nRainbowChainCountRead / 2;\r
+                                                       CChainWalkContext cwc;\r
+                                                       cwc.SetIndex(pChain[nIndexToVerify].nIndexS);\r
+                                                       int nPos;\r
+                                                       for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
+                                                       {\r
+                                                               cwc.IndexToPlain();\r
+                                                               cwc.PlainToHash();\r
+                                                               cwc.HashToIndex(nPos);\r
+                                                       }\r
+                                                       if (cwc.GetIndex() != pChain[nIndexToVerify].nIndexE)\r
+                                                       {\r
+                                                               printf("rainbow chain length verify fail\n");\r
+                                                               break;\r
+                                                       }\r
+\r
+                                                       // Chain sort test\r
+                                                       int i;\r
+                                                       for (i = 0; i < nRainbowChainCountRead - 1; i++)\r
+                                                       {\r
+                                                               if (pChain[i].nIndexE > pChain[i + 1].nIndexE)\r
+                                                                       break;\r
+                                                       }\r
+                                                       if (i != nRainbowChainCountRead - 1)\r
+                                                       {\r
+                                                               printf("this file is not sorted\n");\r
+                                                               break;\r
+                                                       }\r
+\r
+                                                       fVerified = true;\r
+                                               }\r
+\r
+                                               // Search table chunk\r
+                                               gettimeofday( &tv, NULL );\r
+                                               SearchTableChunkOld(pChain, nRainbowChainLen, nRainbowChainCountRead, hs);\r
+                                               gettimeofday( &tv2, NULL );\r
+                                               final = sub_timeofday( tv2, tv );\r
+                                               fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                               printf("cryptanalysis time: %.2f s\n", fTime);\r
+                                               m_fTotalCryptanalysisTime += fTime;\r
+\r
+                                               // Already finished?\r
+                                               if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
+                                                       break;\r
+\r
+/*\r
+       // XXX eliminated by PB - check correctness\r
+                                               // finished the current table\r
+                                               if( doRti2Format && nDataToRead > (nDataRead / 8) )\r
+                                               {\r
+                                                       delete pReader;\r
+                                                       break;\r
+                                               }\r
+*/\r
+                                       }\r
+                               }\r
+                               else\r
+                                       printf("memory allocation fail\n");\r
+                               \r
+                               //delete pChain;\r
+                       }\r
+                       else\r
+                       {\r
+                               static CMemoryPool mpIndex(bytesForChainWalkSet, debug, maxMem);\r
+                               uint64 nAllocatedSizeIndex;\r
+\r
+                               //int nIndexSize = 0;\r
+                               //IndexChain *pIndex = NULL;\r
+\r
+                               FILE* fIndex = fopen(((string)(sPathName + string(".index"))).c_str(), "rb");\r
+                               if(fIndex != NULL)\r
+                               {\r
+                                       // File length check\r
+                                       long nFileLenIndex = GetFileLen(fIndex);\r
+                                       //unsigned int nRows = nFileLenIndex / 11;\r
+                                       //unsigned int nSize = nRows * sizeof(IndexChain);\r
+                                       //printf("Debug: 8\n");\r
+                                       if (nFileLenIndex % 11 != 0)\r
+                                               printf("index file length mismatch (%ld bytes)\n", nFileLenIndex);\r
+                                       else\r
+                                       {\r
+                                               //printf("index nSize: %d\n", nSize);\r
+                                               //pIndex = (IndexChain*)new unsigned char[nSize];\r
+                                               IndexChain *pIndex = (IndexChain*)mpIndex.Allocate(nFileLenIndex, nAllocatedSizeIndex);\r
+                                               #ifdef _WIN32\r
+                                                       if (debug) printf("Debug: Allocated %I64u bytes for index with filelen %ld\n", nAllocatedSizeIndex, nFileLenIndex);\r
+                                               #else\r
+                                                       if (debug) printf("Debug: Allocated %llu bytes for index with filelen %ld\n", nAllocatedSizeIndex, nFileLenIndex);\r
+                                               #endif\r
+                               \r
+                                               static CMemoryPool mp(bytesForChainWalkSet + nAllocatedSizeIndex, debug, maxMem);\r
+                                               \r
+                                               if (pIndex != NULL && nAllocatedSizeIndex > 0)\r
+                                               {\r
+                                                       nAllocatedSizeIndex = nAllocatedSizeIndex / sizeof(IndexChain) * sizeof(IndexChain);            // Round to sizeOfIndexChain boundary\r
+                                               \r
+                                                       fseek(fIndex, 0, SEEK_SET);\r
+\r
+                                                       while ( ftell(fIndex) != nFileLenIndex )        // Index chunk read loop\r
+                                                       {\r
+                                                               // Load index chunk\r
+#ifdef _WIN32\r
+                                                               if (debug) printf("Debug: Setting index to 0x00 in memory, %I64u bytes\n", nAllocatedSizeIndex);\r
+#else\r
+                                                               if (debug) printf("Debug: Setting index to 0x00 in memory, %llu bytes\n", nAllocatedSizeIndex);\r
+#endif\r
+                                                               memset(pIndex, 0x00, nAllocatedSizeIndex);\r
+                                                               printf("reading index... ");\r
+                                                               gettimeofday( &tv, NULL );\r
+                                                               unsigned int nDataRead = fread(pIndex, 1, nAllocatedSizeIndex, fIndex);\r
+                                                               gettimeofday( &tv2, NULL );\r
+                                                               final = sub_timeofday( tv2, tv );\r
+\r
+                                                               float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                                               printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
+                                                               m_fTotalDiskAccessTime += fTime;\r
+                                                       \r
+                                                               //nIndexSize = nFileLenIndex / 11;\r
+                                                               int nIndexChainCountRead = nDataRead / sizeof(IndexChain);\r
+                                                               //fclose(fIndex);\r
+                                                               unsigned int nCoveredRainbowTableChains = 0;\r
+                                                               for(int i = 0; i < nIndexChainCountRead; i++)\r
+                                                               {\r
+                                                                       nCoveredRainbowTableChains += pIndex[i].nChainCount;\r
+                                                               }\r
+\r
+                                                               //RainbowChain* pChain = (RainbowChain*)mp.Allocate(nFileLen, nAllocatedSize);\r
+                                                               RainbowChain* pChain = (RainbowChain*)mp.Allocate(nCoveredRainbowTableChains * sizeOfChain, nAllocatedSize);\r
+                                                               #ifdef _WIN32\r
+                                                                       if (debug) printf("Debug: Allocated %I64u bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);\r
+                                                               #else\r
+                                                                       if (debug) printf("Debug: Allocated %llu bytes for %u chains, filelen %lu\n", nAllocatedSize, nCoveredRainbowTableChains, (unsigned long)nFileLen);\r
+                                                               #endif\r
+\r
+                                                               if (pChain != NULL && nAllocatedSize > 0)\r
+                                                               {\r
+                                                                       nAllocatedSize = nAllocatedSize / sizeOfChain * sizeOfChain;            // Round to sizeOfChain boundary\r
+\r
+                                                                       //fseek(file, 0, SEEK_SET);\r
+                                                                       //bool fVerified = false;\r
+                                                                       uint32 nProcessedChains = 0;\r
+                                                                       while ( ftell(file) != nFileLen \r
+                                                                               && nProcessedChains < nCoveredRainbowTableChains )      // Chunk read loop\r
+                                                                       {\r
+                                                                               // Load table chunk\r
+                                                                               if (debug) printf("Debug: Setting pChain to 0x00 in memory\n");\r
+                                                                               memset(pChain, 0x00, nAllocatedSize);\r
+                                                                               printf("reading table... ");\r
+                                                                               gettimeofday( &tv, NULL );\r
+                                                                               unsigned int nDataRead = fread(pChain, 1, nAllocatedSize, file);\r
+                                                                               gettimeofday( &tv2, NULL );\r
+                                                                               final = sub_timeofday( tv2, tv );\r
+\r
+                                                                               float fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                                                               printf("%u bytes read, disk access time: %.2f s\n", nDataRead, fTime);\r
+                                                                               m_fTotalDiskAccessTime += fTime;\r
+                                                                               int nRainbowChainCountRead = nDataRead / sizeOfChain;\r
+                                                                               // Verify table chunk (Too lazy to implement this)\r
+                                                                               \r
+                                                                               if (!fVerified)\r
+                                                                               {\r
+                                                                                       printf("verifying the file... ");\r
+\r
+                                                                                       // Chain length test\r
+                                                                                       int nIndexToVerify = nRainbowChainCountRead / 2;\r
+                                                                                       CChainWalkContext cwc;\r
+                                                                                       uint64 nIndexS;\r
+                                                                                       nIndexS = pChain[nIndexToVerify].nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes\r
+\r
+                                                                                       //printf("nIndexS: %s\n", uint64tostr(nIndexS).c_str());\r
+                                                                                       cwc.SetIndex(nIndexS);\r
+                                                                                       \r
+                                                                                       int nPos;\r
+                                                                                       for (nPos = 0; nPos < nRainbowChainLen - 1; nPos++)\r
+                                                                                       {\r
+                                                                                               cwc.IndexToPlain();\r
+                                                                                               cwc.PlainToHash();\r
+                                                                                               cwc.HashToIndex(nPos);\r
+                                                                                       }\r
+\r
+                                                                                       uint64 nEndPoint = 0;\r
+\r
+                                                                                       //for(int i = 0; i < nIndexSize; i++)\r
+                                                                                       for(int i = 0; i < nIndexChainCountRead; i++)\r
+                                                                                       {\r
+                                                                                               if(nIndexToVerify >= pIndex[i].nFirstChain && nIndexToVerify < pIndex[i].nFirstChain + pIndex[i].nChainCount) // We found the matching index\r
+                                                                                               { // Now we need to seek nIndexToVerify into the chains\r
+                                                                                                       nEndPoint += (pIndex[i].nPrefix & 0x000000FFFFFFFFFFULL) << 16; // & 0x000000FFFFFFFFFFULL for first 5 bytes\r
+                                                                                                       //printf("nPrefix: %s\n", uint64tostr(pIndex[i].nPrefix & 0x000000FFFFFFFFFF).c_str());\r
+                                                                                                       //printf("nFirstChain: %d\n", pIndex[i].nFirstChain);\r
+                                                                                                       //printf("nChainCount: %d\n", pIndex[i].nChainCount);\r
+                                                                                                       nEndPoint += pChain[nIndexToVerify].nIndexE;\r
+                                                                                                       break;\r
+                                                                                               }\r
+                                                                                       }\r
+\r
+                                                                                       if (cwc.GetIndex() != nEndPoint)\r
+                                                                                       {\r
+                                                                                               printf("rainbow chain length verify fail\n");\r
+                                                                                               break;\r
+                                                                                       }\r
+\r
+                                                                                       fVerified = true;\r
+                                                                                       printf("ok\n");\r
+                                                                               }\r
+\r
+                                                                               // Search table chunk\r
+                                                                               gettimeofday( &tv, NULL );\r
+                                                                               float preTime = m_fTotalCryptanalysisTime;\r
+\r
+                                                                               SearchTableChunk(pChain, nRainbowChainLen, nRainbowChainCountRead, hs, pIndex, nIndexChainCountRead, nProcessedChains);\r
+                                                                               float postTime = m_fTotalCryptanalysisTime;\r
+                                                                               gettimeofday( &tv2, NULL );\r
+                                                                               final = sub_timeofday( tv2, tv );\r
+\r
+                                                                               fTime = 1.0f * final.tv_sec + 1.0f * final.tv_usec / 1000000;\r
+                                                                               printf("cryptanalysis time: %.2f s\n", fTime + postTime - preTime);\r
+                                                                               m_fTotalCryptanalysisTime += fTime;\r
+                                                                               nProcessedChains += nRainbowChainCountRead;\r
+                                                                               // Already finished?\r
+                                                                               if (!hs.AnyHashLeftWithLen(CChainWalkContext::GetHashLen()))\r
+                                                                                       break;\r
+                                                                       }\r
+                                                               }\r
+                                                               else printf("memory allocation failed for rainbow table\n");\r
+\r
+                                                               //delete pChain;\r
+                                                       }\r
+                                               }\r
+                                               else printf("memory allocation failed for index\n");\r
+                                       }               \r
+                               }\r
+                               else \r
+                               {\r
+                                       printf("Can't load index\n");\r
+                                       return;\r
+                               }\r
+                               fclose(fIndex);\r
+                               \r
+                               //delete pIndex;\r
+                       }\r
+               }\r
+               fclose(file);\r
+\r
+               if (debug) printf("Debug: writing progress to %s\n", sProgressPathName.c_str());\r
+               FILE* file = fopen(sProgressPathName.c_str(), "a");\r
+               if (file!=NULL)\r
+               {\r
+                       string buffer = sPathName + "\n";\r
+                       fputs (buffer.c_str(), file);\r
+                       fclose (file);\r
+               }\r
+       }\r
+       else\r
+               printf("can't open file\n");\r
+}\r
+\r
+void CCrackEngine::Run(vector<string> vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug)\r
+{\r
+#ifndef _WIN32\r
+       tty_init();\r
+#endif\r
+       resumeSession = resume;\r
+       debug = bDebug;\r
+\r
+       maxThreads = i_maxThreads;\r
+       maxMem = i_maxMem;\r
+       // Reset statistics\r
+       ResetStatistics();\r
+\r
+       // Sort vPathName (CChainWalkSet need it)\r
+       uint32 i, j;\r
+       for (i = 0; i < vPathName.size() - 1; i++)\r
+               for (j = 0; j < vPathName.size() - i - 1; j++)\r
+               {\r
+                       if (vPathName[j] > vPathName[j + 1])\r
+                       {\r
+                               string sTemp;\r
+                               sTemp = vPathName[j];\r
+                               vPathName[j] = vPathName[j + 1];\r
+                               vPathName[j + 1] = sTemp;\r
+                       }\r
+               }\r
+\r
+       // Run\r
+       for (i = 0; i < vPathName.size() && hs.AnyhashLeft(); i++)\r
+       {\r
+               SearchRainbowTable(vPathName[i], hs);\r
+               printf("\n");\r
+       }\r
+\r
+       // delete precalc files\r
+       if (!keepPrecalcFiles)\r
+               m_cws.removePrecalcFiles();\r
+\r
+#ifndef _WIN32\r
+       tty_done();\r
+#endif\r
+}\r
+\r
+void CCrackEngine::setOutputFile(string sPathName)\r
+{\r
+       writeOutput = true;\r
+       outputFile = sPathName;\r
+}\r
+\r
+void CCrackEngine::setSession(string sSession, string sProgress, string sPrecalc, bool keepPrecalc)\r
+{\r
+       sSessionPathName = sSession;\r
+       sProgressPathName = sProgress;\r
+       sPrecalcPathName = sPrecalc;\r
+       keepPrecalcFiles = keepPrecalc;\r
+}\r
+\r
+float CCrackEngine::GetStatTotalDiskAccessTime()\r
+{\r
+       return m_fTotalDiskAccessTime;\r
+}\r
+/*float CCrackEngine::GetWastedTime()\r
+{\r
+       return m_fIndexTime;\r
+}*/\r
+float CCrackEngine::GetStatTotalCryptanalysisTime()\r
+{\r
+       return m_fTotalCryptanalysisTime;\r
+}\r
+\r
+float CCrackEngine::GetStatTotalPrecalculationTime()\r
+{\r
+       return m_fTotalPrecalculationTime;\r
+}\r
+\r
+int CCrackEngine::GetStatTotalChainWalkStep()\r
+{\r
+       return m_nTotalChainWalkStep;\r
+}\r
+\r
+int CCrackEngine::GetStatTotalFalseAlarm()\r
+{\r
+       return m_nTotalFalseAlarm;\r
+}\r
+\r
+int CCrackEngine::GetStatTotalChainWalkStepDueToFalseAlarm()\r
+{\r
+       return m_nTotalChainWalkStepDueToFalseAlarm;\r
+}\r
index db22aeba8386fbcc48af69287ebb31bf441ec25e..4a4cbbb674856b0fd8bc5978984e6726d1f6e482 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- *
- * Changes: not using OpenSSL routines the slow way anymore, as suggested by jci.
- */
-
-#include "HashAlgorithm.h"
-
-#include "Public.h"
-
-#include <openssl/des.h>
-//#include <openssl/md2.h>
-#include <openssl/md4.h>
-#include <openssl/sha.h>
-//#include <openssl/ripemd.h>
-#include "fast_md5.h"
-#include "md4.h"
-//#include "sha1.h"
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma comment(lib, "libeay32.lib")
-#endif
-
-#ifdef __NetBSD__
-       #include <des.h>
-#endif
-
-#define MSCACHE_HASH_SIZE 16
-void setup_des_key(unsigned char key_56[], des_key_schedule &ks)
-{
-       des_cblock key;
-
-       key[0] = key_56[0];
-       key[1] = (key_56[0] << 7) | (key_56[1] >> 1);
-       key[2] = (key_56[1] << 6) | (key_56[2] >> 2);
-       key[3] = (key_56[2] << 5) | (key_56[3] >> 3);
-       key[4] = (key_56[3] << 4) | (key_56[4] >> 4);
-       key[5] = (key_56[4] << 3) | (key_56[5] >> 5);
-       key[6] = (key_56[5] << 2) | (key_56[6] >> 6);
-       key[7] = (key_56[6] << 1);
-
-       //des_set_odd_parity(&key);
-       des_set_key(&key, ks);
-}
-
-void HashLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       /*
-       unsigned char data[7] = {0};
-       memcpy(data, pPlain, nPlainLen > 7 ? 7 : nPlainLen);
-       */
-
-       int i;
-       for (i = nPlainLen; i < 7; i++)
-               pPlain[i] = 0;
-
-       static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
-       des_key_schedule ks;
-       //setup_des_key(data, ks);
-       setup_des_key(pPlain, ks);
-       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pHash, ks, DES_ENCRYPT);
-}
-
-void HashLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       unsigned char pass[14];
-       unsigned char pre_lmresp[21];
-       static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
-       static unsigned char spoofed_challange[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; 
-       des_key_schedule ks;
-
-       memset (pass,0,sizeof(pass));
-       memset (pre_lmresp,0,sizeof(pre_lmresp));
-
-       memcpy (pass,pPlain, nPlainLen);
-
-       setup_des_key(pass, ks);
-       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pre_lmresp, ks, DES_ENCRYPT);
-
-       setup_des_key(&pass[7], ks);
-       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)&pre_lmresp[8], ks, DES_ENCRYPT);
-
-       setup_des_key(pre_lmresp, ks);
-       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);
-
-       setup_des_key(&pre_lmresp[7], ks);
-       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[8], ks, DES_ENCRYPT);
-
-       setup_des_key(&pre_lmresp[14], ks);
-       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[16], ks, DES_ENCRYPT);
-
-} 
-
-void HashHALFLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{      
-       unsigned char pre_lmresp[8];
-       static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
-       static unsigned char salt[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};
-
-       des_key_schedule ks;
-       unsigned char plain[8] = {0};   
-       memcpy(plain, pPlain, nPlainLen);
-       setup_des_key(plain, ks);
-       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pre_lmresp, ks, DES_ENCRYPT);
-
-       setup_des_key(pre_lmresp, ks);
-       des_ecb_encrypt((des_cblock*)salt, (des_cblock*)pHash, ks, DES_ENCRYPT);
-} 
-
-
-
-void HashNTLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       unsigned char UnicodePlain[MAX_PLAIN_LEN];
-       static unsigned char spoofed_challange[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; 
-       
-       int len = (nPlainLen < 127) ? nPlainLen : 127;
-       int i;
-       
-       for (i = 0; i < len; i++)
-       {
-       UnicodePlain[i * 2] = pPlain[i];
-       UnicodePlain[i * 2 + 1] = 0x00;
-       }
-       
-       des_key_schedule ks;
-       unsigned char lm[21];
-       
-       /*MD4_CTX ctx;
-       MD4_Init(&ctx);
-       MD4_Update(&ctx, UnicodePlain, len * 2);
-       MD4_Final(lm, &ctx);  */
-       MD4_NEW(UnicodePlain, len * 2, lm);
-       
-       //MD4(UnicodePlain, len * 2, lm);
-       lm[16] = lm[17] = lm[18] = lm[19] = lm[20] = 0;
-       
-       setup_des_key(lm, ks);
-       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);
-       
-       setup_des_key(&lm[7], ks);
-       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[8], ks, DES_ENCRYPT);
-       
-       setup_des_key(&lm[14], ks);
-       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[16], ks, DES_ENCRYPT);
-}
-
-void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       char ToEncrypt[256];
-       char temp[256];
-       char username[256];
-
-       DES_cblock iv,iv2;
-       DES_key_schedule ks1,ks2;
-       unsigned char deskey_fixed[]={ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
-       int i,j;
-#if defined(_WIN32) && !defined(__GNUC__)
-       strcpy_s(username, sizeof(username), "SYS");
-#else
-       strcpy(username, "SYS");
-#endif
-       int userlen = 3;
-#if defined(_WIN32) && !defined(__GNUC__)
-       _strupr((char*) pPlain);
-#else
-       strupr((char*) pPlain);
-#endif
-       memset (ToEncrypt,0,sizeof(ToEncrypt));
-
-       for (i=1,j=0; j<userlen; i++,j++)
-       {
-               ToEncrypt[i] = username[j];
-               i++;
-       }
-
-       for (j=0; j<nPlainLen; i++,j++)
-       {
-               ToEncrypt[i] = pPlain[j];
-               i++;
-       }
-
-       i=i-1;
-       memset (iv,0,8);
-       memset (iv2,0,8);
-       DES_set_key((DES_cblock*) deskey_fixed, &ks1);
-       DES_ncbc_encrypt((unsigned char*) ToEncrypt, (unsigned char*) temp, i, &ks1, &iv, DES_ENCRYPT);
-       DES_set_key((DES_cblock*) &iv, &ks2);
-       DES_ncbc_encrypt((unsigned char*) ToEncrypt, (unsigned char*) temp, i, &ks2, &iv2, DES_ENCRYPT);
-       memcpy (pHash,iv2,8);
-}
-
-void HashNTLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       unsigned char UnicodePlain[MAX_PLAIN_LEN * 2];
-       int i;
-       for (i = 0; i < nPlainLen; i++)
-       {
-               UnicodePlain[i * 2] = pPlain[i];
-               UnicodePlain[i * 2 + 1] = 0x00;
-       }
-
-       MD4_NEW(UnicodePlain, nPlainLen * 2, pHash);
-}
-
-/*
-void HashMD2(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       MD2_CTX ctx;
-       MD2_Init(&ctx);
-       MD2_Update(&ctx, pPlain, nPlainLen);
-       MD2_Final(pHash, &ctx);
-
-       //MD2(pPlain, nPlainLen, pHash);
-}
-*/
-
-void HashMD4(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       MD4_NEW(pPlain, nPlainLen, pHash);
-}
-
-void HashMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       fast_MD5(pPlain, nPlainLen, pHash);
-}
-void HashDoubleMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       fast_MD5(pPlain, nPlainLen, pHash);
-       unsigned char hash[16];
-       memcpy(hash, pHash, 16);
-       fast_MD5(hash, 16, pHash);
-}
-
-void HashSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       SHA_CTX ctx;
-       SHA1_Init(&ctx);
-       SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);
-       SHA1_Final(pHash, &ctx);
-}
-
-/*
-void HashRIPEMD160(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       RIPEMD160_CTX ctx;
-       RIPEMD160_Init(&ctx);
-       RIPEMD160_Update(&ctx, pPlain, nPlainLen);
-       RIPEMD160_Final(pHash, &ctx);  
-
-       //RIPEMD160(pPlain, nPlainLen, pHash);
-}
-*/
-
-void HashMSCACHE(unsigned char *pPlain, int nPlainLen, unsigned char* pHash)
-{
-       char unicode_pwd[256];
-       char unicode_user[256];
-       static unsigned char username[] = "administrator";
-       static int userlen = 13;
-       unsigned char   final1[MD4_DIGEST_LENGTH];
-       MD4_CTX ctx;
-       int i;
-
-//     strcpy (username, "administrator");
-//     userlen = 13;
-
-       for (i=0; i<nPlainLen; i++)
-       {
-               unicode_pwd[i*2] = pPlain[i];
-               unicode_pwd[i*2+1] = 0x00;
-       }
-
-       for (i=0; i<userlen; i++)
-       {
-               unicode_user[i*2] = username[i];
-               unicode_user[i*2+1] = 0x00;
-       }
-       /*
-       MD4_Init(&ctx);
-       MD4_Update(&ctx,unicode_pwd,nPlainLen*2);
-       MD4_Final(final1,&ctx);
-       */
-       MD4_NEW( (unsigned char*)unicode_pwd, nPlainLen*2, final1 );
-
-       MD4_Init(&ctx);
-       MD4_Update(&ctx,final1,MD4_DIGEST_LENGTH);
-       MD4_Update(&ctx,(unsigned char*) unicode_user,userlen*2);
-       MD4_Final(pHash,&ctx);
-
-       /*
-       unsigned char unicode_pwd[256];
-       for (int i=0; i<nPlainLen; i++)
-       {
-               unicode_pwd[i*2] = pPlain[i];
-               unicode_pwd[i*2+1] = 0x00;
-       }*/     
-       /*
-       unsigned char *buf = (unsigned char*)calloc(MSCACHE_HASH_SIZE + nSaltLength, sizeof(unsigned char));    
-       HashNTLM(pPlain, nPlainLen, buf, NULL);
-       //MD4(unicode_pwd, nPlainLen*2, buf);
-       memcpy(buf + MSCACHE_HASH_SIZE, pSalt, nSaltLength);
-       MD4(buf, MSCACHE_HASH_SIZE + nSaltLength, pHash); 
-       free(buf);
-       */
-}
-
-//*********************************************************************************
-// Code for MySQL password hashing
-//*********************************************************************************
-
-inline void mysql_hash_password_323(unsigned long *result, const char *password) 
-{
-       register unsigned long nr=1345345333L, add=7, nr2=0x12345671L;
-       unsigned long tmp;
-       for (; *password ; password++) 
-       {
-               if (*password == ' ' || *password == '\t') continue;
-               tmp= (unsigned long) (unsigned char) *password;
-               nr^= (((nr & 63)+add)*tmp)+ (nr << 8);
-               nr2+=(nr2 << 8) ^ nr;
-               add+=tmp;
-       }
-       result[0]=nr & (((unsigned long) 1L << 31) -1L); /* Don't use sign bit (str2int) */;
-       result[1]=nr2 & (((unsigned long) 1L << 31) -1L);
-       return;
-}
-
-void HashMySQL323(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       unsigned long hash_pass[2];     
-       unsigned char* f = (unsigned char*) hash_pass;
-
-       unsigned char* pass = (unsigned char*) calloc (nPlainLen+4,sizeof(unsigned char));
-       memcpy(pass,pPlain,nPlainLen);
-
-       mysql_hash_password_323(hash_pass, (char*) pass);
-       pHash[0]=*(f+3); pHash[1]=*(f+2); pHash[2]=*(f+1); pHash[3]=*(f+0);
-       pHash[4]=*(f+7); pHash[5]=*(f+6); pHash[6]=*(f+5); pHash[7]=*(f+4);
-
-       free (pass);
-}
-
-void HashMySQLSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       unsigned char hash_stage1[SHA_DIGEST_LENGTH];
-       SHA_CTX ctx;
-
-       SHA1_Init(&ctx);
-       SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);
-       SHA1_Final(hash_stage1, &ctx);
-       SHA1_Init(&ctx);
-       SHA1_Update(&ctx, hash_stage1, SHA_DIGEST_LENGTH);
-       SHA1_Final(pHash, &ctx);
-}
-
-//*********************************************************************************
-// Code for PIX password hashing
-//*********************************************************************************
-static char itoa64[] =          /* 0 ... 63 => ascii - 64 */
-       "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
-
-void _crypt_to64(char *s, unsigned long v, int n)
-{
-       while (--n >= 0) {
-               *s++ = itoa64[v&0x3f];
-               v >>= 6;
-       }
-}
-
-void HashPIX(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
-{
-       char temp[MD5_DIGEST_LENGTH+1];
-       unsigned char final[MD5_DIGEST_LENGTH];
-       char* pass = (char*) calloc (nPlainLen+MD5_DIGEST_LENGTH,sizeof(char));
-
-       memcpy (pass,pPlain,nPlainLen);
-
-       /*MD5_CTX ctx;
-       MD5_Init(&ctx);
-       MD5_Update(&ctx, (unsigned char *) pass, MD5_DIGEST_LENGTH);
-       MD5_Final(final, &ctx);*/
-       fast_MD5((unsigned char *) pass, MD5_DIGEST_LENGTH, final);
-
-       char* p = (char*) temp;
-       _crypt_to64(p,*(unsigned long*) (final+0),4); p += 4;
-       _crypt_to64(p,*(unsigned long*) (final+4),4); p += 4;
-       _crypt_to64(p,*(unsigned long*) (final+8),4); p += 4;
-       _crypt_to64(p,*(unsigned long*) (final+12),4); p += 4;
-       *p=0;
-
-       memcpy(pHash,temp,MD5_DIGEST_LENGTH);
-
-       free (pass);
-}
-
-#if !defined(_WIN32) || defined(__GNUC__)
-char *strupr(char *s1)
-{
-       char *p = s1;
-       while(*p)
-       {
-               *p = (char) toupper(*p);
-               p++;
-       }
-       return s1;
-}
-#endif
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright 2009, 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ * Changes: not using OpenSSL routines the slow way anymore, as suggested by jci.\r
+ */\r
+\r
+#include "HashAlgorithm.h"\r
+\r
+#include "Public.h"\r
+\r
+#include <openssl/des.h>\r
+//#include <openssl/md2.h>\r
+#include <openssl/md4.h>\r
+#include <openssl/sha.h>\r
+//#include <openssl/ripemd.h>\r
+#include "fast_md5.h"\r
+#include "md4.h"\r
+//#include "sha1.h"\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma comment(lib, "libeay32.lib")\r
+#endif\r
+\r
+#ifdef __NetBSD__\r
+       #include <des.h>\r
+#endif\r
+\r
+#define MSCACHE_HASH_SIZE 16\r
+void setup_des_key(unsigned char key_56[], des_key_schedule &ks)\r
+{\r
+       des_cblock key;\r
+\r
+       key[0] = key_56[0];\r
+       key[1] = (key_56[0] << 7) | (key_56[1] >> 1);\r
+       key[2] = (key_56[1] << 6) | (key_56[2] >> 2);\r
+       key[3] = (key_56[2] << 5) | (key_56[3] >> 3);\r
+       key[4] = (key_56[3] << 4) | (key_56[4] >> 4);\r
+       key[5] = (key_56[4] << 3) | (key_56[5] >> 5);\r
+       key[6] = (key_56[5] << 2) | (key_56[6] >> 6);\r
+       key[7] = (key_56[6] << 1);\r
+\r
+       //des_set_odd_parity(&key);\r
+       des_set_key(&key, ks);\r
+}\r
+\r
+void HashLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       /*\r
+       unsigned char data[7] = {0};\r
+       memcpy(data, pPlain, nPlainLen > 7 ? 7 : nPlainLen);\r
+       */\r
+\r
+       int i;\r
+       for (i = nPlainLen; i < 7; i++)\r
+               pPlain[i] = 0;\r
+\r
+       static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};\r
+       des_key_schedule ks;\r
+       //setup_des_key(data, ks);\r
+       setup_des_key(pPlain, ks);\r
+       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
+}\r
+\r
+void HashLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       unsigned char pass[14];\r
+       unsigned char pre_lmresp[21];\r
+       static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};\r
+       static unsigned char spoofed_challange[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; \r
+       des_key_schedule ks;\r
+\r
+       memset (pass,0,sizeof(pass));\r
+       memset (pre_lmresp,0,sizeof(pre_lmresp));\r
+\r
+       memcpy (pass,pPlain, nPlainLen);\r
+\r
+       setup_des_key(pass, ks);\r
+       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pre_lmresp, ks, DES_ENCRYPT);\r
+\r
+       setup_des_key(&pass[7], ks);\r
+       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)&pre_lmresp[8], ks, DES_ENCRYPT);\r
+\r
+       setup_des_key(pre_lmresp, ks);\r
+       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
+\r
+       setup_des_key(&pre_lmresp[7], ks);\r
+       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[8], ks, DES_ENCRYPT);\r
+\r
+       setup_des_key(&pre_lmresp[14], ks);\r
+       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[16], ks, DES_ENCRYPT);\r
+\r
+} \r
+\r
+void HashHALFLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{      \r
+       unsigned char pre_lmresp[8];\r
+       static unsigned char magic[] = {0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};\r
+       static unsigned char salt[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88};\r
+\r
+       des_key_schedule ks;\r
+       unsigned char plain[8] = {0};   \r
+       memcpy(plain, pPlain, nPlainLen);\r
+       setup_des_key(plain, ks);\r
+       des_ecb_encrypt((des_cblock*)magic, (des_cblock*)pre_lmresp, ks, DES_ENCRYPT);\r
+\r
+       setup_des_key(pre_lmresp, ks);\r
+       des_ecb_encrypt((des_cblock*)salt, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
+} \r
+\r
+\r
+\r
+void HashNTLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       unsigned char UnicodePlain[MAX_PLAIN_LEN];\r
+       static unsigned char spoofed_challange[] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}; \r
+       \r
+       int len = (nPlainLen < 127) ? nPlainLen : 127;\r
+       int i;\r
+       \r
+       for (i = 0; i < len; i++)\r
+       {\r
+       UnicodePlain[i * 2] = pPlain[i];\r
+       UnicodePlain[i * 2 + 1] = 0x00;\r
+       }\r
+       \r
+       des_key_schedule ks;\r
+       unsigned char lm[21];\r
+       \r
+       /*MD4_CTX ctx;\r
+       MD4_Init(&ctx);\r
+       MD4_Update(&ctx, UnicodePlain, len * 2);\r
+       MD4_Final(lm, &ctx);  */\r
+       MD4_NEW(UnicodePlain, len * 2, lm);\r
+       \r
+       //MD4(UnicodePlain, len * 2, lm);\r
+       lm[16] = lm[17] = lm[18] = lm[19] = lm[20] = 0;\r
+       \r
+       setup_des_key(lm, ks);\r
+       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)pHash, ks, DES_ENCRYPT);\r
+       \r
+       setup_des_key(&lm[7], ks);\r
+       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[8], ks, DES_ENCRYPT);\r
+       \r
+       setup_des_key(&lm[14], ks);\r
+       des_ecb_encrypt((des_cblock*)spoofed_challange, (des_cblock*)&pHash[16], ks, DES_ENCRYPT);\r
+}\r
+\r
+void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       char ToEncrypt[256];\r
+       char temp[256];\r
+       char username[256];\r
+\r
+       DES_cblock iv,iv2;\r
+       DES_key_schedule ks1,ks2;\r
+       unsigned char deskey_fixed[]={ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};\r
+       int i,j;\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       strcpy_s(username, sizeof(username), "SYS");\r
+#else\r
+       strcpy(username, "SYS");\r
+#endif\r
+       int userlen = 3;\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       _strupr((char*) pPlain);\r
+#else\r
+       strupr((char*) pPlain);\r
+#endif\r
+       memset (ToEncrypt,0,sizeof(ToEncrypt));\r
+\r
+       for (i=1,j=0; j<userlen; i++,j++)\r
+       {\r
+               ToEncrypt[i] = username[j];\r
+               i++;\r
+       }\r
+\r
+       for (j=0; j<nPlainLen; i++,j++)\r
+       {\r
+               ToEncrypt[i] = pPlain[j];\r
+               i++;\r
+       }\r
+\r
+       i=i-1;\r
+       memset (iv,0,8);\r
+       memset (iv2,0,8);\r
+       DES_set_key((DES_cblock*) deskey_fixed, &ks1);\r
+       DES_ncbc_encrypt((unsigned char*) ToEncrypt, (unsigned char*) temp, i, &ks1, &iv, DES_ENCRYPT);\r
+       DES_set_key((DES_cblock*) &iv, &ks2);\r
+       DES_ncbc_encrypt((unsigned char*) ToEncrypt, (unsigned char*) temp, i, &ks2, &iv2, DES_ENCRYPT);\r
+       memcpy (pHash,iv2,8);\r
+}\r
+\r
+void HashNTLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       unsigned char UnicodePlain[MAX_PLAIN_LEN * 2];\r
+       int i;\r
+       for (i = 0; i < nPlainLen; i++)\r
+       {\r
+               UnicodePlain[i * 2] = pPlain[i];\r
+               UnicodePlain[i * 2 + 1] = 0x00;\r
+       }\r
+\r
+       MD4_NEW(UnicodePlain, nPlainLen * 2, pHash);\r
+}\r
+\r
+/*\r
+void HashMD2(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       MD2_CTX ctx;\r
+       MD2_Init(&ctx);\r
+       MD2_Update(&ctx, pPlain, nPlainLen);\r
+       MD2_Final(pHash, &ctx);\r
+\r
+       //MD2(pPlain, nPlainLen, pHash);\r
+}\r
+*/\r
+\r
+void HashMD4(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       MD4_NEW(pPlain, nPlainLen, pHash);\r
+}\r
+\r
+void HashMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       fast_MD5(pPlain, nPlainLen, pHash);\r
+}\r
+void HashDoubleMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       fast_MD5(pPlain, nPlainLen, pHash);\r
+       unsigned char hash[16];\r
+       memcpy(hash, pHash, 16);\r
+       fast_MD5(hash, 16, pHash);\r
+}\r
+\r
+void HashSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       SHA_CTX ctx;\r
+       SHA1_Init(&ctx);\r
+       SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);\r
+       SHA1_Final(pHash, &ctx);\r
+}\r
+\r
+/*\r
+void HashRIPEMD160(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       RIPEMD160_CTX ctx;\r
+       RIPEMD160_Init(&ctx);\r
+       RIPEMD160_Update(&ctx, pPlain, nPlainLen);\r
+       RIPEMD160_Final(pHash, &ctx);  \r
+\r
+       //RIPEMD160(pPlain, nPlainLen, pHash);\r
+}\r
+*/\r
+\r
+void HashMSCACHE(unsigned char *pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       char unicode_pwd[256];\r
+       char unicode_user[256];\r
+       static unsigned char username[] = "administrator";\r
+       static int userlen = 13;\r
+       unsigned char   final1[MD4_DIGEST_LENGTH];\r
+       MD4_CTX ctx;\r
+       int i;\r
+\r
+//     strcpy (username, "administrator");\r
+//     userlen = 13;\r
+\r
+       for (i=0; i<nPlainLen; i++)\r
+       {\r
+               unicode_pwd[i*2] = pPlain[i];\r
+               unicode_pwd[i*2+1] = 0x00;\r
+       }\r
+\r
+       for (i=0; i<userlen; i++)\r
+       {\r
+               unicode_user[i*2] = username[i];\r
+               unicode_user[i*2+1] = 0x00;\r
+       }\r
+\r
+       MD4_NEW( (unsigned char*)unicode_pwd, nPlainLen*2, final1 );\r
+\r
+       MD4_Init(&ctx);\r
+       MD4_Update(&ctx,final1,MD4_DIGEST_LENGTH);\r
+       MD4_Update(&ctx,(unsigned char*) unicode_user,userlen*2);\r
+       MD4_Final(pHash,&ctx);\r
+\r
+       /*\r
+       unsigned char unicode_pwd[256];\r
+       for (int i=0; i<nPlainLen; i++)\r
+       {\r
+               unicode_pwd[i*2] = pPlain[i];\r
+               unicode_pwd[i*2+1] = 0x00;\r
+       }*/\r
+       /*\r
+       unsigned char *buf = (unsigned char*)calloc(MSCACHE_HASH_SIZE + nSaltLength, sizeof(unsigned char));    \r
+       HashNTLM(pPlain, nPlainLen, buf, NULL);\r
+       //MD4(unicode_pwd, nPlainLen*2, buf);\r
+       memcpy(buf + MSCACHE_HASH_SIZE, pSalt, nSaltLength);\r
+       MD4(buf, MSCACHE_HASH_SIZE + nSaltLength, pHash); \r
+       free(buf);\r
+       */\r
+}\r
+\r
+//*********************************************************************************\r
+// Code for MySQL password hashing\r
+//*********************************************************************************\r
+\r
+inline void mysql_hash_password_323(unsigned long *result, const char *password) \r
+{\r
+       register unsigned long nr=1345345333L, add=7, nr2=0x12345671L;\r
+       unsigned long tmp;\r
+       for (; *password ; password++) \r
+       {\r
+               if (*password == ' ' || *password == '\t') continue;\r
+               tmp= (unsigned long) (unsigned char) *password;\r
+               nr^= (((nr & 63)+add)*tmp)+ (nr << 8);\r
+               nr2+=(nr2 << 8) ^ nr;\r
+               add+=tmp;\r
+       }\r
+       result[0]=nr & (((unsigned long) 1L << 31) -1L); /* Don't use sign bit (str2int) */;\r
+       result[1]=nr2 & (((unsigned long) 1L << 31) -1L);\r
+       return;\r
+}\r
+\r
+void HashMySQL323(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       unsigned long hash_pass[2];     \r
+       unsigned char* f = (unsigned char*) hash_pass;\r
+\r
+       unsigned char* pass = (unsigned char*) calloc (nPlainLen+4,sizeof(unsigned char));\r
+       memcpy(pass,pPlain,nPlainLen);\r
+\r
+       mysql_hash_password_323(hash_pass, (char*) pass);\r
+       pHash[0]=*(f+3); pHash[1]=*(f+2); pHash[2]=*(f+1); pHash[3]=*(f+0);\r
+       pHash[4]=*(f+7); pHash[5]=*(f+6); pHash[6]=*(f+5); pHash[7]=*(f+4);\r
+\r
+       free (pass);\r
+}\r
+\r
+void HashMySQLSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       unsigned char hash_stage1[SHA_DIGEST_LENGTH];\r
+       SHA_CTX ctx;\r
+\r
+       SHA1_Init(&ctx);\r
+       SHA1_Update(&ctx, (unsigned char *) pPlain, nPlainLen);\r
+       SHA1_Final(hash_stage1, &ctx);\r
+       SHA1_Init(&ctx);\r
+       SHA1_Update(&ctx, hash_stage1, SHA_DIGEST_LENGTH);\r
+       SHA1_Final(pHash, &ctx);\r
+}\r
+\r
+//*********************************************************************************\r
+// Code for PIX password hashing\r
+//*********************************************************************************\r
+static char itoa64[] =          /* 0 ... 63 => ascii - 64 */\r
+       "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";\r
+\r
+void _crypt_to64(char *s, unsigned long v, int n)\r
+{\r
+       while (--n >= 0) {\r
+               *s++ = itoa64[v&0x3f];\r
+               v >>= 6;\r
+       }\r
+}\r
+\r
+void HashPIX(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)\r
+{\r
+       char temp[MD5_DIGEST_LENGTH+1];\r
+       unsigned char final[MD5_DIGEST_LENGTH];\r
+       char* pass = (char*) calloc (nPlainLen+MD5_DIGEST_LENGTH,sizeof(char));\r
+\r
+       memcpy (pass,pPlain,nPlainLen);\r
+\r
+       fast_MD5((unsigned char *) pass, MD5_DIGEST_LENGTH, final);\r
+\r
+       char* p = (char*) temp;\r
+       _crypt_to64(p,*(unsigned long*) (final+0),4); p += 4;\r
+       _crypt_to64(p,*(unsigned long*) (final+4),4); p += 4;\r
+       _crypt_to64(p,*(unsigned long*) (final+8),4); p += 4;\r
+       _crypt_to64(p,*(unsigned long*) (final+12),4); p += 4;\r
+       *p=0;\r
+\r
+       memcpy(pHash,temp,MD5_DIGEST_LENGTH);\r
+\r
+       free (pass);\r
+}\r
+\r
+#if !defined(_WIN32) || defined(__GNUC__)\r
+char *strupr(char *s1)\r
+{\r
+       char *p = s1;\r
+       while(*p)\r
+       {\r
+               *p = (char) toupper(*p);\r
+               p++;\r
+       }\r
+       return s1;\r
+}\r
+#endif\r
index 595f13d29a044c93632128a23b4e3ebe93e278bd..148f46b555a820154cddceba195fe46654e0df88 100644 (file)
@@ -1,96 +1,96 @@
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "HashRoutine.h"
-#include "HashAlgorithm.h"
-
-//////////////////////////////////////////////////////////////////////
-
-CHashRoutine::CHashRoutine()
-{
-       // Notice: MIN_HASH_LEN <= nHashLen <= MAX_HASH_LEN
-
-
-       AddHashRoutine("lm",   HashLM,   8);
-       AddHashRoutine("ntlm", HashNTLM, 16);
-//     AddHashRoutine("md2",  HashMD2,  16);
-       AddHashRoutine("md4",  HashMD4,  16);
-       AddHashRoutine("md5",  HashMD5,  16);
-       AddHashRoutine("doublemd5",  HashDoubleMD5,  16);
-       AddHashRoutine("sha1", HashSHA1, 20);
-//     AddHashRoutine("ripemd160", HashRIPEMD160, 20);
-       AddHashRoutine("mysql323", HashMySQL323, 8);
-       AddHashRoutine("mysqlsha1", HashMySQLSHA1, 20);
-       AddHashRoutine("ciscopix", HashPIX, 16);
-       AddHashRoutine("mscache", HashMSCACHE, 16);
-       AddHashRoutine("halflmchall", HashHALFLMCHALL, 8);
-
-       // Added from mao
-       AddHashRoutine("lmchall", HashLMCHALL, 24);
-       AddHashRoutine("ntlmchall", HashNTLMCHALL, 24);
-       AddHashRoutine("oracle", HashORACLE, 8);
-}
-
-CHashRoutine::~CHashRoutine()
-{
-}
-
-void CHashRoutine::AddHashRoutine(string sHashRoutineName, HASHROUTINE pHashRoutine, int nHashLen)
-{
-       vHashRoutineName.push_back(sHashRoutineName);
-       vHashRoutine.push_back(pHashRoutine);
-       vHashLen.push_back(nHashLen);
-}
-
-string CHashRoutine::GetAllHashRoutineName()
-{
-       string sRet;
-       UINT4 i;
-       for (i = 0; i < vHashRoutineName.size(); i++)
-               sRet += vHashRoutineName[i] + " ";
-
-       return sRet;
-}
-
-void CHashRoutine::GetHashRoutine(string sHashRoutineName, HASHROUTINE& pHashRoutine, int& nHashLen)
-{
-       UINT4 i;
-       for (i = 0; i < vHashRoutineName.size(); i++)
-       {
-               if (sHashRoutineName == vHashRoutineName[i])
-               {
-                       pHashRoutine = vHashRoutine[i];
-                       nHashLen = vHashLen[i];
-                       return;
-               }
-       }
-
-       pHashRoutine = NULL;
-       nHashLen = 0;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "HashRoutine.h"\r
+#include "HashAlgorithm.h"\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+CHashRoutine::CHashRoutine()\r
+{\r
+       // Notice: MIN_HASH_LEN <= nHashLen <= MAX_HASH_LEN\r
+\r
+\r
+       AddHashRoutine("lm",   HashLM,   8);\r
+       AddHashRoutine("ntlm", HashNTLM, 16);\r
+//     AddHashRoutine("md2",  HashMD2,  16);\r
+       AddHashRoutine("md4",  HashMD4,  16);\r
+       AddHashRoutine("md5",  HashMD5,  16);\r
+       AddHashRoutine("doublemd5",  HashDoubleMD5,  16);\r
+       AddHashRoutine("sha1", HashSHA1, 20);\r
+//     AddHashRoutine("ripemd160", HashRIPEMD160, 20);\r
+       AddHashRoutine("mysql323", HashMySQL323, 8);\r
+       AddHashRoutine("mysqlsha1", HashMySQLSHA1, 20);\r
+       AddHashRoutine("ciscopix", HashPIX, 16);\r
+       AddHashRoutine("mscache", HashMSCACHE, 16);\r
+       AddHashRoutine("halflmchall", HashHALFLMCHALL, 8);\r
+\r
+       // Added from mao\r
+       AddHashRoutine("lmchall", HashLMCHALL, 24);\r
+       AddHashRoutine("ntlmchall", HashNTLMCHALL, 24);\r
+       AddHashRoutine("oracle", HashORACLE, 8);\r
+}\r
+\r
+CHashRoutine::~CHashRoutine()\r
+{\r
+}\r
+\r
+void CHashRoutine::AddHashRoutine(string sHashRoutineName, HASHROUTINE pHashRoutine, int nHashLen)\r
+{\r
+       vHashRoutineName.push_back(sHashRoutineName);\r
+       vHashRoutine.push_back(pHashRoutine);\r
+       vHashLen.push_back(nHashLen);\r
+}\r
+\r
+string CHashRoutine::GetAllHashRoutineName()\r
+{\r
+       string sRet;\r
+       uint32 i;\r
+       for (i = 0; i < vHashRoutineName.size(); i++)\r
+               sRet += vHashRoutineName[i] + " ";\r
+\r
+       return sRet;\r
+}\r
+\r
+void CHashRoutine::GetHashRoutine(string sHashRoutineName, HASHROUTINE& pHashRoutine, int& nHashLen)\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < vHashRoutineName.size(); i++)\r
+       {\r
+               if (sHashRoutineName == vHashRoutineName[i])\r
+               {\r
+                       pHashRoutine = vHashRoutine[i];\r
+                       nHashLen = vHashLen[i];\r
+                       return;\r
+               }\r
+       }\r
+\r
+       pHashRoutine = NULL;\r
+       nHashLen = 0;\r
+}\r
index a62547500fe3078dcbeeac9d5df1e0547cf8f3cf..dedb2ba139253db37b333669c9aedc178acdd8dc 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "HashSet.h"
-
-CHashSet::CHashSet()
-{
-}
-
-CHashSet::~CHashSet()
-{
-}
-
-void CHashSet::AddHash(string sHash)
-{
-       if (sHash == "aad3b435b51404ee")
-               return;
-
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (m_vHash[i] == sHash)
-                       return;
-       }
-
-       //printf("debug: adding hash %s\n", sHash.c_str());
-
-       m_vHash.push_back(sHash);
-       m_vFound.push_back(false);
-       m_vPlain.push_back("");
-       m_vBinary.push_back("");
-}
-
-string CHashSet::GetHashInfo(int i)
-{
-       string found;
-       if (m_vFound[i])
-               found = "1";
-       else
-               found = "0";
-
-       string buffer = m_vHash[i] + ":" + found + ":" + m_vPlain[i] + ":" + m_vBinary[i];
-
-       return buffer;
-}
-
-bool CHashSet::AnyhashLeft()
-{
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (!m_vFound[i])
-                       return true;
-       }
-
-       return false;
-}
-
-bool CHashSet::AnyHashLeftWithLen(int nLen)
-{
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (!m_vFound[i])
-                       if (m_vHash[i].size() == (unsigned long)nLen * 2)
-                               return true;
-       }
-
-       return false;
-}
-
-void CHashSet::GetLeftHashWithLen(vector<string>& vHash, int nLen)
-{
-       vHash.clear();
-
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (!m_vFound[i])
-                       if (m_vHash[i].size() == (unsigned long)nLen * 2)
-                               vHash.push_back(m_vHash[i]);
-       }
-}
-
-void CHashSet::AddHashInfo(string sHash, bool found, string sPlain, string sBinary)
-{
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (m_vHash[i] == sHash)
-                       return;
-       }
-
-       m_vHash.push_back(sHash);
-       m_vFound.push_back(found);
-       m_vPlain.push_back(sPlain);
-       m_vBinary.push_back(sBinary);
-}
-
-void CHashSet::SetPlain(string sHash, string sPlain, string sBinary)
-{
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (m_vHash[i] == sHash)
-               {
-                       m_vFound[i]    = true;
-                       m_vPlain[i]    = sPlain;
-                       m_vBinary[i]   = sBinary;
-                       return;
-               }
-       }
-}
-
-bool CHashSet::GetPlain(string sHash, string& sPlain, string& sBinary)
-{
-       if (sHash == "aad3b435b51404ee")
-       {
-               sPlain  = "";
-               sBinary = "";
-               return true;
-       }
-
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (m_vHash[i] == sHash)
-               {
-                       if (m_vFound[i])
-                       {
-                               sPlain  = m_vPlain[i];
-                               sBinary = m_vBinary[i];
-                               return true;
-                       }
-               }
-       }
-
-       return false;
-}
-
-int CHashSet::GetStatHashFound()
-{
-       int nHashFound = 0;
-       UINT4 i;
-       for (i = 0; i < m_vHash.size(); i++)
-       {
-               if (m_vFound[i])
-                       nHashFound++;
-       }
-
-       return nHashFound;
-}
-
-int CHashSet::GetStatHashTotal()
-{
-       return (int) m_vHash.size();
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "HashSet.h"\r
+\r
+CHashSet::CHashSet()\r
+{\r
+}\r
+\r
+CHashSet::~CHashSet()\r
+{\r
+}\r
+\r
+void CHashSet::AddHash(string sHash)\r
+{\r
+       if (sHash == "aad3b435b51404ee")\r
+               return;\r
+\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (m_vHash[i] == sHash)\r
+                       return;\r
+       }\r
+\r
+       //printf("debug: adding hash %s\n", sHash.c_str());\r
+\r
+       m_vHash.push_back(sHash);\r
+       m_vFound.push_back(false);\r
+       m_vPlain.push_back("");\r
+       m_vBinary.push_back("");\r
+}\r
+\r
+string CHashSet::GetHashInfo(int i)\r
+{\r
+       string found;\r
+       if (m_vFound[i])\r
+               found = "1";\r
+       else\r
+               found = "0";\r
+\r
+       string buffer = m_vHash[i] + ":" + found + ":" + m_vPlain[i] + ":" + m_vBinary[i];\r
+\r
+       return buffer;\r
+}\r
+\r
+bool CHashSet::AnyhashLeft()\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (!m_vFound[i])\r
+                       return true;\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+bool CHashSet::AnyHashLeftWithLen(int nLen)\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (!m_vFound[i])\r
+                       if (m_vHash[i].size() == (unsigned long)nLen * 2)\r
+                               return true;\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+void CHashSet::GetLeftHashWithLen(vector<string>& vHash, int nLen)\r
+{\r
+       vHash.clear();\r
+\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (!m_vFound[i])\r
+                       if (m_vHash[i].size() == (unsigned long)nLen * 2)\r
+                               vHash.push_back(m_vHash[i]);\r
+       }\r
+}\r
+\r
+void CHashSet::AddHashInfo(string sHash, bool found, string sPlain, string sBinary)\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (m_vHash[i] == sHash)\r
+                       return;\r
+       }\r
+\r
+       m_vHash.push_back(sHash);\r
+       m_vFound.push_back(found);\r
+       m_vPlain.push_back(sPlain);\r
+       m_vBinary.push_back(sBinary);\r
+}\r
+\r
+void CHashSet::SetPlain(string sHash, string sPlain, string sBinary)\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (m_vHash[i] == sHash)\r
+               {\r
+                       m_vFound[i]    = true;\r
+                       m_vPlain[i]    = sPlain;\r
+                       m_vBinary[i]   = sBinary;\r
+                       return;\r
+               }\r
+       }\r
+}\r
+\r
+bool CHashSet::GetPlain(string sHash, string& sPlain, string& sBinary)\r
+{\r
+       if (sHash == "aad3b435b51404ee")\r
+       {\r
+               sPlain  = "";\r
+               sBinary = "";\r
+               return true;\r
+       }\r
+\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (m_vHash[i] == sHash)\r
+               {\r
+                       if (m_vFound[i])\r
+                       {\r
+                               sPlain  = m_vPlain[i];\r
+                               sBinary = m_vBinary[i];\r
+                               return true;\r
+                       }\r
+               }\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+int CHashSet::GetStatHashFound()\r
+{\r
+       int nHashFound = 0;\r
+       uint32 i;\r
+       for (i = 0; i < m_vHash.size(); i++)\r
+       {\r
+               if (m_vFound[i])\r
+                       nHashFound++;\r
+       }\r
+\r
+       return nHashFound;\r
+}\r
+\r
+int CHashSet::GetStatHashTotal()\r
+{\r
+       return (int) m_vHash.size();\r
+}\r
index 10e235c4b8485e4b4883d3571fd13c9c0358c4ad..77a4eabbd5aacca9bdd22776718c896ad7952084 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- * Copyright 2010 uroskn
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "MemoryPool.h"
-#include "Public.h"
-
-CMemoryPool::CMemoryPool(unsigned int bytesSaved, bool bDebug, uint64 maxMem)
-{
-       m_pMem = NULL;
-       m_nMemSize = 0;
-       debug = bDebug;
-
-       uint64 nAvailPhys = GetAvailPhysMemorySize();
-
-       if ( debug )
-       {
-               #ifdef _WIN32
-                       printf( "Debug: nAvailPhys: %I64u\n", nAvailPhys );
-               #else
-                       printf( "Debug: nAvailPhys: %llu\n", nAvailPhys );
-               #endif
-               printf( "Debug: bytesSaved: %d\n", bytesSaved );
-       }
-
-       if ( maxMem > 0 && maxMem < nAvailPhys )
-               nAvailPhys = maxMem;
-       
-       m_nMemMax = nAvailPhys - bytesSaved;    // Leave memory for CChainWalkSet       
-
-       if (m_nMemMax < 16 * 1024 * 1024)
-               m_nMemMax = 16 * 1024 * 1024;
-}
-
-CMemoryPool::~CMemoryPool()
-{
-       if (m_pMem != NULL)
-       {
-               delete [] m_pMem;
-               m_pMem = NULL;
-               m_nMemSize = 0;
-       }
-}
-
-unsigned char* CMemoryPool::Allocate(unsigned int nFileLen, uint64& nAllocatedSize)
-{
-       if (nFileLen <= m_nMemSize)
-       {
-               nAllocatedSize = nFileLen;
-               return m_pMem;
-       }
-
-       unsigned int nTargetSize;
-       if (nFileLen < m_nMemMax)
-               nTargetSize = nFileLen;
-       else
-               nTargetSize = m_nMemMax;
-
-       // Free existing memory
-       if (m_pMem != NULL)
-       {
-               delete [] m_pMem;
-               m_pMem = NULL;
-               m_nMemSize = 0;
-       }
-
-       // Allocate new memory
-       //printf("allocating %u bytes memory\n", nTargetSize);
-       m_pMem = new (nothrow) unsigned char[nTargetSize];
-       while (m_pMem == NULL && nTargetSize >= 32 * 1024 * 1024 )
-       {
-          nTargetSize -= 16 * 1024 * 1024;
-          m_pMem = new (nothrow) unsigned char[nTargetSize];
-       }
-
-       if (m_pMem != NULL)
-       {
-               m_nMemSize = nTargetSize;
-               nAllocatedSize = nTargetSize;
-               return m_pMem;
-       }
-       else
-       {
-               m_nMemSize = 0;
-               nAllocatedSize = 0;
-               return NULL;
-       }
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ * Copyright 2010 uroskn\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#include "MemoryPool.h"\r
+#include "Public.h"\r
+\r
+CMemoryPool::CMemoryPool(unsigned int bytesSaved, bool bDebug, uint64 maxMem)\r
+{\r
+       m_pMem = NULL;\r
+       m_nMemSize = 0;\r
+       debug = bDebug;\r
+\r
+       unsigned long nAvailPhys = GetAvailPhysMemorySize();\r
+\r
+       if ( debug )\r
+       {\r
+               #if defined(_WIN32) && !defined(__GNUC__)\r
+                       printf( "Debug: nAvailPhys: %I64u\n", nAvailPhys );\r
+               #else\r
+                       printf( "Debug: nAvailPhys: %lu\n", nAvailPhys );\r
+               #endif\r
+               printf( "Debug: bytesSaved: %d\n", bytesSaved );\r
+       }\r
+\r
+       if ( maxMem > 0 && maxMem < nAvailPhys )\r
+               nAvailPhys = maxMem;\r
+       \r
+       m_nMemMax = nAvailPhys - bytesSaved;    // Leave memory for CChainWalkSet       \r
+\r
+       if (m_nMemMax < 16 * 1024 * 1024)\r
+               m_nMemMax = 16 * 1024 * 1024;\r
+}\r
+\r
+CMemoryPool::~CMemoryPool()\r
+{\r
+       if (m_pMem != NULL)\r
+       {\r
+               delete [] m_pMem;\r
+               m_pMem = NULL;\r
+               m_nMemSize = 0;\r
+       }\r
+}\r
+\r
+unsigned char* CMemoryPool::Allocate(unsigned int nFileLen, uint64& nAllocatedSize)\r
+{\r
+       if (nFileLen <= m_nMemSize)\r
+       {\r
+               nAllocatedSize = nFileLen;\r
+               return m_pMem;\r
+       }\r
+\r
+       unsigned int nTargetSize;\r
+       if (nFileLen < m_nMemMax)\r
+               nTargetSize = nFileLen;\r
+       else\r
+               nTargetSize = m_nMemMax;\r
+\r
+       // Free existing memory\r
+       if (m_pMem != NULL)\r
+       {\r
+               delete [] m_pMem;\r
+               m_pMem = NULL;\r
+               m_nMemSize = 0;\r
+       }\r
+\r
+       // Allocate new memory\r
+       //printf("allocating %u bytes memory\n", nTargetSize);\r
+       m_pMem = new (nothrow) unsigned char[nTargetSize];\r
+       while (m_pMem == NULL && nTargetSize >= 32 * 1024 * 1024 )\r
+       {\r
+               nTargetSize -= 16 * 1024 * 1024;\r
+               m_pMem = new (nothrow) unsigned char[nTargetSize];\r
+       }\r
+\r
+       if (m_pMem != NULL)\r
+       {\r
+               m_nMemSize = nTargetSize;\r
+               nAllocatedSize = nTargetSize;\r
+               return m_pMem;\r
+       }\r
+       else\r
+       {\r
+               m_nMemSize = 0;\r
+               nAllocatedSize = 0;\r
+               return NULL;\r
+       }\r
+}\r
index 93047481896076a59bd744da4047b74fa8307bb6..6c82fc1cff4d983e52fab398e9e838f3cafd92e9 100644 (file)
@@ -1,49 +1,49 @@
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- * Copyright 2010 uroskn
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _MEMORYPOOL_H
-#define _MEMORYPOOL_H
-
-#include "global.h"
-
-class CMemoryPool  
-{
-public:
-       CMemoryPool(unsigned int bytesSaved, bool bDebug, uint64 maxMem);
-       virtual ~CMemoryPool();
-
-private:
-       bool debug;
-       unsigned char* m_pMem;
-       uint64 m_nMemSize;
-
-       uint64 m_nMemMax;
-
-public:
-       unsigned char* Allocate(unsigned int nFileLen, uint64& nAllocatedSize);
-};
-
-#endif
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ * Copyright 2010 uroskn\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#ifndef _MEMORYPOOL_H\r
+#define _MEMORYPOOL_H\r
+\r
+#include "global.h"\r
+\r
+class CMemoryPool  \r
+{\r
+public:\r
+       CMemoryPool(unsigned int bytesSaved, bool bDebug, uint64 maxMem);\r
+       virtual ~CMemoryPool();\r
+\r
+private:\r
+       bool debug;\r
+       unsigned char* m_pMem;\r
+       uint64 m_nMemSize;\r
+\r
+       uint64 m_nMemMax;\r
+\r
+public:\r
+       unsigned char* Allocate(unsigned int nFileLen, uint64& nAllocatedSize);\r
+};\r
+\r
+#endif\r
index 53249245de7f4741516205d19682507a7069f1bc..941331ba7443b0393e3c87d24e0ffdd5e60a5b49 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2 of the License.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "Public.h"
-
-#ifdef _WIN32
-       #include <windows.h>
-#endif
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #include <windows.h>
-       #include <time.h>
-
-       #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
-               #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
-       #else
-               #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
-       #endif
-       struct timezone
-       {
-               int  tz_minuteswest; /* minutes W of Greenwich */
-               int  tz_dsttime;     /* type of dst correction */
-       };
-       int gettimeofday(struct timeval *tv, struct timezone *tz)
-       {
-               // Define a structure to receive the current Windows filetime
-               FILETIME ft;
-               // Initialize the present time to 0 and the timezone to UTC
-               unsigned __int64 tmpres = 0;
-               static int tzflag = 0;
-               if (NULL != tv)
-               {
-                       GetSystemTimeAsFileTime(&ft);
-                       // The GetSystemTimeAsFileTime returns the number of 100 nanosecond 
-                       // intervals since Jan 1, 1601 in a structure. Copy the high bits to 
-                       // the 64 bit tmpres, shift it left by 32 then or in the low 32 bits.
-                       tmpres |= ft.dwHighDateTime;
-                       tmpres <<= 32;
-                       tmpres |= ft.dwLowDateTime;
-                       // Convert to microseconds by dividing by 10
-                       tmpres /= 10;
-                       // The Unix epoch starts on Jan 1 1970.  Need to subtract the difference 
-                       // in seconds from Jan 1 1601.
-                       tmpres -= DELTA_EPOCH_IN_MICROSECS;
-        
-                       // Finally change microseconds to seconds and place in the seconds value. 
-                       // The modulus picks up the microseconds.
-                       tv->tv_sec = (long)(tmpres / 1000000UL);
-                       tv->tv_usec = (long)(tmpres % 1000000UL);
-               }
-        
-               if (NULL != tz)
-               {
-                       if (!tzflag)
-                       {
-                               _tzset();
-                               tzflag++;
-                       }
-         
-                       // Adjust for the timezone west of Greenwich
-                       tz->tz_minuteswest = _timezone / 60;
-                       tz->tz_dsttime = _daylight;
-               }
-        
-               return 0;
-       }
-
-#elif defined(__APPLE__) || \
-       ((defined(__unix__) || defined(unix)) && !defined(USG))
-
-       #include <sys/param.h>
-
-       #if defined(BSD)
-               #include <sys/sysctl.h>
-       #elif defined(__linux__)
-               #include <sys/sysinfo.h>
-       #else
-               #error Unsupported Operating System
-       #endif
-#endif
-
-//////////////////////////////////////////////////////////////////////
-
-timeval sub_timeofday( timeval tv2, timeval tv )
-{
-       timeval final;
-
-       final.tv_usec = tv2.tv_usec - tv.tv_usec;
-       final.tv_sec = tv2.tv_sec - tv.tv_sec;
-
-       if ( final.tv_usec < 0 )
-       {
-               final.tv_usec += 1000000;
-               --final.tv_sec;
-       }
-
-       return final;
-}
-
-unsigned int GetFileLen(FILE* file)
-{
-       long int pos = ftell(file);
-       fseek(file, 0, SEEK_END);
-       long int len = ftell(file);
-       fseek(file, pos, SEEK_SET);
-
-       return len;
-}
-
-string TrimString(string s)
-{
-       while (s.size() > 0)
-       {
-               if (s[0] == ' ' || s[0] == '\t')
-                       s = s.substr(1);
-               else
-                       break;
-       }
-
-       while (s.size() > 0)
-       {
-               if (s[s.size() - 1] == ' ' || s[s.size() - 1] == '\t')
-                       s = s.substr(0, s.size() - 1);
-               else
-                       break;
-       }
-
-       return s;
-}
-bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset)
-{
-       // Example: hybrid(mixalpha-numeric-all-space#1-6,numeric#1-4)
-       if(sCharset.substr(0, 6) != "hybrid") // Not hybrid charset
-               return false;
-
-       string::size_type nEnd = sCharset.rfind(')');
-       string::size_type nStart = (int) sCharset.rfind('(');
-       string sChar = sCharset.substr(nStart + 1, nEnd - nStart - 1);
-       vector<string> vParts;
-       SeperateString(sChar, ",", vParts);
-       for(UINT4 i = 0; i < vParts.size(); i++)
-       {
-               tCharset stCharset;
-               vector<string> vParts2;
-               SeperateString(vParts[i], "#", vParts2);
-               stCharset.sName = vParts2[0];
-               vector<string> vParts3;
-               SeperateString(vParts2[1], "-", vParts3);
-               stCharset.nPlainLenMin = atoi(vParts3[0].c_str());
-               stCharset.nPlainLenMax = atoi(vParts3[1].c_str());
-               vCharset.push_back(stCharset);
-       }
-       return true;
-}
-bool ReadLinesFromFile(string sPathName, vector<string>& vLine)
-{
-       vLine.clear();
-
-       FILE* file = fopen(sPathName.c_str(), "rb");
-       if (file != NULL)
-       {
-               unsigned int len = GetFileLen(file);
-               char* data = new char[len + 1];
-               fread(data, 1, len, file);
-               data[len] = '\0';
-               string content = data;
-               content += "\n";
-               delete [] data;
-
-               unsigned int i;
-               for (i = 0; i < content.size(); i++)
-               {
-                       if (content[i] == '\r')
-                               content[i] = '\n';
-               }
-
-               string::size_type n;
-               while ((n = content.find("\n", 0)) != string::npos)
-               {
-                       string line = content.substr(0, n);
-                       line = TrimString(line);
-                       if (line != "")
-                               vLine.push_back(line);
-                       content = content.substr(n + 1);
-               }
-
-               fclose(file);
-       }
-       else
-               return false;
-
-       return true;
-}
-
-bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary)
-{
-       FILE* file = fopen(sOutputFile.c_str(), "a");
-       if (file!=NULL)
-       {
-               string buffer = sHash + ":" + sPlain + ":" + sBinary + "\n";
-               fputs (buffer.c_str(), file);
-               fclose (file);
-               return true;
-       }
-       else
-               return false;
-}
-
-bool SeperateString(string s, string sSeperator, vector<string>& vPart)
-{
-       vPart.clear();
-
-       unsigned int i;
-       for (i = 0; i < sSeperator.size(); i++)
-       {
-               string::size_type n;
-               if ( (n = s.find(sSeperator[i])) != string::npos)
-               {
-                       vPart.push_back(s.substr(0, n));
-                       s = s.substr(n + 1);
-               }
-               else
-               {
-                       printf("not found: %c\n", sSeperator[i]);
-                       printf("s: %s\n", s.c_str());
-                       return false;
-               }
-       }
-       vPart.push_back(s);
-
-       return true;
-}
-
-string uint64tostr(uint64 n)
-{
-       char str[32];
-
-#ifdef _WIN32
-       sprintf(str, "%I64u", n);
-#else
-       sprintf(str, "%llu", n);
-#endif
-
-       return str;
-}
-
-string uint64tohexstr(uint64 n)
-{
-       char str[32];
-
-#ifdef _WIN32
-       sprintf(str, "%016I64x", n);
-#else
-       sprintf(str, "%016llx", n);
-#endif
-
-       return str;
-}
-
-string HexToStr(const unsigned char* pData, int nLen)
-{
-       string sRet;
-       int i;
-       for (i = 0; i < nLen; i++)
-       {
-               char szByte[3];
-               sprintf(szByte, "%02x", pData[i]);
-               sRet += szByte;
-       }
-
-       return sRet;
-}
-
-uint64 GetAvailPhysMemorySize()
-{
-#if defined(_WIN32)
-       MEMORYSTATUS ms;
-       GlobalMemoryStatus(&ms);
-       return ms.dwAvailPhys;
-#elif defined(BSD)
-       int mib[2] = { CTL_HW, HW_PHYSMEM };
-       uint64 physMem;
-       //XXX warning size_t isn't portable
-       size_t len;
-       len = sizeof(physMem);
-       sysctl(mib, 2, &physMem, &len, NULL, 0);
-       return physMem;
-#elif defined(__linux__)
-       struct sysinfo info;
-       sysinfo(&info);
-       return ( info.freeram + info.bufferram ) * (unsigned long) info.mem_unit;
-#else
-       return 0;
-       #error Unsupported Operating System
-#endif
-}
-
-string GetApplicationPath()
-{
-       char fullPath[FILENAME_MAX];
-
-#ifdef _WIN32
-       GetModuleFileName(NULL, fullPath, FILENAME_MAX);
-#else
-       char szTmp[32];
-       // XXX linux/proc file system dependen
-       sprintf(szTmp, "/proc/%d/exe", getpid());
-       int bytes = readlink(szTmp, fullPath, FILENAME_MAX);
-       if(bytes >= 0)
-               fullPath[bytes] = '\0';
-#endif
-
-       string sApplicationPath = fullPath;
-#ifdef _WIN32
-       string::size_type nIndex = sApplicationPath.find_last_of('\\');
-#else
-       string::size_type nIndex = sApplicationPath.find_last_of('/');
-#endif
-
-       if ( nIndex != string::npos )
-               sApplicationPath = sApplicationPath.substr(0, nIndex+1);
-
-       //printf ("\n\nDebug: The application directory is %s\n", sApplicationPath.c_str());
-       return sApplicationPath;
-}
-
-void ParseHash(string sHash, unsigned char* pHash, int& nHashLen)
-{
-       UINT4 i;
-       for (i = 0; i < sHash.size() / 2; i++)
-       {
-               string sSub = sHash.substr(i * 2, 2);
-               int nValue;
-               sscanf(sSub.c_str(), "%02x", &nValue);
-               pHash[i] = (unsigned char)nValue;
-       }
-
-       nHashLen = (int) sHash.size() / 2;
-}
-
-void Logo()
-{
-       printf("RainbowCrack (improved, multi-threaded) - Making a Faster Cryptanalytic Time-Memory Trade-Off\n");
-       printf("by Martin Westergaard <martinwj2005@gmail.com>\n");
-       printf("multi-threaded and enhanced by neinbrucke (version 0.6.3)\n");
-       printf("http://www.freerainbowtables.com/\n");
-       printf("original code by Zhu Shuanglei <shuanglei@hotmail.com>\n");
-       printf("http://www.antsight.com/zsl/rainbowcrack/\n\n");
-}
-
-// XXX nmap is GPL2, will check newer releases regarding license
-// Code comes from nmap, used for the linux implementation of kbhit()
-#ifndef _WIN32
-
-static int tty_fd = 0;
-struct termios saved_ti;
-
-int tty_getchar()
-{
-       int c, numChars;
-
-       if (tty_fd && tcgetpgrp(tty_fd) == getpid()) {
-               c = 0;
-               numChars = read(tty_fd, &c, 1);
-               if (numChars > 0) return c;
-       }
-
-       return -1;
-}
-
-void tty_done()
-{
-       if (!tty_fd) return;
-
-       tcsetattr(tty_fd, TCSANOW, &saved_ti);
-
-       close(tty_fd);
-       tty_fd = 0;
-}
-
-void tty_init()
-{
-       struct termios ti;
-
-       if (tty_fd)
-               return;
-
-       if ((tty_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return;
-
-       tcgetattr(tty_fd, &ti);
-       saved_ti = ti;
-       ti.c_lflag &= ~(ICANON | ECHO);
-       ti.c_cc[VMIN] = 1;
-       ti.c_cc[VTIME] = 0;
-       tcsetattr(tty_fd, TCSANOW, &ti);
-
-       atexit(tty_done);
-}
-
-void tty_flush(void)
-{
-       tcflush(tty_fd, TCIFLUSH);
-}
-// end nmap code
-#endif
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, version 2 of the License.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "Public.h"\r
+\r
+#ifdef _WIN32\r
+       #include <windows.h>\r
+#endif\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #include <windows.h>\r
+       #include <time.h>\r
+\r
+       #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)\r
+               #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64\r
+       #else\r
+               #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL\r
+       #endif\r
\r
+       struct timezone\r
+       {\r
+               int  tz_minuteswest; /* minutes W of Greenwich */\r
+               int  tz_dsttime;     /* type of dst correction */\r
+       };\r
\r
+       int gettimeofday(struct timeval *tv, struct timezone *tz)\r
+       {\r
+               // Define a structure to receive the current Windows filetime\r
+               FILETIME ft;\r
\r
+               // Initialize the present time to 0 and the timezone to UTC\r
+               unsigned __int64 tmpres = 0;\r
+               static int tzflag = 0;\r
\r
+               if (NULL != tv)\r
+               {\r
+                       GetSystemTimeAsFileTime(&ft);\r
\r
+                       // The GetSystemTimeAsFileTime returns the number of 100 nanosecond \r
+                       // intervals since Jan 1, 1601 in a structure. Copy the high bits to \r
+                       // the 64 bit tmpres, shift it left by 32 then or in the low 32 bits.\r
+                       tmpres |= ft.dwHighDateTime;\r
+                       tmpres <<= 32;\r
+                       tmpres |= ft.dwLowDateTime;\r
\r
+                       // Convert to microseconds by dividing by 10\r
+                       tmpres /= 10;\r
\r
+                       // The Unix epoch starts on Jan 1 1970.  Need to subtract the difference \r
+                       // in seconds from Jan 1 1601.\r
+                       tmpres -= DELTA_EPOCH_IN_MICROSECS;\r
+        \r
+                       // Finally change microseconds to seconds and place in the seconds value. \r
+                       // The modulus picks up the microseconds.\r
+                       tv->tv_sec = (long)(tmpres / 1000000UL);\r
+                       tv->tv_usec = (long)(tmpres % 1000000UL);\r
+               }\r
+        \r
+               if (NULL != tz)\r
+               {\r
+                       if (!tzflag)\r
+                       {\r
+                               _tzset();\r
+                               tzflag++;\r
+                       }\r
+         \r
+                       // Adjust for the timezone west of Greenwich\r
+                       tz->tz_minuteswest = _timezone / 60;\r
+                       tz->tz_dsttime = _daylight;\r
+               }\r
+        \r
+               return 0;\r
+       }\r
+\r
+#elif defined(__APPLE__) || \\r
+       ((defined(__unix__) || defined(unix)) && !defined(USG))\r
+\r
+       #include <sys/param.h>\r
+\r
+       #if defined(BSD)\r
+               #include <sys/sysctl.h>\r
+       #elif defined(__linux__)\r
+               #include <sys/sysinfo.h>\r
+       #else\r
+               #error Unsupported Operating System\r
+       #endif\r
+#endif\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+timeval sub_timeofday( timeval tv2, timeval tv )\r
+{\r
+       timeval final;\r
+\r
+       final.tv_usec = tv2.tv_usec - tv.tv_usec;\r
+       final.tv_sec = tv2.tv_sec - tv.tv_sec;\r
+\r
+       if ( final.tv_usec < 0 )\r
+       {\r
+               final.tv_usec += 1000000;\r
+               --final.tv_sec;\r
+       }\r
+\r
+       return final;\r
+}\r
+\r
+long GetFileLen(FILE* file)\r
+{\r
+       // XXX on x86/x86_64 linux returns long\r
+       // 32-bit this is a problem if the file is > (2^31-1) bytes\r
+       long pos = ftell(file);\r
+       fseek(file, 0, SEEK_END);\r
+       long len = ftell(file);\r
+       fseek(file, pos, SEEK_SET);\r
+\r
+       return len;\r
+}\r
+\r
+string TrimString(string s)\r
+{\r
+       while (s.size() > 0)\r
+       {\r
+               if (s[0] == ' ' || s[0] == '\t')\r
+                       s = s.substr(1);\r
+               else\r
+                       break;\r
+       }\r
+\r
+       while (s.size() > 0)\r
+       {\r
+               if (s[s.size() - 1] == ' ' || s[s.size() - 1] == '\t')\r
+                       s = s.substr(0, s.size() - 1);\r
+               else\r
+                       break;\r
+       }\r
+\r
+       return s;\r
+}\r
+bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset)\r
+{\r
+       // Example: hybrid(mixalpha-numeric-all-space#1-6,numeric#1-4)\r
+       if(sCharset.substr(0, 6) != "hybrid") // Not hybrid charset\r
+               return false;\r
+\r
+       string::size_type nEnd = sCharset.rfind(')');\r
+       string::size_type nStart = (int) sCharset.rfind('(');\r
+       string sChar = sCharset.substr(nStart + 1, nEnd - nStart - 1);\r
+       vector<string> vParts;\r
+       SeperateString(sChar, ",", vParts);\r
+       for(uint32 i = 0; i < vParts.size(); i++)\r
+       {\r
+               tCharset stCharset;\r
+               vector<string> vParts2;\r
+               SeperateString(vParts[i], "#", vParts2);\r
+               stCharset.sName = vParts2[0];\r
+               vector<string> vParts3;\r
+               SeperateString(vParts2[1], "-", vParts3);\r
+               stCharset.nPlainLenMin = atoi(vParts3[0].c_str());\r
+               stCharset.nPlainLenMax = atoi(vParts3[1].c_str());\r
+               vCharset.push_back(stCharset);\r
+       }\r
+       return true;\r
+}\r
+#ifdef BOINC\r
+bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine)\r
+{\r
+       vLine.clear();\r
+       char input_path[512];\r
+       boinc_resolve_filename(sPathName.c_str(), input_path, sizeof(input_path));\r
+       FILE *file = boinc_fopen(input_path, "rb");\r
+       if (!file) {\r
+               fprintf(stderr,\r
+                       "Couldn't find input file, resolved name %s.\n", input_path\r
+               );\r
+               exit(-1);\r
+       }\r
+\r
+       if (file != NULL)\r
+       {\r
+               long len = GetFileLen(file);\r
+               char* data = new char[len + 1];\r
+               fread(data, 1, len, file);\r
+               data[len] = '\0';\r
+               string content = data;\r
+               content += "\n";\r
+               delete [] data;\r
+\r
+               unsigned int i;\r
+               for (i = 0; i < content.size(); i++)\r
+               {\r
+                       if (content[i] == '\r')\r
+                               content[i] = '\n';\r
+               }\r
+\r
+               string::size_type n;\r
+               while ((n = content.find("\n", 0)) != string::npos)\r
+               {\r
+                       string line = content.substr(0, n);\r
+                       line = TrimString(line);\r
+                       if (line != "")\r
+                               vLine.push_back(line);\r
+                       content = content.substr(n + 1);\r
+               }\r
+\r
+               fclose(file);\r
+       }\r
+       else\r
+               return false;\r
+\r
+       return true;\r
+}\r
+#endif\r
+bool ReadLinesFromFile(string sPathName, vector<string>& vLine)\r
+{\r
+       vLine.clear();\r
+\r
+       FILE* file = fopen(sPathName.c_str(), "rb");\r
+       if (file != NULL)\r
+       {\r
+               long len = GetFileLen(file);\r
+               char* data = new char[len + 1];\r
+               fread(data, 1, len, file);\r
+               data[len] = '\0';\r
+               string content = data;\r
+               content += "\n";\r
+               delete [] data;\r
+\r
+               unsigned int i;\r
+               for (i = 0; i < content.size(); i++)\r
+               {\r
+                       if (content[i] == '\r')\r
+                               content[i] = '\n';\r
+               }\r
+\r
+               string::size_type n;\r
+               while ((n = content.find("\n", 0)) != string::npos)\r
+               {\r
+                       string line = content.substr(0, n);\r
+                       line = TrimString(line);\r
+                       if (line != "")\r
+                               vLine.push_back(line);\r
+                       content = content.substr(n + 1);\r
+               }\r
+\r
+               fclose(file);\r
+       }\r
+       else\r
+               return false;\r
+\r
+       return true;\r
+}\r
+\r
+bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary)\r
+{\r
+       FILE* file = fopen(sOutputFile.c_str(), "a");\r
+       if (file!=NULL)\r
+       {\r
+               string buffer = sHash + ":" + sPlain + ":" + sBinary + "\n";\r
+               fputs (buffer.c_str(), file);\r
+               fclose (file);\r
+               return true;\r
+       }\r
+       else\r
+               return false;\r
+}\r
+\r
+bool SeperateString(string s, string sSeperator, vector<string>& vPart)\r
+{\r
+       vPart.clear();\r
+\r
+       unsigned int i;\r
+       for (i = 0; i < sSeperator.size(); i++)\r
+       {\r
+               string::size_type n;\r
+               if ( (n = s.find(sSeperator[i])) != string::npos)\r
+               {\r
+                       vPart.push_back(s.substr(0, n));\r
+                       s = s.substr(n + 1);\r
+               }\r
+               else\r
+               {\r
+                       printf("not found: %c\n", sSeperator[i]);\r
+                       printf("s: %s\n", s.c_str());\r
+                       return false;\r
+               }\r
+       }\r
+       vPart.push_back(s);\r
+\r
+       return true;\r
+}\r
+\r
+string uint64tostr(uint64 n)\r
+{\r
+       char str[32];\r
+\r
+#ifdef _WIN32\r
+       sprintf(str, "%I64u", n);\r
+#else\r
+       sprintf(str, "%llu", n);\r
+#endif\r
+\r
+       return str;\r
+}\r
+\r
+string uint64tohexstr(uint64 n)\r
+{\r
+       char str[32];\r
+\r
+#ifdef _WIN32\r
+       sprintf(str, "%016I64x", n);\r
+#else\r
+       sprintf(str, "%016llx", n);\r
+#endif\r
+\r
+       return str;\r
+}\r
+\r
+string HexToStr(const unsigned char* pData, int nLen)\r
+{\r
+       string sRet;\r
+       int i;\r
+       for (i = 0; i < nLen; i++)\r
+       {\r
+               char szByte[3];\r
+               sprintf(szByte, "%02x", pData[i]);\r
+               sRet += szByte;\r
+       }\r
+\r
+       return sRet;\r
+}\r
+\r
+unsigned long GetAvailPhysMemorySize()\r
+{\r
+#ifdef _WIN32\r
+       MEMORYSTATUS ms;\r
+       GlobalMemoryStatus(&ms);\r
+       return ms.dwAvailPhys;\r
+#elif defined(BSD)\r
+       int mib[2] = { CTL_HW, HW_PHYSMEM };\r
+       uint64 physMem;\r
+       //XXX warning size_t isn't portable\r
+       size_t len;\r
+       len = sizeof(physMem);\r
+       sysctl(mib, 2, &physMem, &len, NULL, 0);\r
+       return physMem;\r
+#elif defined(__linux__)\r
+       struct sysinfo info;\r
+       sysinfo(&info);\r
+       return ( info.freeram + info.bufferram ) * (unsigned long) info.mem_unit;\r
+#else\r
+       return 0;\r
+       #error Unsupported Operating System\r
+#endif\r
+}\r
+\r
+string GetApplicationPath()\r
+{\r
+       char fullPath[FILENAME_MAX];\r
+\r
+#ifdef _WIN32\r
+       GetModuleFileName(NULL, fullPath, FILENAME_MAX);\r
+#else\r
+       char szTmp[32];\r
+       // XXX linux/proc file system dependent\r
+       sprintf(szTmp, "/proc/%d/exe", getpid());\r
+       int bytes = readlink(szTmp, fullPath, FILENAME_MAX);\r
+\r
+       if( bytes >= 0 )\r
+               fullPath[bytes] = '\0';\r
+#endif\r
+\r
+       string sApplicationPath = fullPath;\r
+#ifdef _WIN32\r
+       string::size_type nIndex = sApplicationPath.find_last_of('\\');\r
+#else\r
+       string::size_type nIndex = sApplicationPath.find_last_of('/');\r
+#endif\r
+\r
+       if ( nIndex != string::npos )\r
+               sApplicationPath = sApplicationPath.substr(0, nIndex+1);\r
+\r
+       return sApplicationPath;\r
+}\r
+\r
+void ParseHash(string sHash, unsigned char* pHash, int& nHashLen)\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < sHash.size() / 2; i++)\r
+       {\r
+               string sSub = sHash.substr(i * 2, 2);\r
+               int nValue;\r
+               sscanf(sSub.c_str(), "%02x", &nValue);\r
+               pHash[i] = (unsigned char)nValue;\r
+       }\r
+\r
+       nHashLen = (int) sHash.size() / 2;\r
+}\r
+\r
+void Logo()\r
+{\r
+       printf("RainbowCrack (improved, multi-threaded) - Making a Faster Cryptanalytic Time-Memory Trade-Off\n");\r
+       printf("by Martin Westergaard <martinwj2005@gmail.com>\n");\r
+       printf("multi-threaded and enhanced by neinbrucke (version 0.6.3)\n");\r
+       printf("http://www.freerainbowtables.com/\n");\r
+       printf("original code by Zhu Shuanglei <shuanglei@hotmail.com>\n");\r
+       printf("http://www.antsight.com/zsl/rainbowcrack/\n\n");\r
+}\r
+\r
+// XXX nmap is GPL2, will check newer releases regarding license\r
+// Code comes from nmap, used for the linux implementation of kbhit()\r
+#ifndef _WIN32\r
+\r
+static int tty_fd = 0;\r
+struct termios saved_ti;\r
+\r
+int tty_getchar()\r
+{\r
+       int c, numChars;\r
+\r
+       if (tty_fd && tcgetpgrp(tty_fd) == getpid()) {\r
+               c = 0;\r
+               numChars = read(tty_fd, &c, 1);\r
+               if (numChars > 0) return c;\r
+       }\r
+\r
+       return -1;\r
+}\r
+\r
+void tty_done()\r
+{\r
+       if (!tty_fd) return;\r
+\r
+       tcsetattr(tty_fd, TCSANOW, &saved_ti);\r
+\r
+       close(tty_fd);\r
+       tty_fd = 0;\r
+}\r
+\r
+void tty_init()\r
+{\r
+       struct termios ti;\r
+\r
+       if (tty_fd)\r
+               return;\r
+\r
+       if ((tty_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return;\r
+\r
+       tcgetattr(tty_fd, &ti);\r
+       saved_ti = ti;\r
+       ti.c_lflag &= ~(ICANON | ECHO);\r
+       ti.c_cc[VMIN] = 1;\r
+       ti.c_cc[VTIME] = 0;\r
+       tcsetattr(tty_fd, TCSANOW, &ti);\r
+\r
+       atexit(tty_done);\r
+}\r
+\r
+void tty_flush(void)\r
+{\r
+       tcflush(tty_fd, TCIFLUSH);\r
+}\r
+// end nmap code\r
+#endif\r
index 89bbc805ed981ff2bd10f27bf07e17f54f810c72..d359371b98cd756265a7d1dc0d1dff0c1a7b0633 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, version 2 of the License.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef _PUBLIC_H
-#define _PUBLIC_H
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <string>
-#include <vector>
-#include <list>
-
-#include "global.h"
-
-using namespace std;
-
-
-struct RainbowChainO
-{
-       uint64 nIndexS;
-       uint64 nIndexE;
-};
-//struct RainbowChain
-//{
-//     //uint64 nChain;
-//     uint64 nIndexS;
-//     int nIndexE;
-//     int nCheckPoint;
-//};
-union RainbowChain
-{
-       //uint64 nChain;
-       uint64 nIndexS; 
-       struct
-       {
-               unsigned short foo[3];
-               unsigned short nIndexE;
-       };
-       //int nCheckPoint;
-};
-//struct RainbowChain
-//{
-//     uint64 nIndexS : 48;
-//     unsigned short nIndexE : 16;
-//};
-//struct IndexChain
-//{
-//     uint64 nPrefix;
-//     int nFirstChain;
-//     int nChainCount;
-//     //unsigned short nChainCount; //(maybe union with nPrefix, 1 byte spoiled)
-//};
-#pragma pack(1)
-union IndexChain
-{
-       uint64 nPrefix; //5
-       struct
-       {
-               unsigned char foo[5];
-               int nFirstChain; //4
-               unsigned short nChainCount; //2
-       };
-       //unsigned short nChainCount; (maybe union with nPrefix, 1 byte spoiled, no pack(1) needed)
-};
-#pragma pack()
-typedef struct
-{
-       string sName;
-       int nPlainLenMin;
-       int nPlainLenMax;
-} tCharset;
-
-#define MAX_PLAIN_LEN 256
-#define MIN_HASH_LEN  8
-#define MAX_HASH_LEN  256
-#define MAX_SALT_LEN  256
-
-// XXX nmap is GPL2, will check newer releases regarding license
-// Code comes from nmap, used for the linux implementation of kbhit()
-#ifndef _WIN32
-#include <unistd.h>
-#include <termios.h>
-#include <fcntl.h>
-
-int tty_getchar();
-void tty_done();
-void tty_init();
-void tty_flush(void);
-// end nmap code
-#endif
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       int gettimeofday( struct timeval *tv, struct timezone *tz );
-#endif
-
-#if !defined(_WIN32) || defined(__GNUC__)
-       #include <sys/time.h>
-#endif
-
-timeval sub_timeofday( timeval tv2, timeval tv );
-
-unsigned int GetFileLen(FILE* file);
-string TrimString(string s);
-bool ReadLinesFromFile(string sPathName, vector<string>& vLine);
-bool SeperateString(string s, string sSeperator, vector<string>& vPart);
-string uint64tostr(uint64 n);
-string uint64tohexstr(uint64 n);
-string HexToStr(const unsigned char* pData, int nLen);
-uint64 GetAvailPhysMemorySize();
-string GetApplicationPath();
-void ParseHash(string sHash, unsigned char* pHash, int& nHashLen);
-bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset);
-void Logo();
-bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary);
-
-#endif
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, version 2 of the License.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#ifndef _PUBLIC_H\r
+#define _PUBLIC_H\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+#include <string>\r
+#include <vector>\r
+#include <list>\r
+\r
+#include "global.h"\r
+\r
+using namespace std;\r
+\r
+\r
+struct RainbowChainO\r
+{\r
+       uint64 nIndexS;\r
+       uint64 nIndexE;\r
+};\r
+//struct RainbowChain\r
+//{\r
+//     //uint64 nChain;\r
+//     uint64 nIndexS;\r
+//     int nIndexE;\r
+//     int nCheckPoint;\r
+//};\r
+union RainbowChain\r
+{\r
+       //uint64 nChain;\r
+       uint64 nIndexS; \r
+       struct\r
+       {\r
+               unsigned short foo[3];\r
+               unsigned short nIndexE;\r
+       };\r
+       //int nCheckPoint;\r
+};\r
+//struct RainbowChain\r
+//{\r
+//     uint64 nIndexS : 48;\r
+//     unsigned short nIndexE : 16;\r
+//};\r
+//struct IndexChain\r
+//{\r
+//     uint64 nPrefix;\r
+//     int nFirstChain;\r
+//     int nChainCount;\r
+//     //unsigned short nChainCount; //(maybe union with nPrefix, 1 byte spoiled)\r
+//};\r
+#pragma pack(1)\r
+union IndexChain\r
+{\r
+       uint64 nPrefix; //5\r
+       struct\r
+       {\r
+               unsigned char foo[5];\r
+               int nFirstChain; //4\r
+               unsigned short nChainCount; //2\r
+       };\r
+       //unsigned short nChainCount; (maybe union with nPrefix, 1 byte spoiled, no pack(1) needed)\r
+};\r
+#pragma pack()\r
+typedef struct\r
+{\r
+       string sName;\r
+       int nPlainLenMin;\r
+       int nPlainLenMax;\r
+} tCharset;\r
+\r
+#define MAX_PLAIN_LEN 256\r
+#define MIN_HASH_LEN  8\r
+#define MAX_HASH_LEN  256\r
+#define MAX_SALT_LEN  256\r
+\r
+// XXX nmap is GPL2, will check newer releases regarding license\r
+// Code comes from nmap, used for the linux implementation of kbhit()\r
+#ifndef _WIN32\r
+#include <unistd.h>\r
+#include <termios.h>\r
+#include <fcntl.h>\r
+\r
+int tty_getchar();\r
+void tty_done();\r
+void tty_init();\r
+void tty_flush(void);\r
+// end nmap code\r
+#endif\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       int gettimeofday( struct timeval *tv, struct timezone *tz );\r
+#endif\r
+\r
+#if !defined(_WIN32) || defined(__GNUC__)\r
+       #include <sys/time.h>\r
+#endif\r
+\r
+timeval sub_timeofday( timeval tv2, timeval tv );\r
+\r
+long GetFileLen(FILE* file);\r
+string TrimString(string s);\r
+bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine);\r
+bool ReadLinesFromFile(string sPathName, vector<string>& vLine);\r
+bool SeperateString(string s, string sSeperator, vector<string>& vPart);\r
+string uint64tostr(uint64 n);\r
+string uint64tohexstr(uint64 n);\r
+string HexToStr(const unsigned char* pData, int nLen);\r
+unsigned long GetAvailPhysMemorySize();\r
+string GetApplicationPath();\r
+void ParseHash(string sHash, unsigned char* pHash, int& nHashLen);\r
+bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset);\r
+void Logo();\r
+bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary);\r
+\r
+#endif\r
diff --git a/Client Applications/rcracki_mt/RTI2Reader.cpp b/Client Applications/rcracki_mt/RTI2Reader.cpp
new file mode 100644 (file)
index 0000000..b1d5f96
--- /dev/null
@@ -0,0 +1,163 @@
+/*
+ * rcracki_mt is a multithreaded implementation and fork of the original 
+ * RainbowCrack
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of rcracki_mt.
+ *
+ * rcracki_mt is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * rcracki_mt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "RTI2Reader.h"
+
+#include <math.h>
+
+RTI2Header *RTI2Reader::m_pHeader = NULL;
+RTI2Reader::RTI2Reader(string Filename)
+{
+       //m_pIndexPos = NULL, m_pChainPos = NULL;;
+       m_pIndex = NULL;
+       m_pFile = fopen(Filename.c_str(), "rb");
+       if(m_pFile == NULL)
+       {
+               printf("Unable to open file %s", Filename.c_str());
+               exit(1);
+       }
+       FILE *pFileIndex = fopen(Filename.append(".index").c_str(), "rb");
+       if(pFileIndex == NULL)
+       {
+               printf("Unable to open file %s", Filename.append(".index").c_str());
+               exit(1);
+       }
+       m_chainPosition = 0;
+
+       long len = GetFileLen(pFileIndex);
+       fseek(pFileIndex, 0, SEEK_SET);
+
+       m_pIndex = new (nothrow) unsigned char[len];
+       if(m_pIndex == NULL) {
+               printf("Error allocating %ld MB memory for index in RTI2Reader::RTI2Reader()", len / (1024 * 1024));
+               exit(-2);
+       }
+       if(fread(m_pIndex, 1, len, pFileIndex) != (unsigned long)len)
+       {
+               printf("Error while reading index file");
+               exit(1);
+       }
+       fclose(pFileIndex);
+       m_pHeader = new RTI2Header();   
+       memcpy(m_pHeader, m_pIndex, sizeof(RTI2Header));
+       m_pHeader->m_cppos = (unsigned int*)(m_pIndex + 8);
+       m_pHeader->prefixstart = *(uint64*)(m_pIndex + 8 + (m_pHeader->rti_cplength * 4));
+       m_chainsizebytes = (uint32)ceil((float)(m_pHeader->rti_startptlength + m_pHeader->rti_endptlength + m_pHeader->rti_cplength) / 8); // Get the size of each chain in bytes
+       m_indexrowsizebytes = (uint32)ceil((float)m_pHeader->rti_index_numchainslength / 8);
+       // Check the filesize
+       fseek(m_pFile, 0, SEEK_END);
+       len = ftell(m_pFile);
+       fseek(m_pFile, 0, SEEK_SET);
+       if(len % m_chainsizebytes > 0)
+       {
+               printf("Invalid filesize %ld\n", len);
+               return;
+       }
+       
+
+}
+
+RTI2Reader::~RTI2Reader(void)
+{
+       if(m_pIndex != NULL) delete m_pIndex;
+       if(m_pFile != NULL) fclose(m_pFile);
+
+}
+
+unsigned int RTI2Reader::GetChainsLeft()
+{
+       long len = GetFileLen(m_pFile);
+       return len / m_chainsizebytes - m_chainPosition;
+}
+
+int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChainO *pData)
+{
+       if(strncmp(m_pHeader->header, "RTI2", 4) != 0)
+       {
+               numChains = 0;
+               return -1;
+       }
+       unsigned char *pNumChains = m_pIndex + (m_pHeader->rti_cplength * 4) + 16; // Pointer into the index containing info about how many numbers are in the first chain prefix
+       unsigned int i = 0;
+       unsigned int indexRow = 0; // Current offset into the index
+       unsigned int curRowPosition = 0;
+       
+       while(true) // Fast forward to current position
+       {
+               // ALERT: Possible problem here if m_indexrowsizebytes > 1 as pNumChains is a unsigned char.
+               unsigned int NumChainsInRow = (unsigned int)*(pNumChains + indexRow * m_indexrowsizebytes);
+               if(m_indexrowsizebytes > 1)
+               {
+                       //XXX Have to find a solution to this problem
+                       printf( "FATAL: m_indexrowsizebytes > 1: %d\n", m_indexrowsizebytes ); 
+                       exit(2);
+               }
+               if(i + NumChainsInRow > m_chainPosition)
+               {
+                       curRowPosition = m_chainPosition - i;
+                       break; // The current position is somewhere within this prefix
+               }
+               indexRow++;             
+               i += NumChainsInRow;
+       }
+       
+       uint64 chainrow = 0; // Buffer to store a single read chain
+       unsigned int chainsProcessed = 0; // Number of chains processed
+
+       // XXX: same problem with unsigned char here.
+       unsigned int NumChainsInRow = *(pNumChains + indexRow);
+       while(chainsProcessed < numChains && fread(&chainrow, 1, m_chainsizebytes, m_pFile) == m_chainsizebytes)
+       {
+               if(curRowPosition >= NumChainsInRow)
+               { // Skip to next index row position
+                       indexRow++;
+                       curRowPosition = 0;
+                       NumChainsInRow = *(pNumChains + indexRow);
+               }
+               while(NumChainsInRow == 0) // We skip forward until we hit a index with > 0 chains
+               {
+                       indexRow++;
+                       NumChainsInRow = *(pNumChains + indexRow);
+                       curRowPosition = 0;
+               }
+               // Load the starting point from the data
+               pData[chainsProcessed].nIndexS = chainrow << ( 64 - m_pHeader->rti_startptlength );
+               pData[chainsProcessed].nIndexS = pData[chainsProcessed].nIndexS >> ( 64 - m_pHeader->rti_startptlength );
+
+               // Load the ending point prefix 
+               pData[chainsProcessed].nIndexE = ( m_pHeader->prefixstart + indexRow ) << m_pHeader->rti_endptlength;
+               // Append the ending point suffix
+#if defined(_WIN32) && !defined(__GNUC__)
+               pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFI64 >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
+#else
+               pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFllu >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
+#endif
+               //pData[chainsProcessed].nCheckPoint = (chainrow >> m_pHeader->rti_startptlength + m_pHeader->rti_endptlength);
+               curRowPosition++;
+               chainsProcessed++;
+       }
+       numChains = chainsProcessed;
+       m_chainPosition += numChains;
+       return 0;
+}
diff --git a/Client Applications/rcracki_mt/RTI2Reader.h b/Client Applications/rcracki_mt/RTI2Reader.h
new file mode 100644 (file)
index 0000000..e0f5ed4
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * rcracki_mt is a multithreaded implementation and fork of the original 
+ * RainbowCrack
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of rcracki_mt.
+ *
+ * rcracki_mt is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * rcracki_mt is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __RTI2READER_H__
+#define __RTI2READER_H__
+
+#include "Public.h"
+#include <string>
+
+#if defined(_WIN32) && !defined(__GNUC__)
+       #include <io.h>
+#endif
+
+#include <vector>
+#include "BaseRTReader.h"
+
+using namespace std;
+
+typedef struct 
+{
+       char header[4];
+       unsigned char rti_startptlength, rti_endptlength, rti_cplength, rti_index_numchainslength;
+       uint64 prefixstart;
+       unsigned int *m_cppos;
+} RTI2Header;
+
+class RTI2Reader : BaseRTReader
+{
+private:
+       FILE *m_pFile;
+       uint32 m_chainPosition;
+       unsigned char *m_pPos, *m_pChainPos;
+       static RTI2Header *m_pHeader;
+       unsigned char *m_pIndex;
+       uint32 m_chainsizebytes;
+       uint32 m_indexrowsizebytes;
+       
+
+public:
+       RTI2Reader(string Filename);
+       ~RTI2Reader(void);
+       int ReadChains(uint32 &numChains, RainbowChainO *pData);
+       unsigned int GetChainsLeft();
+       static RTI2Header *GetHeader() { return m_pHeader; }
+};
+
+
+#endif
index ccd94217e10012c076aa81ecf195ced1234a6d35..812035411f55ffad9875543c12552ed8717f5614 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright 2009, 2010  Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009 James Dickson
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- * Copyright 2010 uroskn
- *
- * Modified by Martin Westergaard Jørgensen <martinwj2005@gmail.com> to support  * indexed and hybrid tables
- *
- * Modified by neinbrucke to support multi threading and a bunch of other stuff :)
- *
- * 2009-01-04 - <james.dickson@comhem.se> - Slightly modified (or "fulhack" as 
- * we say in sweden)  to support cain .lst files.
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "CrackEngine.h"
-#include "lm2ntlm.h"
-#include <algorithm>
-
-#ifdef _WIN32
-       #include <io.h>
-#else
-       #include <sys/types.h>
-       #include <sys/stat.h>
-       #include <unistd.h>
-       #include <dirent.h>
-#endif
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma comment(lib, "libeay32.lib")
-#endif
-
-//////////////////////////////////////////////////////////////////////
-
-#ifdef _WIN32
-void GetTableList(string sWildCharPathName, vector<string>& vPathName)
-{
-       //vPathName.clear();
-
-       string sPath;
-       string::size_type n = sWildCharPathName.find_last_of('\\');
-
-       if ( n == (sWildCharPathName.size() - 1) )
-       {
-               sWildCharPathName = sWildCharPathName.substr(0, n);
-               n = sWildCharPathName.find_last_of('\\');
-       }
-
-       if (n != string::npos)
-               sPath = sWildCharPathName.substr(0, n + 1);
-
-       _finddata_t fd;
-
-       long handle = _findfirst(sWildCharPathName.c_str(), &fd);
-       if (handle != -1)
-       {
-               do
-               {
-                       string sName = fd.name;
-                       if (sName.size()>3) {
-                               if (sName.substr(sName.size()-3, 3) == ".rt" && !(fd.attrib & _A_SUBDIR))
-                               {
-                                       string sPathName = sPath + sName;
-                                       vPathName.push_back(sPathName);
-                               }
-                       }
-                       if (sName.size()>4) {
-                               if (sName.substr(sName.size()-4, 4) == ".rti" && !(fd.attrib & _A_SUBDIR))
-                               {
-                                       string sPathName = sPath + sName;
-                                       vPathName.push_back(sPathName);
-                               }
-                       }
-                       if (sName.size()>5) {
-                               if (sName.substr(sName.size()-5, 5) == ".rti2" && !(fd.attrib & _A_SUBDIR))
-                               {
-                                       string sPathName = sPath + sName;
-                                       vPathName.push_back(sPathName);
-                               }
-                       }
-
-                       if (sName != "." && sName != ".." && (fd.attrib & _A_SUBDIR))
-                       {
-                               string sPath_sub = sPath + sName + '\\';
-                               string sWildCharPathName_sub = sPath_sub + '*';
-                               GetTableList(sWildCharPathName_sub, vPathName);
-                       }
-
-               } while (_findnext(handle, &fd) == 0);
-
-               _findclose(handle);
-       }
-       //printf("Found %d rainbowtables (files) in %d sub directories...\n", vPathName.size(), subDir_count);
-}
-#else
-//void GetTableList(int argc, char* argv[], vector<string>& vPathName)
-void GetTableList(string sWildCharPathName, vector<string>& vPathName)
-{
-       //vPathName.clear();
-
-       struct stat buf;
-       if (lstat(sWildCharPathName.c_str(), &buf) == 0)
-       {
-               if (S_ISDIR(buf.st_mode))
-               {
-                       DIR *dir = opendir(sWildCharPathName.c_str());
-                       if(dir)
-                       {
-                               struct dirent *pDir=NULL;
-                               while((pDir = readdir(dir)) != NULL)
-                               {
-                                       string filename = "";
-                                       filename += (*pDir).d_name;
-                                       if (filename != "." && filename != "..")
-                                       {
-                                               string new_filename = sWildCharPathName + '/' + filename;
-                                               GetTableList(new_filename, vPathName);
-                                       }
-                               }
-                               closedir(dir);
-                       }
-               }
-               else if (S_ISREG(buf.st_mode))
-               {
-                       if (sWildCharPathName.size()>3)
-                       {
-                               if (sWildCharPathName.substr(sWildCharPathName.size()-3, 3) == ".rt")
-                               {
-                                       vPathName.push_back(sWildCharPathName);
-                               }
-                       }
-                       if (sWildCharPathName.size()>4)
-                       {
-                               if (sWildCharPathName.substr(sWildCharPathName.size()-4, 4) == ".rti")
-                               {
-                                       //string sPathName_sub = sPath_sub + sName_sub;
-                                       vPathName.push_back(sWildCharPathName);
-                                       //printf("sPathName_sub: %s\n", sPathName_sub.c_str());
-                               }
-                       }
-                       if ( sWildCharPathName.size() > 5 )
-                       {
-                               if ( sWildCharPathName.substr( sWildCharPathName.size() - 5, 5 ) == ".rti2" )
-                               {
-                                       vPathName.push_back( sWildCharPathName );
-                               }
-                       }
-               }
-       }
-}
-#endif
-
-bool NormalizeHash(string& sHash)
-{
-       string sNormalizedHash = sHash;
-
-       if (   sNormalizedHash.size() % 2 != 0
-               || sNormalizedHash.size() < MIN_HASH_LEN * 2
-               || sNormalizedHash.size() > MAX_HASH_LEN * 2)
-               return false;
-
-       // Make lower
-       UINT4 i;
-       for (i = 0; i < sNormalizedHash.size(); i++)
-       {
-               if (sNormalizedHash[i] >= 'A' && sNormalizedHash[i] <= 'F')
-                       sNormalizedHash[i] = (char) sNormalizedHash[i] - 'A' + 'a';
-       }
-
-       // Character check
-       for (i = 0; i < sNormalizedHash.size(); i++)
-       {
-               if (   (sNormalizedHash[i] < 'a' || sNormalizedHash[i] > 'f')
-                       && (sNormalizedHash[i] < '0' || sNormalizedHash[i] > '9'))
-                       return false;
-       }
-
-       sHash = sNormalizedHash;
-       return true;
-}
-
-void LoadLMHashFromPwdumpFile(string sPathName, vector<string>& vUserName, vector<string>& vLMHash, vector<string>& vNTLMHash)
-{
-       vector<string> vLine;
-       if (ReadLinesFromFile(sPathName, vLine))
-       {
-               UINT4 i;
-               for (i = 0; i < vLine.size(); i++)
-               {
-                       vector<string> vPart;
-                       if (SeperateString(vLine[i], "::::", vPart))
-                       {
-                               string sUserName = vPart[0];
-                               string sLMHash   = vPart[2];
-                               string sNTLMHash = vPart[3];
-
-                               if (sLMHash.size() == 32 && sNTLMHash.size() == 32)
-                               {
-                                       if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash))
-                                       {
-                                               vUserName.push_back(sUserName);
-                                               vLMHash.push_back(sLMHash);
-                                               vNTLMHash.push_back(sNTLMHash);
-                                       }
-                                       else
-                                               printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str());
-                               }
-                       }
-               }
-       }
-       else
-               printf("can't open %s\n", sPathName.c_str());
-}
-
-// 2009-01-04 - james.dickson - Added this so we can load hashes from cain .LST files.
-void LoadLMHashFromCainLSTFile(string sPathName, vector<string>& vUserName, vector<string>& vLMHash, vector<string>& vNTLMHash)
-{
-       vector<string> vLine;
-       if (ReadLinesFromFile(sPathName, vLine))
-       {
-               UINT4 i;
-               for (i = 0; i < vLine.size(); i++)
-               {
-                       vector<string> vPart;
-                       if (SeperateString(vLine[i], "\t\t\t\t\t\t", vPart))
-                       {
-                               string sUserName = vPart[0];
-                               string sLMHash   = vPart[4];
-                               string sNTLMHash = vPart[5];
-
-                               if (sLMHash.size() == 32 && sNTLMHash.size() == 32)
-                               {
-                                       if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash))
-                                       {
-                                               vUserName.push_back(sUserName);
-                                               vLMHash.push_back(sLMHash);
-                                               vNTLMHash.push_back(sNTLMHash);
-                                       }
-                                       else
-                                               printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str());
-                               }
-                       }
-               }
-       }
-       else
-               printf("can't open %s\n", sPathName.c_str());
-}
-
-bool NTLMPasswordSeek(unsigned char* pLMPassword, int nLMPasswordLen, int nLMPasswordNext,
-                                         unsigned char* pNTLMHash, string& sNTLMPassword)
-{
-       if (nLMPasswordNext == nLMPasswordLen)
-       {
-               unsigned char md[MD4_DIGEST_LENGTH];
-               MD4_NEW(pLMPassword, nLMPasswordLen * 2, md);
-
-               if (memcmp(md, pNTLMHash, MD4_DIGEST_LENGTH) == 0)
-               {
-                       sNTLMPassword = "";
-                       int i;
-                       for (i = 0; i < nLMPasswordLen; i++)
-                               sNTLMPassword += char(pLMPassword[i * 2]);
-                       return true;
-               }
-               else
-                       return false;
-       }
-
-       if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword))
-               return true;
-
-       if (   pLMPassword[nLMPasswordNext * 2] >= 'A'
-               && pLMPassword[nLMPasswordNext * 2] <= 'Z')
-       {
-               pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'A' + 'a';
-               if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword))
-                       return true;
-               pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'a' + 'A';
-       }
-
-       return false;
-}
-
-bool LMPasswordCorrectCase(string sLMPassword, unsigned char* pNTLMHash, string& sNTLMPassword)
-{
-       if (sLMPassword.size() == 0)
-       {
-               sNTLMPassword = "";
-               return true;
-       }
-
-       unsigned char* pLMPassword = new unsigned char[sLMPassword.size() * 2];
-       UINT4 i;
-       for (i = 0; i < sLMPassword.size(); i++)
-       {
-               pLMPassword[i * 2    ] = sLMPassword[i];
-               pLMPassword[i * 2 + 1] = 0x00;
-       }
-       bool fRet = NTLMPasswordSeek(pLMPassword, sLMPassword.size(), 0, pNTLMHash, sNTLMPassword);
-
-       delete pLMPassword;
-
-       return fRet;
-}
-
-void Usage()
-{
-       Logo();
-
-       printf("usage: rcracki_mt -h hash rainbow_table_pathname\n");
-       printf("       rcracki_mt -l hash_list_file rainbow_table_pathname\n");
-       printf("       rcracki_mt -f pwdump_file rainbow_table_pathname\n");
-       printf("       rcracki_mt -c lst_file rainbow_table_pathname\n");
-       printf("\n");
-       printf("-h hash:                use raw hash as input\n");
-       printf("-l hash_list_file:      use hash list file as input, each hash in a line\n");
-       printf("-f pwdump_file:         use pwdump file as input, handles lanmanager hash only\n");
-       printf("-c lst_file:            use .lst (cain format) file as input\n");
-       printf("-r [-s session_name]:   resume from previous session, optional session name\n");
-       printf("rainbow_table_pathname: pathname(s) of the rainbow table(s)\n");
-       printf("\n");
-       printf("Extra options:    -t [nr] use this amount of threads/cores, default is 1\n");
-       printf("                  -o [output_file] write (temporary) results to this file\n");
-       printf("                  -s [session_name] write session data with this name\n");
-       printf("                  -k keep precalculation on disk\n");
-       printf("                  -m [megabytes] limit memory usage\n");
-       printf("                  -v show debug information\n");
-       printf("\n");
-#ifdef _WIN32
-       printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]\\MD5\n");
-       printf("         rcracki_mt -l hash.txt [path_to_specific_table]\\*\n");
-#else
-       printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]/MD5\n");
-       printf("         rcracki_mt -l hash.txt [path_to_specific_table]/*\n");
-#endif
-       printf("         rcracki_mt -f hash.txt -t 4 -o results.txt *.rti\n");
-}
-
-int main(int argc, char* argv[])
-{
-       if (argc < 2)
-       {
-               Usage();
-               return 0;
-       }
-
-       vector<string> vPathName;
-       vector<string> vDefaultRainbowTablePath;
-       string sWildCharPathName                        = "";
-       string sInputType                                               = "";
-       string sInput                                                   = "";
-       string outputFile                                               = "";
-       string sApplicationPath                         = "";
-       string sIniPathName                                     = "rcracki_mt.ini";
-       bool writeOutput                                                = false;
-       string sSessionPathName                         = "rcracki.session";
-       string sProgressPathName                        = "rcracki.progress";
-       string sPrecalcPathName                         = "rcracki.precalc";
-       bool resumeSession                                      = false;
-       bool useDefaultRainbowTablePath = false;
-       bool debug                                                              = false;
-       bool keepPrecalcFiles                           = false;
-       string sAlgorithm                                               = "";
-       int maxThreads                                                  = 1;
-       uint64 maxMem                                                   = 0;
-       CHashSet hs;
-
-       // Read defaults from ini file;
-       bool readFromIni = false;
-       vector<string> vLine;
-       if (ReadLinesFromFile(sIniPathName, vLine)) {
-               readFromIni = true;
-       }
-       else if (ReadLinesFromFile(GetApplicationPath() + sIniPathName, vLine)) {
-               readFromIni = true;
-       }
-       if (readFromIni)
-       {
-               UINT4 i;
-               for (i = 0; i < vLine.size(); i++)
-               {
-                       if (vLine[i].substr(0,1) != "#")
-                       {
-                               vector<string> vPart;
-                               if (SeperateString(vLine[i], "=", vPart))
-                               {
-                                       string sOption = vPart[0];
-                                       string sValue  = vPart[1];
-                                       
-                                       if (sOption == "Threads") {
-                                               maxThreads = atoi(sValue.c_str());
-                                       }
-                                       else if (sOption == "MaxMemoryUsage" ) {
-                                               maxMem = atoi(sValue.c_str()) * 1024 *1024;
-                                       }
-                                       else if (sOption == "DefaultResultsFile") {
-                                               outputFile = sValue;
-                                       }
-                                       else if (sOption == "AlwaysStoreResultsToFile") {
-                                               if (sValue == "1")
-                                                       writeOutput = true;
-                                       }
-                                       else if (sOption.substr(0,24) == "DefaultRainbowTablePath.") {
-                                               //printf("Default RT path: %s\n", sValue.c_str());
-                                               vDefaultRainbowTablePath.push_back(vLine[i]);
-                                       }
-                                       else if (sOption == "DefaultAlgorithm") {
-                                               useDefaultRainbowTablePath = true;
-                                               sAlgorithm = sValue;
-                                       }
-                                       else if (sOption == "AlwaysDebug") {
-                                               if (sValue == "1")
-                                                       debug = true;
-                                       }
-                                       else if (sOption == "AlwaysKeepPrecalcFiles") {
-                                               if (sValue == "1")
-                                                       keepPrecalcFiles = true;
-                                       }
-                                       else {
-                                               printf("illegal option %s in ini file %s\n", sOption.c_str(), sIniPathName.c_str());
-                                               return 0;
-                                       }
-                               }
-                       }
-               }
-               if (writeOutput && outputFile == "")
-               {
-                       printf("You need to specify a 'DefaultResultsFile' with 'AlwaysStoreResultsToFile=1'\n");
-                       writeOutput = false;
-               }
-       }
-
-       // Parse command line arguments
-       int i;
-       for (i = 1; i < argc; i++)
-       {
-               string cla = argv[i];
-               if (cla == "-h") {
-                       sInputType = cla;
-                       i++;
-                       if (i < argc)
-                               sInput = argv[i];
-               }
-               else if (cla == "-l") {
-                       sInputType = cla;
-                       i++;
-                       if (i < argc)
-                               sInput = argv[i];
-               }
-               else if (cla == "-f") {
-                       sInputType = cla;
-                       i++;
-                       if (i < argc)
-                               sInput = argv[i];
-               }
-               else if (cla == "-c") {
-                       sInputType = cla;
-                       i++;
-                       if (i < argc)
-                               sInput = argv[i];
-               }
-               else if (cla == "-t") {
-                       i++;
-                       if (i < argc)
-                               maxThreads = atoi(argv[i]);
-               }
-               else if ( cla == "-m" ) {
-                       i++;
-                       if ( i < argc )
-                               maxMem = atoi(argv[i]) * 1024 * 1024;
-               }
-               else if (cla == "-o") {
-                       writeOutput = true;
-                       i++;
-                       if (i < argc)
-                               outputFile = argv[i];
-               }
-               else if (cla == "-r") {
-                       resumeSession = true;
-               }
-               else if (cla == "-s") {
-                       i++;
-                       if (i < argc)
-                       {
-                               sSessionPathName                =  argv[i];
-                               sSessionPathName                += ".session";
-                               sProgressPathName               =  argv[i];
-                               sProgressPathName               += ".progress";
-                               sPrecalcPathName                =  argv[i];
-                               sPrecalcPathName                += ".precalc";
-                       }
-               }
-               else if (cla == "-v") {
-                       debug = true;
-               }
-               else if (cla == "-k") {
-                       keepPrecalcFiles = true;
-               }
-               else if (cla == "-a") {
-                       useDefaultRainbowTablePath = true;
-                       i++;
-                       if (i < argc)
-                               sAlgorithm = argv[i];
-               }
-               else {
-                       GetTableList(cla, vPathName);
-               }
-       }
-
-       if (debug && !readFromIni)
-               printf("Debug: Couldn't read rcracki_mt.ini, continuing anyway.\n");
-
-       // Load session data if we are resuming
-       if (resumeSession)
-       {
-               vPathName.clear();
-               vector<string> sSessionData;
-               if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData))
-               {
-                       UINT4 i;
-                       for (i = 0; i < sSessionData.size(); i++)
-                       {
-                               vector<string> vPart;
-                               if (SeperateString(sSessionData[i], "=", vPart))
-                               {
-                                       string sOption = vPart[0];
-                                       string sValue  = vPart[1];
-                                       
-                                       if (sOption == "sPathName") {
-                                               vPathName.push_back(sValue);
-                                       }
-                                       else if (sOption == "sInputType") {
-                                               sInputType = sValue;
-                                       }
-                                       else if (sOption == "sInput") {
-                                               sInput = sValue;
-                                       }
-                                       else if (sOption == "outputFile") {
-                                               writeOutput = true;
-                                               outputFile = sValue;
-                                       }
-                                       else if (sOption == "keepPrecalcFiles") {
-                                               if (sValue == "1")
-                                                       keepPrecalcFiles = true;
-                                       }
-                               }
-                       }
-               }
-               else {
-                       printf("Couldn't open session file %s\n", sSessionPathName.c_str());
-                       return 0;
-               }
-       }
-
-       if (maxThreads<1)
-               maxThreads = 1;
-
-       // don't load these if we are resuming a session that already has a list of tables
-       if (useDefaultRainbowTablePath && !resumeSession)
-       {
-               UINT4 i;
-               for (i = 0; i < vDefaultRainbowTablePath.size(); i++)
-               {
-                       vector<string> vPart;
-                       if (SeperateString(vDefaultRainbowTablePath[i], ".=", vPart))
-                       {
-                               string lineAlgorithm = vPart[1];
-                               string linePath = vPart[2];
-
-                               if (lineAlgorithm == sAlgorithm)
-                                       GetTableList(linePath, vPathName);
-                       }
-               }
-       }
-
-       printf("Using %d threads for pre-calculation and false alarm checking...\n", maxThreads);
-
-       setvbuf(stdout, NULL, _IONBF,0);
-       if (vPathName.size() == 0)
-       {
-               printf("no rainbow table found\n");
-               return 0;
-       }
-       printf("Found %lu rainbowtable files...\n\n",
-               (unsigned long)vPathName.size());
-
-       bool fCrackerType;                      // true: hash cracker, false: lm cracker
-       vector<string> vHash;           // hash cracker
-       vector<string> vUserName;       // lm cracker
-       vector<string> vLMHash;         // lm cracker
-       vector<string> vNTLMHash;       // lm cracker
-       if (sInputType == "-h")
-       {
-               fCrackerType = true;
-
-               string sHash = sInput;
-               if (NormalizeHash(sHash))
-                       vHash.push_back(sHash);
-               else
-                       printf("invalid hash: %s\n", sHash.c_str());
-       }
-       else if (sInputType == "-l")
-       {
-               fCrackerType = true;
-
-               string sPathName = sInput;
-               vector<string> vLine;
-               if (ReadLinesFromFile(sPathName, vLine))
-               {
-                       UINT4 i;
-                       for (i = 0; i < vLine.size(); i++)
-                       {
-                               string sHash = vLine[i];
-                               if (NormalizeHash(sHash))
-                                       vHash.push_back(sHash);
-                               else
-                                       printf("invalid hash: %s\n", sHash.c_str());
-                       }
-               }
-               else
-                       printf("can't open %s\n", sPathName.c_str());
-       }
-       else if (sInputType == "-f")
-       {
-               fCrackerType = false;
-
-               string sPathName = sInput;
-               LoadLMHashFromPwdumpFile(sPathName, vUserName, vLMHash, vNTLMHash);
-       }
-       else if (sInputType == "-c")
-       {
-               // 2009-01-04 - james.dickson - Added this for cain-files.
-               fCrackerType = false;
-               string sPathName = sInput;
-               LoadLMHashFromCainLSTFile(sPathName, vUserName, vLMHash, vNTLMHash);
-       }
-       else
-       {
-               Usage();
-               return 0;
-       }
-
-       if (fCrackerType && vHash.size() == 0)
-       {
-               printf("no hashes found");
-               return 0;
-       }
-       if (!fCrackerType && vLMHash.size() == 0)
-       {
-               return 0;
-               printf("no hashes found");
-       }
-
-       if (fCrackerType)
-       {
-               UINT4 i;
-               for (i = 0; i < vHash.size(); i++)
-                       hs.AddHash(vHash[i]);
-       }
-       else
-       {
-               UINT4 i;
-               for (i = 0; i < vLMHash.size(); i++)
-               {
-                       hs.AddHash(vLMHash[i].substr(0, 16));
-                       hs.AddHash(vLMHash[i].substr(16, 16));
-               }
-       }
-
-       // Load found hashes from session file
-       if (resumeSession)
-       {
-               vector<string> sSessionData;
-               if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData))
-               {
-                       UINT4 i;
-                       for (i = 0; i < sSessionData.size(); i++)
-                       {
-                               vector<string> vPart;
-                               if (SeperateString(sSessionData[i], "=", vPart))
-                               {
-                                       string sOption = vPart[0];
-                                       string sValue  = vPart[1];
-                                       
-                                       if (sOption == "sHash") {
-                                               vector<string> vPartHash;
-                                               if (SeperateString(sValue, "::", vPartHash))
-                                               {
-                                                       string sHash = vPartHash[0];
-                                                       string sBinary = vPartHash[1];
-                                                       string sPlain = vPartHash[2];
-                                                       
-                                                       hs.SetPlain(sHash, sPlain, sBinary);
-                                               }
-                                       }
-                               }
-                       }
-               }
-       }
-
-       // (Over)write session data if we are not resuming
-       if (!resumeSession)
-       {
-               FILE* file = fopen(sSessionPathName.c_str(), "w");
-               string buffer = "";
-
-               if (file!=NULL)
-               {
-                       buffer += "sInputType=" + sInputType + "\n";
-                       buffer += "sInput=" + sInput + "\n";
-
-                       UINT4 i;
-                       for (i = 0; i < vPathName.size(); i++)
-                       {
-                               buffer += "sPathName=" + vPathName[i] + "\n";
-                       }
-
-                       if (writeOutput)
-                               buffer += "outputFile=" + outputFile + "\n";
-
-                       if (keepPrecalcFiles)
-                               buffer += "keepPrecalcFiles=1\n";
-
-                       fputs (buffer.c_str(), file);
-                       fclose (file);
-               }
-               file = fopen(sProgressPathName.c_str(), "w");
-               fclose (file);
-       }
-
-       // Run
-       CCrackEngine ce;
-       if (writeOutput)
-               ce.setOutputFile(outputFile);
-       ce.setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles);
-       ce.Run(vPathName, hs, maxThreads, maxMem, resumeSession, debug);
-
-       // Remove session files
-       if (debug) printf("Debug: Removing session files.\n");
-
-       if (remove(sSessionPathName.c_str()) == 0)
-               remove(sProgressPathName.c_str());
-       else
-               if (debug) printf("Debug: Failed removing session files.\n");
-
-       // Statistics
-       printf("statistics\n");
-       printf("-------------------------------------------------------\n");
-       printf("plaintext found:            %d of %d (%.2f%%)\n", hs.GetStatHashFound(),
-                                                                                                                       hs.GetStatHashTotal(),
-                                                                                                                       100.0f * hs.GetStatHashFound() / hs.GetStatHashTotal());
-       printf("total disk access time:     %.2f s\n", ce.GetStatTotalDiskAccessTime());
-       printf("total cryptanalysis time:   %.2f s\n", ce.GetStatTotalCryptanalysisTime());
-       printf("total pre-calculation time: %.2f s\n", ce.GetStatTotalPrecalculationTime());
-       printf("total chain walk step:      %d\n",     ce.GetStatTotalChainWalkStep());
-       printf("total false alarm:          %d\n",     ce.GetStatTotalFalseAlarm());
-       printf("total chain walk step due to false alarm: %d\n", ce.GetStatTotalChainWalkStepDueToFalseAlarm());
-//     printf("total chain walk step skipped due to checkpoints: %d\n", ce.GetStatTotalFalseAlarmSkipped()); // Checkpoints not used - yet
-       printf("\n");
-
-       // Result
-       printf("result\n");
-       printf("-------------------------------------------------------\n");
-       if (fCrackerType)
-       {
-               UINT4 i;
-               for (i = 0; i < vHash.size(); i++)
-               {
-                       string sPlain, sBinary;
-                       if (!hs.GetPlain(vHash[i], sPlain, sBinary))
-                       {
-                               sPlain  = "<notfound>";
-                               sBinary = "<notfound>";
-                       }
-
-                       printf("%s\t%s\thex:%s\n", vHash[i].c_str(), sPlain.c_str(), sBinary.c_str());
-               }
-       }
-       else
-       {
-               UINT4 i;
-               for (i = 0; i < vLMHash.size(); i++)
-               {
-                       string sPlain1, sBinary1;
-                       bool fPart1Found = hs.GetPlain(vLMHash[i].substr(0, 16), sPlain1, sBinary1);
-                       if (!fPart1Found)
-                       {
-                               sPlain1  = "<notfound>";
-                               sBinary1 = "<notfound>";
-                       }
-
-                       string sPlain2, sBinary2;
-                       bool fPart2Found = hs.GetPlain(vLMHash[i].substr(16, 16), sPlain2, sBinary2);
-                       if (!fPart2Found)
-                       {
-                               sPlain2  = "<notfound>";
-                               sBinary2 = "<notfound>";
-                       }
-
-                       string sPlain = sPlain1 + sPlain2;
-                       string sBinary = sBinary1 + sBinary2;
-
-                       // Correct case
-                       if (fPart1Found && fPart2Found)
-                       {
-                               unsigned char NTLMHash[16];
-                               int nHashLen;
-                               ParseHash(vNTLMHash[i], NTLMHash, nHashLen);
-                               if (nHashLen != 16)
-                                       printf("debug: nHashLen mismatch\n");
-                               string sNTLMPassword;
-                               if (LMPasswordCorrectCase(sPlain, NTLMHash, sNTLMPassword))
-                               {
-                                       sPlain = sNTLMPassword;
-                                       sBinary = HexToStr((const unsigned char*)sNTLMPassword.c_str(), sNTLMPassword.size());
-                               }
-                               else
-                               {
-                                       printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(), sPlain.c_str(), sBinary.c_str());
-                                       LM2NTLMcorrector corrector;
-                                       if (corrector.LMPasswordCorrectUnicode(sBinary, NTLMHash, sNTLMPassword))
-                                       {
-                                               sPlain = sNTLMPassword;
-                                               sBinary = corrector.getBinary();
-                                               if (writeOutput)
-                                               {
-                                                       if (!writeResultLineToFile(outputFile, vNTLMHash[i].c_str(), sPlain.c_str(), sBinary.c_str()))
-                                                               printf("Couldn't write final result to file!\n");
-                                               }
-                                       }
-                                       else {
-                                               printf("case correction for password %s failed!\n", sPlain.c_str());
-                                       }
-                               }
-                       }
-
-                       // Display
-                       printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(),
-                                                                                 sPlain.c_str(),
-                                                                                 sBinary.c_str());
-                       
-               }
-       }
-
-       return 0;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright 2009, 2010  Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009 James Dickson\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ * Copyright 2010 uroskn\r
+ *\r
+ * Modified by Martin Westergaard Jørgensen <martinwj2005@gmail.com> to support  * indexed and hybrid tables\r
+ *\r
+ * Modified by neinbrucke to support multi threading and a bunch of other stuff :)\r
+ *\r
+ * 2009-01-04 - <james.dickson@comhem.se> - Slightly modified (or "fulhack" as \r
+ * we say in sweden)  to support cain .lst files.\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "CrackEngine.h"\r
+#include "lm2ntlm.h"\r
+#include <algorithm>\r
+\r
+#ifdef _WIN32\r
+       #include <io.h>\r
+#else\r
+       #include <sys/types.h>\r
+       #include <sys/stat.h>\r
+       #include <unistd.h>\r
+       #include <dirent.h>\r
+#endif\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma comment(lib, "libeay32.lib")\r
+#endif\r
+\r
+//////////////////////////////////////////////////////////////////////\r
+\r
+#ifdef _WIN32\r
+void GetTableList(string sWildCharPathName, vector<string>& vPathName)\r
+{\r
+       //vPathName.clear();\r
+\r
+       string sPath;\r
+       string::size_type n = sWildCharPathName.find_last_of('\\');\r
+\r
+       if ( n == (sWildCharPathName.size() - 1) )\r
+       {\r
+               sWildCharPathName = sWildCharPathName.substr(0, n);\r
+               n = sWildCharPathName.find_last_of('\\');\r
+       }\r
+\r
+       if (n != string::npos)\r
+               sPath = sWildCharPathName.substr(0, n + 1);\r
+\r
+       _finddata_t fd;\r
+\r
+       long handle = _findfirst(sWildCharPathName.c_str(), &fd);\r
+       if (handle != -1)\r
+       {\r
+               do\r
+               {\r
+                       string sName = fd.name;\r
+                       if (sName.size()>3) {\r
+                               if (sName.substr(sName.size()-3, 3) == ".rt" && !(fd.attrib & _A_SUBDIR))\r
+                               {\r
+                                       string sPathName = sPath + sName;\r
+                                       vPathName.push_back(sPathName);\r
+                               }\r
+                       }\r
+                       if (sName.size()>4) {\r
+                               if (sName.substr(sName.size()-4, 4) == ".rti" && !(fd.attrib & _A_SUBDIR))\r
+                               {\r
+                                       string sPathName = sPath + sName;\r
+                                       vPathName.push_back(sPathName);\r
+                               }\r
+                       }\r
+                       if (sName.size()>5) {\r
+                               if (sName.substr(sName.size()-5, 5) == ".rti2" && !(fd.attrib & _A_SUBDIR))\r
+                               {\r
+                                       string sPathName = sPath + sName;\r
+                                       vPathName.push_back(sPathName);\r
+                               }\r
+                       }\r
+\r
+                       if (sName != "." && sName != ".." && (fd.attrib & _A_SUBDIR))\r
+                       {\r
+                               string sPath_sub = sPath + sName + '\\';\r
+                               string sWildCharPathName_sub = sPath_sub + '*';\r
+                               GetTableList(sWildCharPathName_sub, vPathName);\r
+                       }\r
+\r
+               } while (_findnext(handle, &fd) == 0);\r
+\r
+               _findclose(handle);\r
+       }\r
+       //printf("Found %d rainbowtables (files) in %d sub directories...\n", vPathName.size(), subDir_count);\r
+}\r
+#else\r
+//void GetTableList(int argc, char* argv[], vector<string>& vPathName)\r
+void GetTableList(string sWildCharPathName, vector<string>& vPathName)\r
+{\r
+       //vPathName.clear();\r
+\r
+       struct stat buf;\r
+       if (lstat(sWildCharPathName.c_str(), &buf) == 0)\r
+       {\r
+               if (S_ISDIR(buf.st_mode))\r
+               {\r
+                       DIR *dir = opendir(sWildCharPathName.c_str());\r
+                       if(dir)\r
+                       {\r
+                               struct dirent *pDir=NULL;\r
+                               while((pDir = readdir(dir)) != NULL)\r
+                               {\r
+                                       string filename = "";\r
+                                       filename += (*pDir).d_name;\r
+                                       if (filename != "." && filename != "..")\r
+                                       {\r
+                                               string new_filename = sWildCharPathName + '/' + filename;\r
+                                               GetTableList(new_filename, vPathName);\r
+                                       }\r
+                               }\r
+                               closedir(dir);\r
+                       }\r
+               }\r
+               else if (S_ISREG(buf.st_mode))\r
+               {\r
+                       if (sWildCharPathName.size()>3)\r
+                       {\r
+                               if (sWildCharPathName.substr(sWildCharPathName.size()-3, 3) == ".rt")\r
+                               {\r
+                                       vPathName.push_back(sWildCharPathName);\r
+                               }\r
+                       }\r
+                       if (sWildCharPathName.size()>4)\r
+                       {\r
+                               if (sWildCharPathName.substr(sWildCharPathName.size()-4, 4) == ".rti")\r
+                               {\r
+                                       //string sPathName_sub = sPath_sub + sName_sub;\r
+                                       vPathName.push_back(sWildCharPathName);\r
+                                       //printf("sPathName_sub: %s\n", sPathName_sub.c_str());\r
+                               }\r
+                       }\r
+                       if ( sWildCharPathName.size() > 5 )\r
+                       {\r
+                               if ( sWildCharPathName.substr( sWildCharPathName.size() - 5, 5 ) == ".rti2" )\r
+                               {\r
+                                       vPathName.push_back( sWildCharPathName );\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+}\r
+#endif\r
+\r
+bool NormalizeHash(string& sHash)\r
+{\r
+       string sNormalizedHash = sHash;\r
+\r
+       if (   sNormalizedHash.size() % 2 != 0\r
+               || sNormalizedHash.size() < MIN_HASH_LEN * 2\r
+               || sNormalizedHash.size() > MAX_HASH_LEN * 2)\r
+               return false;\r
+\r
+       // Make lower\r
+       uint32 i;\r
+       for (i = 0; i < sNormalizedHash.size(); i++)\r
+       {\r
+               if (sNormalizedHash[i] >= 'A' && sNormalizedHash[i] <= 'F')\r
+                       sNormalizedHash[i] = (char) sNormalizedHash[i] - 'A' + 'a';\r
+       }\r
+\r
+       // Character check\r
+       for (i = 0; i < sNormalizedHash.size(); i++)\r
+       {\r
+               if (   (sNormalizedHash[i] < 'a' || sNormalizedHash[i] > 'f')\r
+                       && (sNormalizedHash[i] < '0' || sNormalizedHash[i] > '9'))\r
+                       return false;\r
+       }\r
+\r
+       sHash = sNormalizedHash;\r
+       return true;\r
+}\r
+\r
+void LoadLMHashFromPwdumpFile(string sPathName, vector<string>& vUserName, vector<string>& vLMHash, vector<string>& vNTLMHash)\r
+{\r
+       vector<string> vLine;\r
+       if (ReadLinesFromFile(sPathName, vLine))\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vLine.size(); i++)\r
+               {\r
+                       vector<string> vPart;\r
+                       if (SeperateString(vLine[i], "::::", vPart))\r
+                       {\r
+                               string sUserName = vPart[0];\r
+                               string sLMHash   = vPart[2];\r
+                               string sNTLMHash = vPart[3];\r
+\r
+                               if (sLMHash.size() == 32 && sNTLMHash.size() == 32)\r
+                               {\r
+                                       if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash))\r
+                                       {\r
+                                               vUserName.push_back(sUserName);\r
+                                               vLMHash.push_back(sLMHash);\r
+                                               vNTLMHash.push_back(sNTLMHash);\r
+                                       }\r
+                                       else\r
+                                               printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str());\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       else\r
+               printf("can't open %s\n", sPathName.c_str());\r
+}\r
+\r
+// 2009-01-04 - james.dickson - Added this so we can load hashes from cain .LST files.\r
+void LoadLMHashFromCainLSTFile(string sPathName, vector<string>& vUserName, vector<string>& vLMHash, vector<string>& vNTLMHash)\r
+{\r
+       vector<string> vLine;\r
+       if (ReadLinesFromFile(sPathName, vLine))\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vLine.size(); i++)\r
+               {\r
+                       vector<string> vPart;\r
+                       if (SeperateString(vLine[i], "\t\t\t\t\t\t", vPart))\r
+                       {\r
+                               string sUserName = vPart[0];\r
+                               string sLMHash   = vPart[4];\r
+                               string sNTLMHash = vPart[5];\r
+\r
+                               if (sLMHash.size() == 32 && sNTLMHash.size() == 32)\r
+                               {\r
+                                       if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash))\r
+                                       {\r
+                                               vUserName.push_back(sUserName);\r
+                                               vLMHash.push_back(sLMHash);\r
+                                               vNTLMHash.push_back(sNTLMHash);\r
+                                       }\r
+                                       else\r
+                                               printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str());\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+       else\r
+               printf("can't open %s\n", sPathName.c_str());\r
+}\r
+\r
+bool NTLMPasswordSeek(unsigned char* pLMPassword, int nLMPasswordLen, int nLMPasswordNext,\r
+                                         unsigned char* pNTLMHash, string& sNTLMPassword)\r
+{\r
+       if (nLMPasswordNext == nLMPasswordLen)\r
+       {\r
+               unsigned char md[MD4_DIGEST_LENGTH];\r
+               MD4_NEW(pLMPassword, nLMPasswordLen * 2, md);\r
+\r
+               if (memcmp(md, pNTLMHash, MD4_DIGEST_LENGTH) == 0)\r
+               {\r
+                       sNTLMPassword = "";\r
+                       int i;\r
+                       for (i = 0; i < nLMPasswordLen; i++)\r
+                               sNTLMPassword += char(pLMPassword[i * 2]);\r
+                       return true;\r
+               }\r
+               else\r
+                       return false;\r
+       }\r
+\r
+       if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword))\r
+               return true;\r
+\r
+       if (   pLMPassword[nLMPasswordNext * 2] >= 'A'\r
+               && pLMPassword[nLMPasswordNext * 2] <= 'Z')\r
+       {\r
+               pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'A' + 'a';\r
+               if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword))\r
+                       return true;\r
+               pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'a' + 'A';\r
+       }\r
+\r
+       return false;\r
+}\r
+\r
+bool LMPasswordCorrectCase(string sLMPassword, unsigned char* pNTLMHash, string& sNTLMPassword)\r
+{\r
+       if (sLMPassword.size() == 0)\r
+       {\r
+               sNTLMPassword = "";\r
+               return true;\r
+       }\r
+\r
+       unsigned char* pLMPassword = new unsigned char[sLMPassword.size() * 2];\r
+       uint32 i;\r
+       for (i = 0; i < sLMPassword.size(); i++)\r
+       {\r
+               pLMPassword[i * 2    ] = sLMPassword[i];\r
+               pLMPassword[i * 2 + 1] = 0x00;\r
+       }\r
+       bool fRet = NTLMPasswordSeek(pLMPassword, sLMPassword.size(), 0, pNTLMHash, sNTLMPassword);\r
+\r
+       delete pLMPassword;\r
+\r
+       return fRet;\r
+}\r
+\r
+void Usage()\r
+{\r
+       Logo();\r
+\r
+       printf("usage: rcracki_mt -h hash rainbow_table_pathname\n");\r
+       printf("       rcracki_mt -l hash_list_file rainbow_table_pathname\n");\r
+       printf("       rcracki_mt -f pwdump_file rainbow_table_pathname\n");\r
+       printf("       rcracki_mt -c lst_file rainbow_table_pathname\n");\r
+       printf("\n");\r
+       printf("-h hash:                use raw hash as input\n");\r
+       printf("-l hash_list_file:      use hash list file as input, each hash in a line\n");\r
+       printf("-f pwdump_file:         use pwdump file as input, handles lanmanager hash only\n");\r
+       printf("-c lst_file:            use .lst (cain format) file as input\n");\r
+       printf("-r [-s session_name]:   resume from previous session, optional session name\n");\r
+       printf("rainbow_table_pathname: pathname(s) of the rainbow table(s)\n");\r
+       printf("\n");\r
+       printf("Extra options:    -t [nr] use this amount of threads/cores, default is 1\n");\r
+       printf("                  -o [output_file] write (temporary) results to this file\n");\r
+       printf("                  -s [session_name] write session data with this name\n");\r
+       printf("                  -k keep precalculation on disk\n");\r
+       printf("                  -m [megabytes] limit memory usage\n");\r
+       printf("                  -v show debug information\n");\r
+       printf("\n");\r
+#ifdef _WIN32\r
+       printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]\\MD5\n");\r
+       printf("         rcracki_mt -l hash.txt [path_to_specific_table]\\*\n");\r
+#else\r
+       printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]/MD5\n");\r
+       printf("         rcracki_mt -l hash.txt [path_to_specific_table]/*\n");\r
+#endif\r
+       printf("         rcracki_mt -f hash.txt -t 4 -o results.txt *.rti\n");\r
+}\r
+\r
+int main(int argc, char* argv[])\r
+{\r
+       if (argc < 2)\r
+       {\r
+               Usage();\r
+               return 0;\r
+       }\r
+\r
+       vector<string> vPathName;\r
+       vector<string> vDefaultRainbowTablePath;\r
+       string sWildCharPathName                        = "";\r
+       string sInputType                                               = "";\r
+       string sInput                                                   = "";\r
+       string outputFile                                               = "";\r
+       string sApplicationPath                         = "";\r
+       string sIniPathName                                     = "rcracki_mt.ini";\r
+       bool writeOutput                                                = false;\r
+       string sSessionPathName                         = "rcracki.session";\r
+       string sProgressPathName                        = "rcracki.progress";\r
+       string sPrecalcPathName                         = "rcracki.precalc";\r
+       bool resumeSession                                      = false;\r
+       bool useDefaultRainbowTablePath = false;\r
+       bool debug                                                              = false;\r
+       bool keepPrecalcFiles                           = false;\r
+       string sAlgorithm                                               = "";\r
+       int maxThreads                                                  = 1;\r
+       uint64 maxMem                                                   = 0;\r
+       CHashSet hs;\r
+\r
+       // Read defaults from ini file;\r
+       bool readFromIni = false;\r
+       vector<string> vLine;\r
+       if (ReadLinesFromFile(sIniPathName, vLine)) {\r
+               readFromIni = true;\r
+       }\r
+       else if (ReadLinesFromFile(GetApplicationPath() + sIniPathName, vLine)) {\r
+               readFromIni = true;\r
+       }\r
+       if (readFromIni)\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vLine.size(); i++)\r
+               {\r
+                       if (vLine[i].substr(0,1) != "#")\r
+                       {\r
+                               vector<string> vPart;\r
+                               if (SeperateString(vLine[i], "=", vPart))\r
+                               {\r
+                                       string sOption = vPart[0];\r
+                                       string sValue  = vPart[1];\r
+                                       \r
+                                       if (sOption == "Threads") {\r
+                                               maxThreads = atoi(sValue.c_str());\r
+                                       }\r
+                                       else if (sOption == "MaxMemoryUsage" ) {\r
+                                               maxMem = atoi(sValue.c_str()) * 1024 *1024;\r
+                                       }\r
+                                       else if (sOption == "DefaultResultsFile") {\r
+                                               outputFile = sValue;\r
+                                       }\r
+                                       else if (sOption == "AlwaysStoreResultsToFile") {\r
+                                               if (sValue == "1")\r
+                                                       writeOutput = true;\r
+                                       }\r
+                                       else if (sOption.substr(0,24) == "DefaultRainbowTablePath.") {\r
+                                               //printf("Default RT path: %s\n", sValue.c_str());\r
+                                               vDefaultRainbowTablePath.push_back(vLine[i]);\r
+                                       }\r
+                                       else if (sOption == "DefaultAlgorithm") {\r
+                                               useDefaultRainbowTablePath = true;\r
+                                               sAlgorithm = sValue;\r
+                                       }\r
+                                       else if (sOption == "AlwaysDebug") {\r
+                                               if (sValue == "1")\r
+                                                       debug = true;\r
+                                       }\r
+                                       else if (sOption == "AlwaysKeepPrecalcFiles") {\r
+                                               if (sValue == "1")\r
+                                                       keepPrecalcFiles = true;\r
+                                       }\r
+                                       else {\r
+                                               printf("illegal option %s in ini file %s\n", sOption.c_str(), sIniPathName.c_str());\r
+                                               return 0;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               if (writeOutput && outputFile == "")\r
+               {\r
+                       printf("You need to specify a 'DefaultResultsFile' with 'AlwaysStoreResultsToFile=1'\n");\r
+                       writeOutput = false;\r
+               }\r
+       }\r
+\r
+       // Parse command line arguments\r
+       int i;\r
+       for (i = 1; i < argc; i++)\r
+       {\r
+               string cla = argv[i];\r
+               if (cla == "-h") {\r
+                       sInputType = cla;\r
+                       i++;\r
+                       if (i < argc)\r
+                               sInput = argv[i];\r
+               }\r
+               else if (cla == "-l") {\r
+                       sInputType = cla;\r
+                       i++;\r
+                       if (i < argc)\r
+                               sInput = argv[i];\r
+               }\r
+               else if (cla == "-f") {\r
+                       sInputType = cla;\r
+                       i++;\r
+                       if (i < argc)\r
+                               sInput = argv[i];\r
+               }\r
+               else if (cla == "-c") {\r
+                       sInputType = cla;\r
+                       i++;\r
+                       if (i < argc)\r
+                               sInput = argv[i];\r
+               }\r
+               else if (cla == "-t") {\r
+                       i++;\r
+                       if (i < argc)\r
+                               maxThreads = atoi(argv[i]);\r
+               }\r
+               else if ( cla == "-m" ) {\r
+                       i++;\r
+                       if ( i < argc )\r
+                               maxMem = atoi(argv[i]) * 1024 * 1024;\r
+               }\r
+               else if (cla == "-o") {\r
+                       writeOutput = true;\r
+                       i++;\r
+                       if (i < argc)\r
+                               outputFile = argv[i];\r
+               }\r
+               else if (cla == "-r") {\r
+                       resumeSession = true;\r
+               }\r
+               else if (cla == "-s") {\r
+                       i++;\r
+                       if (i < argc)\r
+                       {\r
+                               sSessionPathName                =  argv[i];\r
+                               sSessionPathName                += ".session";\r
+                               sProgressPathName               =  argv[i];\r
+                               sProgressPathName               += ".progress";\r
+                               sPrecalcPathName                =  argv[i];\r
+                               sPrecalcPathName                += ".precalc";\r
+                       }\r
+               }\r
+               else if (cla == "-v") {\r
+                       debug = true;\r
+               }\r
+               else if (cla == "-k") {\r
+                       keepPrecalcFiles = true;\r
+               }\r
+               else if (cla == "-a") {\r
+                       useDefaultRainbowTablePath = true;\r
+                       i++;\r
+                       if (i < argc)\r
+                               sAlgorithm = argv[i];\r
+               }\r
+               else {\r
+                       GetTableList(cla, vPathName);\r
+               }\r
+       }\r
+\r
+       if (debug && !readFromIni)\r
+               printf("Debug: Couldn't read rcracki_mt.ini, continuing anyway.\n");\r
+\r
+       // Load session data if we are resuming\r
+       if (resumeSession)\r
+       {\r
+               vPathName.clear();\r
+               vector<string> sSessionData;\r
+               if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData))\r
+               {\r
+                       uint32 i;\r
+                       for (i = 0; i < sSessionData.size(); i++)\r
+                       {\r
+                               vector<string> vPart;\r
+                               if (SeperateString(sSessionData[i], "=", vPart))\r
+                               {\r
+                                       string sOption = vPart[0];\r
+                                       string sValue  = vPart[1];\r
+                                       \r
+                                       if (sOption == "sPathName") {\r
+                                               vPathName.push_back(sValue);\r
+                                       }\r
+                                       else if (sOption == "sInputType") {\r
+                                               sInputType = sValue;\r
+                                       }\r
+                                       else if (sOption == "sInput") {\r
+                                               sInput = sValue;\r
+                                       }\r
+                                       else if (sOption == "outputFile") {\r
+                                               writeOutput = true;\r
+                                               outputFile = sValue;\r
+                                       }\r
+                                       else if (sOption == "keepPrecalcFiles") {\r
+                                               if (sValue == "1")\r
+                                                       keepPrecalcFiles = true;\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+               else {\r
+                       printf("Couldn't open session file %s\n", sSessionPathName.c_str());\r
+                       return 0;\r
+               }\r
+       }\r
+\r
+       if (maxThreads<1)\r
+               maxThreads = 1;\r
+\r
+       // don't load these if we are resuming a session that already has a list of tables\r
+       if (useDefaultRainbowTablePath && !resumeSession)\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vDefaultRainbowTablePath.size(); i++)\r
+               {\r
+                       vector<string> vPart;\r
+                       if (SeperateString(vDefaultRainbowTablePath[i], ".=", vPart))\r
+                       {\r
+                               string lineAlgorithm = vPart[1];\r
+                               string linePath = vPart[2];\r
+\r
+                               if (lineAlgorithm == sAlgorithm)\r
+                                       GetTableList(linePath, vPathName);\r
+                       }\r
+               }\r
+       }\r
+\r
+       printf("Using %d threads for pre-calculation and false alarm checking...\n", maxThreads);\r
+\r
+       setvbuf(stdout, NULL, _IONBF,0);\r
+       if (vPathName.size() == 0)\r
+       {\r
+               printf("no rainbow table found\n");\r
+               return 0;\r
+       }\r
+       printf("Found %lu rainbowtable files...\n\n",\r
+               (unsigned long)vPathName.size());\r
+\r
+       bool fCrackerType;                      // true: hash cracker, false: lm cracker\r
+       vector<string> vHash;           // hash cracker\r
+       vector<string> vUserName;       // lm cracker\r
+       vector<string> vLMHash;         // lm cracker\r
+       vector<string> vNTLMHash;       // lm cracker\r
+       if (sInputType == "-h")\r
+       {\r
+               fCrackerType = true;\r
+\r
+               string sHash = sInput;\r
+               if (NormalizeHash(sHash))\r
+                       vHash.push_back(sHash);\r
+               else\r
+                       printf("invalid hash: %s\n", sHash.c_str());\r
+       }\r
+       else if (sInputType == "-l")\r
+       {\r
+               fCrackerType = true;\r
+\r
+               string sPathName = sInput;\r
+               vector<string> vLine;\r
+               if (ReadLinesFromFile(sPathName, vLine))\r
+               {\r
+                       uint32 i;\r
+                       for (i = 0; i < vLine.size(); i++)\r
+                       {\r
+                               string sHash = vLine[i];\r
+                               if (NormalizeHash(sHash))\r
+                                       vHash.push_back(sHash);\r
+                               else\r
+                                       printf("invalid hash: %s\n", sHash.c_str());\r
+                       }\r
+               }\r
+               else\r
+                       printf("can't open %s\n", sPathName.c_str());\r
+       }\r
+       else if (sInputType == "-f")\r
+       {\r
+               fCrackerType = false;\r
+\r
+               string sPathName = sInput;\r
+               LoadLMHashFromPwdumpFile(sPathName, vUserName, vLMHash, vNTLMHash);\r
+       }\r
+       else if (sInputType == "-c")\r
+       {\r
+               // 2009-01-04 - james.dickson - Added this for cain-files.\r
+               fCrackerType = false;\r
+               string sPathName = sInput;\r
+               LoadLMHashFromCainLSTFile(sPathName, vUserName, vLMHash, vNTLMHash);\r
+       }\r
+       else\r
+       {\r
+               Usage();\r
+               return 0;\r
+       }\r
+\r
+       if (fCrackerType && vHash.size() == 0)\r
+       {\r
+               printf("no hashes found");\r
+               return 0;\r
+       }\r
+       if (!fCrackerType && vLMHash.size() == 0)\r
+       {\r
+               return 0;\r
+               printf("no hashes found");\r
+       }\r
+\r
+       if (fCrackerType)\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vHash.size(); i++)\r
+                       hs.AddHash(vHash[i]);\r
+       }\r
+       else\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vLMHash.size(); i++)\r
+               {\r
+                       hs.AddHash(vLMHash[i].substr(0, 16));\r
+                       hs.AddHash(vLMHash[i].substr(16, 16));\r
+               }\r
+       }\r
+\r
+       // Load found hashes from session file\r
+       if (resumeSession)\r
+       {\r
+               vector<string> sSessionData;\r
+               if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData))\r
+               {\r
+                       uint32 i;\r
+                       for (i = 0; i < sSessionData.size(); i++)\r
+                       {\r
+                               vector<string> vPart;\r
+                               if (SeperateString(sSessionData[i], "=", vPart))\r
+                               {\r
+                                       string sOption = vPart[0];\r
+                                       string sValue  = vPart[1];\r
+                                       \r
+                                       if (sOption == "sHash") {\r
+                                               vector<string> vPartHash;\r
+                                               if (SeperateString(sValue, "::", vPartHash))\r
+                                               {\r
+                                                       string sHash = vPartHash[0];\r
+                                                       string sBinary = vPartHash[1];\r
+                                                       string sPlain = vPartHash[2];\r
+                                                       \r
+                                                       hs.SetPlain(sHash, sPlain, sBinary);\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       // (Over)write session data if we are not resuming\r
+       if (!resumeSession)\r
+       {\r
+               FILE* file = fopen(sSessionPathName.c_str(), "w");\r
+               string buffer = "";\r
+\r
+               if (file!=NULL)\r
+               {\r
+                       buffer += "sInputType=" + sInputType + "\n";\r
+                       buffer += "sInput=" + sInput + "\n";\r
+\r
+                       uint32 i;\r
+                       for (i = 0; i < vPathName.size(); i++)\r
+                       {\r
+                               buffer += "sPathName=" + vPathName[i] + "\n";\r
+                       }\r
+\r
+                       if (writeOutput)\r
+                               buffer += "outputFile=" + outputFile + "\n";\r
+\r
+                       if (keepPrecalcFiles)\r
+                               buffer += "keepPrecalcFiles=1\n";\r
+\r
+                       fputs (buffer.c_str(), file);\r
+                       fclose (file);\r
+               }\r
+               file = fopen(sProgressPathName.c_str(), "w");\r
+               fclose (file);\r
+       }\r
+\r
+       // Run\r
+       CCrackEngine ce;\r
+       if (writeOutput)\r
+               ce.setOutputFile(outputFile);\r
+       ce.setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles);\r
+       ce.Run(vPathName, hs, maxThreads, maxMem, resumeSession, debug);\r
+\r
+       // Remove session files\r
+       if (debug) printf("Debug: Removing session files.\n");\r
+\r
+       if (remove(sSessionPathName.c_str()) == 0)\r
+               remove(sProgressPathName.c_str());\r
+       else\r
+               if (debug) printf("Debug: Failed removing session files.\n");\r
+\r
+       // Statistics\r
+       printf("statistics\n");\r
+       printf("-------------------------------------------------------\n");\r
+       printf("plaintext found:            %d of %d (%.2f%%)\n", hs.GetStatHashFound(),\r
+                                                                                                                       hs.GetStatHashTotal(),\r
+                                                                                                                       100.0f * hs.GetStatHashFound() / hs.GetStatHashTotal());\r
+       printf("total disk access time:     %.2f s\n", ce.GetStatTotalDiskAccessTime());\r
+       printf("total cryptanalysis time:   %.2f s\n", ce.GetStatTotalCryptanalysisTime());\r
+       printf("total pre-calculation time: %.2f s\n", ce.GetStatTotalPrecalculationTime());\r
+       printf("total chain walk step:      %d\n",     ce.GetStatTotalChainWalkStep());\r
+       printf("total false alarm:          %d\n",     ce.GetStatTotalFalseAlarm());\r
+       printf("total chain walk step due to false alarm: %d\n", ce.GetStatTotalChainWalkStepDueToFalseAlarm());\r
+//     printf("total chain walk step skipped due to checkpoints: %d\n", ce.GetStatTotalFalseAlarmSkipped()); // Checkpoints not used - yet\r
+       printf("\n");\r
+\r
+       // Result\r
+       printf("result\n");\r
+       printf("-------------------------------------------------------\n");\r
+       if (fCrackerType)\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vHash.size(); i++)\r
+               {\r
+                       string sPlain, sBinary;\r
+                       if (!hs.GetPlain(vHash[i], sPlain, sBinary))\r
+                       {\r
+                               sPlain  = "<notfound>";\r
+                               sBinary = "<notfound>";\r
+                       }\r
+\r
+                       printf("%s\t%s\thex:%s\n", vHash[i].c_str(), sPlain.c_str(), sBinary.c_str());\r
+               }\r
+       }\r
+       else\r
+       {\r
+               uint32 i;\r
+               for (i = 0; i < vLMHash.size(); i++)\r
+               {\r
+                       string sPlain1, sBinary1;\r
+                       bool fPart1Found = hs.GetPlain(vLMHash[i].substr(0, 16), sPlain1, sBinary1);\r
+                       if (!fPart1Found)\r
+                       {\r
+                               sPlain1  = "<notfound>";\r
+                               sBinary1 = "<notfound>";\r
+                       }\r
+\r
+                       string sPlain2, sBinary2;\r
+                       bool fPart2Found = hs.GetPlain(vLMHash[i].substr(16, 16), sPlain2, sBinary2);\r
+                       if (!fPart2Found)\r
+                       {\r
+                               sPlain2  = "<notfound>";\r
+                               sBinary2 = "<notfound>";\r
+                       }\r
+\r
+                       string sPlain = sPlain1 + sPlain2;\r
+                       string sBinary = sBinary1 + sBinary2;\r
+\r
+                       // Correct case\r
+                       if (fPart1Found && fPart2Found)\r
+                       {\r
+                               unsigned char NTLMHash[16];\r
+                               int nHashLen;\r
+                               ParseHash(vNTLMHash[i], NTLMHash, nHashLen);\r
+                               if (nHashLen != 16)\r
+                                       printf("debug: nHashLen mismatch\n");\r
+                               string sNTLMPassword;\r
+                               if (LMPasswordCorrectCase(sPlain, NTLMHash, sNTLMPassword))\r
+                               {\r
+                                       sPlain = sNTLMPassword;\r
+                                       sBinary = HexToStr((const unsigned char*)sNTLMPassword.c_str(), sNTLMPassword.size());\r
+                               }\r
+                               else\r
+                               {\r
+                                       printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(), sPlain.c_str(), sBinary.c_str());\r
+                                       LM2NTLMcorrector corrector;\r
+                                       if (corrector.LMPasswordCorrectUnicode(sBinary, NTLMHash, sNTLMPassword))\r
+                                       {\r
+                                               sPlain = sNTLMPassword;\r
+                                               sBinary = corrector.getBinary();\r
+                                               if (writeOutput)\r
+                                               {\r
+                                                       if (!writeResultLineToFile(outputFile, vNTLMHash[i].c_str(), sPlain.c_str(), sBinary.c_str()))\r
+                                                               printf("Couldn't write final result to file!\n");\r
+                                               }\r
+                                       }\r
+                                       else {\r
+                                               printf("case correction for password %s failed!\n", sPlain.c_str());\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       // Display\r
+                       printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(),\r
+                                                                                 sPlain.c_str(),\r
+                                                                                 sBinary.c_str());\r
+                       \r
+               }\r
+       }\r
+\r
+       return 0;\r
+}\r
index 514be09b0eed9b1e9c7520f42ad4d05079f2549b..934e9c6b8b62ea69322e1e90d742230a6f760341 100644 (file)
 
 
 #ifndef MD5_pad_w1
-static inline UINT4 MD5_pad_w1(UINT4 data)
+static inline uint32 MD5_pad_w1(uint32 data)
 {
 // XXX x86 specific
        __asm__ (
@@ -263,7 +263,7 @@ static inline UINT4 MD5_pad_w1(UINT4 data)
 #endif
 
 #ifndef MD5_pad_w3
-static inline UINT4 MD5_pad_w3(UINT4 data)
+static inline uint32 MD5_pad_w3(uint32 data)
 {
 // XXX x86 specific
        __asm__ (
@@ -279,7 +279,7 @@ static inline UINT4 MD5_pad_w3(UINT4 data)
 #endif
 
 
-static inline void MD5_copy_pad_block(UINT4 *dData, UINT4 *wIn, int blocklen, int len)
+static inline void MD5_copy_pad_block(uint32 *dData, uint32 *wIn, int blocklen, int len)
 {
        register int cl;
 
@@ -313,7 +313,7 @@ static inline void MD5_copy_pad_block(UINT4 *dData, UINT4 *wIn, int blocklen, in
 // fast initializer array
 //__attribute__((aligned(16)))
 //__declspec(align(16))
-static const UINT4 CC[4] = {Ca, Cb, Cc, Cd};
+static const uint32 CC[4] = {Ca, Cb, Cc, Cd};
 
 
 
@@ -323,13 +323,13 @@ static const UINT4 CC[4] = {Ca, Cb, Cc, Cd};
  */
 void fast_MD5(unsigned char *pData, int len, unsigned char *pDigest)
 {
-       #define wIn             ((UINT4 *)pData)
-       #define wOut    ((UINT4 *)pDigest)
+       #define wIn             ((uint32 *)pData)
+       #define wOut    ((uint32 *)pDigest)
 
-       register UINT4 a;
-       register UINT4 b;
-       register UINT4 c;
-       register UINT4 d;
+       register uint32 a;
+       register uint32 b;
+       register uint32 c;
+       register uint32 d;
 
        switch (len) {
                case 0:
@@ -383,7 +383,7 @@ void fast_MD5(unsigned char *pData, int len, unsigned char *pDigest)
        }
 
        // data block used for padding
-       UINT4 dData[16];
+       uint32 dData[16];
 
        if (len < 56) {
                // 16 < length < 56
@@ -404,7 +404,7 @@ void fast_MD5(unsigned char *pData, int len, unsigned char *pDigest)
        } else {
                // len >= 56
 
-               #define wIn             ((UINT4 *)pData)
+               #define wIn             ((uint32 *)pData)
 
                // original len
                int tlen = len;
@@ -479,7 +479,7 @@ void fast_MD5(unsigned char *pData, int len, unsigned char *pDigest)
                        );
 
                        #undef  wIn
-                       #define wIn             ((UINT4 *)pData)
+                       #define wIn             ((uint32 *)pData)
                        return;
                }
        }
index 952aab45deee9077d71d07fa21b5e9cb38435d40..9e6cbf1c6277555eddb9c5bec26cad5911c7a748 100644 (file)
@@ -24,8 +24,6 @@
 #ifndef _GLOBAL_H
 #define _GLOBAL_H
 
-//#include <stdint.h>
-
 #if defined(_WIN32) && !defined(__GNUC__)
        #define uint64 unsigned __int64
 #else
 
 #if defined(_WIN32) && !defined(__GNUC__)
        #define UINT4 unsigned __int32
+       #define uint32 unsigned __int32
 #else
        #ifndef u_int32_t
                #define UINT4 unsigned int
+               #define uint32 unsigned int
        #else
                #define UINT4 u_int32_t
+               #define uint32 u_int32_t
        #endif
 #endif
 
index a335ad32a3eff6c63c34bacc374ac8b74c2fbed2..c3d385804e0168bb50a6596a696777dd3b870542 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "lm2ntlm.h"
-
-LM2NTLMcorrector::LM2NTLMcorrector()
-{
-       progressCurrentCombination = 0;
-       totalCurrentCombination = 1;
-       counterOverall = 0;
-       countCombinations = 0;
-       countTotalCombinations = 0;
-       counter = 0;
-       fillMapW();
-       aborting = false;
-       sBinary = "";
-
-}
-
-string LM2NTLMcorrector::getBinary()
-{
-       return sBinary;
-}
-
-bool LM2NTLMcorrector::LMPasswordCorrectUnicode(string hexPassword, unsigned char* pNTLMHash, string& sNTLMPassword) //, unsigned char* pLMPassword
-{
-       string sPlain = "";
-
-       UINT4 i;
-       for (i = 0; i < hexPassword.size() / 2; i++)
-       {
-               string sSub = hexPassword.substr(i * 2, 2);
-               int nValue;
-               sscanf(sSub.c_str(), "%02x", &nValue);
-               sPlain += (unsigned char)nValue;
-       }
-
-       memcpy(NTLMHash, pNTLMHash, MD4_DIGEST_LENGTH);
-
-
-       unsigned long int tmpLength = sPlain.size() * 2;
-       unsigned char* pLMPassword = new unsigned char[tmpLength];
-
-       //printf("Searching for unicode password.\n");
-       printf("Failed case correction, trying unicode correction for: %s\n", sPlain.c_str());
-       //printf("NTLM hash:          %s\n\n", sNTLMHash.c_str());
-       
-       setvbuf(stdout, NULL, _IONBF,0);
-
-       startClock = clock();
-       previousClock = clock();
-
-#ifndef _WIN32
-       tty_init();
-#endif
-
-       if (startCorrecting(sPlain, sNTLMPassword, pLMPassword))
-       {
-               sBinary = ByteToStr(pLMPassword, tmpLength).c_str();
-               //printf("\nFound unicode password: %s\n", sNTLMPassword.c_str());
-               //printf("Password in hex: %s\n", sBinary.c_str());
-               writeEndStats();
-#ifndef _WIN32
-               tty_done();
-#endif
-               return true;
-       }
-       else
-       {
-               //printf("\ncase correction for password %s fail!\n", sPlain.c_str());
-               writeEndStats();
-#ifndef _WIN32
-               tty_done();
-#endif
-               return false;
-       }
-}
-
-bool LM2NTLMcorrector::startCorrecting(string sLMPassword, string& sNTLMPassword, unsigned char* pLMPassword)
-{
-       if (sLMPassword.size() == 0)
-       {
-               sNTLMPassword = "";
-               return true;
-       }
-
-       string muteMe = sLMPassword;
-       int length = muteMe.size();
-
-       unsigned char* pMuteMe = new unsigned char[length];
-       unsigned char* pTempMute = new unsigned char[length * 2];
-
-       int i;
-       for (i = 0; i < length; i++)
-       {
-               pMuteMe[i] = muteMe[i];
-               pTempMute[i * 2    ] = muteMe[i];
-               pTempMute[i * 2 + 1] = 0x00;
-               unsigned char muteChar = pMuteMe[i];
-               int sizeMapForChar = m_mapChar[muteChar].size();
-               int j;
-               for (j = 0; j < sizeMapForChar; j++)
-               {
-                       currentCharmap[i][j] = m_mapChar[muteChar][j];
-               }
-       }
-       
-       int* jAtPos = new int[length];
-       int* sizeAtPos = new int[length];
-       bool* fullAtPos = new bool[length];
-
-       int setSize;
-       for (setSize = 0; setSize <= length; setSize++)
-       {
-               int cntFull = 0;
-
-               // clear all 'fullatpos' before new setSize
-               int i;
-               for (i=0; i < length; i++)
-               {
-                       fullAtPos[i] = false;
-               }
-
-               //printf("Trying full unicode map for %d/%d characters...\t\t\n", setSize, length);
-               printf("Trying full unicode map for %d/%d characters...%-20s\n", setSize, length, "");
-
-               bool notFirst = true;
-
-               // start at end and set 'full' combination
-               countCombinations = 0;
-               countTotalCombinations = calculateTotalCombinations(length, setSize);
-
-               int sPos = length - 1;
-               while (sPos >= 0 && notFirst) // finding combinations for current 'setSize'
-               {
-                       if (aborting)
-                               return false;
-
-                       if (cntFull < setSize)
-                       {
-                               if (fullAtPos[sPos] == false)
-                               {
-                                       fullAtPos[sPos] = true;
-                                       cntFull++;
-                               }
-                               sPos--;
-                       }
-                       else
-                       {
-                               if (fullAtPos[sPos] == false && setSize > 0)
-                               {
-                                       fullAtPos[sPos] = true;
-                                       cntFull++;
-                                       
-                                       // reset positions after sPos
-                                       int k;
-                                       for (k = sPos+1; k < length; k++)
-                                       {
-                                               if (fullAtPos[k] == true)
-                                               {
-                                                       fullAtPos[k] = false;
-                                                       cntFull--;
-                                               }
-                                       }
-                                       // start at end again
-                                       sPos = length - 1;
-                               }
-                               else
-                               {
-                                       sPos--;
-                               }
-                       }
-                       // we have a combination
-                       if (cntFull == setSize)
-                       {
-                               countCombinations++;
-
-                               setupCombinationAtPositions(length, pMuteMe, pTempMute, jAtPos, fullAtPos, sizeAtPos);
-
-                               if (checkPermutations(length, pTempMute, jAtPos, sizeAtPos, pLMPassword, sNTLMPassword))
-                               {
-                                       return true;
-                               }
-                       }
-
-                       if (setSize == 0)
-                               notFirst = false;
-               }
-       }
-       return false;
-}
-
-// set up combination at positions
-void LM2NTLMcorrector::setupCombinationAtPositions(int length, unsigned char* pMuteMe, unsigned char* pTempMute, int* jAtPos, bool* fullAtPos, int* sizeAtPos)
-{
-       progressCurrentCombination = 0;
-       totalCurrentCombination = 1;
-
-       int i;
-       for (i=0; i < length; i++)
-       {
-               pTempMute[i*2] = currentCharmap[i][0];
-               pTempMute[i*2+1] = currentCharmap[i][1]; // reset to first char in map
-       
-               jAtPos[i] = 0; // reset charcounter for this char (that is all chars)
-
-               // based on combination, set full map or only upper/lowercase
-               if (fullAtPos[i] == true)
-               {
-                       unsigned char muteChar = pMuteMe[i];
-                       long unsigned int sizeMapForChar = m_mapChar[muteChar].size()/2; // 2 bytes per char
-                       sizeAtPos[i] = sizeMapForChar;
-               }
-               else
-               {
-                       sizeAtPos[i] = 2;
-               }
-
-               totalCurrentCombination *= sizeAtPos[i];
-       }
-       //printf("Trying %I64u passwords for current combination\t\t\r", totalCurrentCombination);
-}
-
-// go check all permutations for this combination
-bool LM2NTLMcorrector::checkPermutations(int length, unsigned char* pTempMute, int* jAtPos, int* sizeAtPos, unsigned char* pLMPassword, string& sNTLMPassword)
-{
-       int pos = length - 1;
-
-       while (pos >= 0)
-       {
-               counter++;
-
-               pos = length - 1;
-
-               int jAtCurPos = jAtPos[pos];
-               int sizeMapForCharPos = sizeAtPos[pos];
-               // move to start of string and find character with permutations left
-               while (jAtCurPos >= sizeMapForCharPos-1 && pos >= -1)
-               {
-                       pos--;
-                       if (pos >= 0 )
-                       {
-                               jAtCurPos = jAtPos[pos];
-                               sizeMapForCharPos = sizeAtPos[pos];
-                       }
-               }
-               if (pos < 0)
-                       continue;
-
-               // next permutation for character
-               jAtCurPos++;
-               jAtPos[pos] = jAtCurPos;
-               
-               pTempMute[pos*2] = currentCharmap[pos][jAtCurPos*2];
-               pTempMute[pos*2+1] = currentCharmap[pos][jAtCurPos*2+1];
-               
-               // reset positions after pos
-               int k;
-               for (k = pos+1; k < length; k++)
-               {
-                       jAtPos[k] = 0;
-                       pTempMute[k*2] = currentCharmap[k][0]; // reset to first char in map
-                       pTempMute[k*2+1] = currentCharmap[k][1];
-               }
-
-               if (checkNTLMPassword(pTempMute, length, sNTLMPassword) == true)
-               {
-                       int i;
-                       for (i = 0; i < length*2; i++)
-                               pLMPassword[i] = pTempMute[i];
-                       return true;
-               }
-
-               if (counter > 10000) // don't check clocks too often
-               {
-                       clock_t currentClock = clock();
-                       float fTime = 1.0f * (currentClock - previousClock);
-                       if (fTime > 1.0f * CLOCKS_PER_SEC)
-                       {
-                               float progressPercentageCurrentCombination = progressCurrentCombination * 100.0f / totalCurrentCombination;
-                               float fTime = 1.0f * (currentClock - startClock) / CLOCKS_PER_SEC;
-                               float currentSpeed = (counterOverall + progressCurrentCombination) / fTime / 1000000;
-
-                               //printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)\t\t\t\t\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed);
-                               printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)%-30s\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed, "");
-
-                               previousClock = clock();
-                               #ifdef _WIN32
-                               if (_kbhit())
-                               {
-                                       int ch = _getch();
-                                       ch = toupper(ch);
-                                       if (ch == 'S')
-                                       {
-                                               aborting = true;
-                                               printf( "\nAborting unicode correction for this hash...\n");
-                                       }
-                                       else
-                                       {
-                                               printf( "\nPress 'S' to skip unicode correction for this hash...\n");
-                                       }
-                               }
-                               #else
-                               int c = tty_getchar();
-                               if (c >= 0) {
-                                       tty_flush();
-                                       if (c==115) { // = s
-                                               aborting = true;
-                                               printf( "\nAborting unicode correction for this hash...\n");
-                                       }
-                                       else {
-                                               printf( "\nPress 's' to skip unicode correction for this hash...\n");
-                                       }
-                               }
-                               #endif
-                               if (aborting)
-                                       return false;
-                       }
-                       counter = 0;
-               }
-               
-               progressCurrentCombination++;
-               counterOverall++;
-       }
-       return false;
-}
-
-// check password, maybe integrate this function in checkPermutations() for performance reasons.
-bool LM2NTLMcorrector::checkNTLMPassword(unsigned char* pLMPassword, int nLMPasswordLen, string& sNTLMPassword)
-{
-       unsigned char md[MD4_DIGEST_LENGTH];
-
-       //MD4(pLMPassword, nLMPasswordLen * 2, md);
-       /*
-       MD4_CTX ctx;
-       MD4_Init(&ctx);
-       MD4_Update(&ctx, pLMPassword, nLMPasswordLen * 2);
-       MD4_Final(md, &ctx);*/ 
-
-       MD4_NEW( pLMPassword, nLMPasswordLen * 2, md );
-
-       if (memcmp(md, NTLMHash, MD4_DIGEST_LENGTH) == 0)
-       {
-               sNTLMPassword = "";
-               int i;
-               for (i = 0; i < nLMPasswordLen; i++) {
-                       sNTLMPassword += char(pLMPassword[i * 2]);
-               }
-               return true;
-       }
-       else
-               return false;
-}
-
-void LM2NTLMcorrector::checkAbort()
-{
-#ifdef _WIN32
-       if (_kbhit())
-       {
-               int ch = _getch();
-               ch = toupper(ch);
-               if (ch == 'S')
-               {
-                       aborting = true;
-                       printf( "\nAborting unicode correction for this hash...\n");
-               }
-               else
-               {
-                       printf( "\nPress 'S' to skip unicode correction for this hash...\n");
-               }
-       }
-#endif
-}
-
-void LM2NTLMcorrector::writeEndStats()
-{
-       clock_t endClock = clock();
-       if (endClock - startClock > 0)
-       {
-               float fTime = 1.0f * (endClock - startClock) / CLOCKS_PER_SEC;
-               float speedOverall = counterOverall / fTime / 1000000;
-               printf("\nTried %s passwords in %.2f s (%.2f Mhashes/s)\n", uint64tostr(counterOverall).c_str(), fTime, speedOverall);
-       }
-
-       printf("\n");
-}
-
-int LM2NTLMcorrector::calculateTotalCombinations(int length, int setSize)
-{
-       return factorial(length) / (factorial(setSize) * factorial(length-setSize));
-}
-
-int LM2NTLMcorrector::factorial (int num)
-{
-       int result = 1;
-       int i;
-       for (i = 1; i <= num; ++i)
-               result *= i;
-       return result;
-}
-
-// convert some bytes into a string
-string LM2NTLMcorrector::ByteToStr(const unsigned char* pData, int nLen)
-{
-       string sRet = "";
-       int i;
-       for (i = 0; i < nLen/2; i++)
-       {
-               char szByte[3];
-               sprintf(szByte, "%02x", pData[i*2+1]); // swap 2-byte characters again
-               sRet += szByte;
-               sprintf(szByte, "%02x", pData[i*2]);
-               sRet += szByte;
-       }
-
-       return sRet;
-}
-
-void LM2NTLMcorrector::addToMapW(unsigned char key, unsigned char value1, unsigned char value2)
-{
-       unsigned long int cnt = m_mapChar[key].size();
-       m_mapChar[key][cnt] = value2;
-       m_mapChar[key][cnt+1] = value1; //reverse for endiannes
-}
-
-// construct the mappings, would be nicer in a separate (importable) file
-void LM2NTLMcorrector::fillMapW()
-{
-       addToMapW(0x01, 0x00, 0x01);
-       addToMapW(0x01, 0x26, 0x3A);
-       addToMapW(0x02, 0x00, 0x02);
-       addToMapW(0x02, 0x26, 0x3B);
-       addToMapW(0x03, 0x00, 0x03);
-       addToMapW(0x03, 0x26, 0x65);
-       addToMapW(0x04, 0x00, 0x04);
-       addToMapW(0x04, 0x26, 0x66);
-       addToMapW(0x05, 0x00, 0x05);
-       addToMapW(0x05, 0x26, 0x63);
-       addToMapW(0x06, 0x00, 0x06);
-       addToMapW(0x06, 0x26, 0x60);
-       addToMapW(0x07, 0x00, 0x07);
-       addToMapW(0x07, 0x00, 0xB7);
-       addToMapW(0x07, 0x20, 0x22);
-       addToMapW(0x07, 0x20, 0x24);
-       addToMapW(0x07, 0x20, 0x26);
-       addToMapW(0x07, 0x22, 0x19);
-       addToMapW(0x07, 0x22, 0xC5);
-       addToMapW(0x07, 0x30, 0xFB);
-       addToMapW(0x08, 0x00, 0x08);
-       addToMapW(0x08, 0x25, 0xD8);
-       addToMapW(0x09, 0x00, 0x09);
-       addToMapW(0x09, 0x20, 0xDD);
-       addToMapW(0x09, 0x25, 0xCB);
-       addToMapW(0x09, 0x30, 0x07);
-       addToMapW(0x0a, 0x00, 0x0A);
-       addToMapW(0x0a, 0x25, 0xD9);
-       addToMapW(0x0b, 0x00, 0x0B);
-       addToMapW(0x0b, 0x26, 0x42);
-       addToMapW(0x0c, 0x00, 0x0C);
-       addToMapW(0x0c, 0x26, 0x40);
-       addToMapW(0x0d, 0x00, 0x0D);
-       addToMapW(0x0d, 0x26, 0x6A);
-       addToMapW(0x0e, 0x00, 0x0E);
-       addToMapW(0x0e, 0x26, 0x6B);
-       addToMapW(0x0f, 0x00, 0x0F);
-       addToMapW(0x0f, 0x00, 0xA4);
-       addToMapW(0x0f, 0x26, 0x3C);
-       addToMapW(0x10, 0x00, 0x10);
-       addToMapW(0x10, 0x25, 0xBA);
-       addToMapW(0x11, 0x00, 0x11);
-       addToMapW(0x11, 0x25, 0xC4);
-       addToMapW(0x12, 0x00, 0x12);
-       addToMapW(0x12, 0x21, 0x95);
-       addToMapW(0x13, 0x00, 0x13);
-       addToMapW(0x13, 0x20, 0x3C);
-       addToMapW(0x14, 0x00, 0x14);
-       addToMapW(0x14, 0x00, 0xB6);
-       addToMapW(0x15, 0x00, 0x15);
-       addToMapW(0x15, 0x00, 0xA7);
-       addToMapW(0x16, 0x00, 0x16);
-       addToMapW(0x16, 0x02, 0xC9);
-       addToMapW(0x16, 0x25, 0xAC);
-       addToMapW(0x17, 0x00, 0x17);
-       addToMapW(0x17, 0x21, 0xA8);
-       addToMapW(0x18, 0x00, 0x18);
-       addToMapW(0x18, 0x21, 0x91);
-       addToMapW(0x19, 0x00, 0x19);
-       addToMapW(0x19, 0x21, 0x93);
-       addToMapW(0x1a, 0x00, 0x1A);
-       addToMapW(0x1a, 0x21, 0x92);
-       addToMapW(0x1b, 0x00, 0x1B);
-       addToMapW(0x1b, 0x21, 0x90);
-       addToMapW(0x1c, 0x00, 0x1C);
-       addToMapW(0x1c, 0x22, 0x1F);
-       addToMapW(0x1d, 0x00, 0x1D);
-       addToMapW(0x1d, 0x21, 0x94);
-       addToMapW(0x1e, 0x00, 0x1E);
-       addToMapW(0x1e, 0x25, 0xB2);
-       addToMapW(0x1f, 0x00, 0x1F);
-       addToMapW(0x1f, 0x25, 0xBC);
-       addToMapW(0x20, 0x00, 0x20);
-       addToMapW(0x20, 0x20, 0x00);
-       addToMapW(0x20, 0x20, 0x01);
-       addToMapW(0x20, 0x20, 0x02);
-       addToMapW(0x20, 0x20, 0x03);
-       addToMapW(0x20, 0x20, 0x04);
-       addToMapW(0x20, 0x20, 0x05);
-       addToMapW(0x20, 0x20, 0x06);
-       addToMapW(0x20, 0x30, 0x00);
-       addToMapW(0x21, 0x00, 0x21);
-       addToMapW(0x21, 0x00, 0xA1);
-       addToMapW(0x21, 0x01, 0xC3);
-       addToMapW(0x21, 0xFF, 0x01);
-       addToMapW(0x22, 0x00, 0x22);
-       addToMapW(0x22, 0x00, 0xA8);
-       addToMapW(0x22, 0x02, 0xBA);
-       addToMapW(0x22, 0x03, 0x08);
-       addToMapW(0x22, 0x03, 0x0E);
-       addToMapW(0x22, 0x20, 0x1C);
-       addToMapW(0x22, 0x20, 0x1D);
-       addToMapW(0x22, 0x20, 0x1E);
-       addToMapW(0x22, 0x20, 0x33);
-       addToMapW(0x22, 0x20, 0x35);
-       addToMapW(0x22, 0x27, 0x5D);
-       addToMapW(0x22, 0x27, 0x5E);
-       addToMapW(0x22, 0x30, 0x1D);
-       addToMapW(0x22, 0x30, 0x1E);
-       addToMapW(0x22, 0x30, 0x1F);
-       addToMapW(0x22, 0xFF, 0x02);
-       addToMapW(0x23, 0x00, 0x23);
-       addToMapW(0x23, 0xFF, 0x03);
-       addToMapW(0x24, 0x00, 0x24);
-       addToMapW(0x24, 0xFF, 0x04);
-       addToMapW(0x25, 0x00, 0x25);
-       addToMapW(0x25, 0x06, 0x6A);
-       addToMapW(0x25, 0x20, 0x30);
-       addToMapW(0x25, 0xFF, 0x05);
-       addToMapW(0x26, 0x00, 0x26);
-       addToMapW(0x26, 0xFF, 0x06);
-       addToMapW(0x27, 0x00, 0x27);
-       addToMapW(0x27, 0x00, 0xB4);
-       addToMapW(0x27, 0x02, 0xB9);
-       addToMapW(0x27, 0x02, 0xBB);
-       addToMapW(0x27, 0x02, 0xBC);
-       addToMapW(0x27, 0x02, 0xC8);
-       addToMapW(0x27, 0x02, 0xCA);
-       addToMapW(0x27, 0x02, 0xCB);
-       addToMapW(0x27, 0x03, 0x00);
-       addToMapW(0x27, 0x03, 0x01);
-       addToMapW(0x27, 0x20, 0x18);
-       addToMapW(0x27, 0x20, 0x19);
-       addToMapW(0x27, 0x20, 0x1A);
-       addToMapW(0x27, 0x20, 0x32);
-       addToMapW(0x27, 0x27, 0x5B);
-       addToMapW(0x27, 0x27, 0x5C);
-       addToMapW(0x27, 0xFF, 0x07);
-       addToMapW(0x28, 0x00, 0x28);
-       addToMapW(0x28, 0x23, 0x20);
-       addToMapW(0x28, 0xFF, 0x08);
-       addToMapW(0x29, 0x00, 0x29);
-       addToMapW(0x29, 0x23, 0x21);
-       addToMapW(0x29, 0xFF, 0x09);
-       addToMapW(0x2a, 0x00, 0x2A);
-       addToMapW(0x2a, 0x22, 0x17);
-       addToMapW(0x2a, 0xFF, 0x0A);
-       addToMapW(0x2b, 0x00, 0x2B);
-       addToMapW(0x2b, 0x00, 0xB1);
-       addToMapW(0x2b, 0x20, 0x20);
-       addToMapW(0x2b, 0x20, 0x21);
-       addToMapW(0x2b, 0xFF, 0x0B);
-       addToMapW(0x2c, 0x00, 0x2C);
-       addToMapW(0x2c, 0x00, 0xB8);
-       addToMapW(0x2c, 0x03, 0x27);
-       addToMapW(0x2c, 0x20, 0x1A);
-       addToMapW(0x2c, 0x20, 0x1E);
-       addToMapW(0x2c, 0xFF, 0x0C);
-       addToMapW(0x2d, 0x00, 0x2D);
-       addToMapW(0x2d, 0x00, 0xAC);
-       addToMapW(0x2d, 0x00, 0xAD);
-       addToMapW(0x2d, 0x20, 0x10);
-       addToMapW(0x2d, 0x20, 0x11);
-       addToMapW(0x2d, 0x20, 0x13);
-       addToMapW(0x2d, 0x20, 0x14);
-       addToMapW(0x2d, 0x22, 0x12);
-       addToMapW(0x2d, 0x22, 0x13);
-       addToMapW(0x2d, 0xFF, 0x0D);
-       addToMapW(0x2e, 0x00, 0x2E);
-       addToMapW(0x2e, 0x20, 0x26);
-       addToMapW(0x2e, 0xFF, 0x0E);
-       addToMapW(0x2f, 0x00, 0x2F);
-       addToMapW(0x2f, 0x20, 0x44);
-       addToMapW(0x2f, 0x22, 0x15);
-       addToMapW(0x2f, 0x22, 0x16);
-       addToMapW(0x2f, 0xFF, 0x0F);
-       addToMapW(0x30, 0x00, 0x30);
-       addToMapW(0x30, 0x20, 0x70);
-       addToMapW(0x30, 0x20, 0x80);
-       addToMapW(0x30, 0xFF, 0x10);
-       addToMapW(0x31, 0x00, 0x31);
-       addToMapW(0x31, 0x00, 0xB9);
-       addToMapW(0x31, 0x00, 0xBC);
-       addToMapW(0x31, 0x00, 0xBD);
-       addToMapW(0x31, 0x20, 0x81);
-       addToMapW(0x31, 0xFF, 0x11);
-       addToMapW(0x32, 0x00, 0x32);
-       addToMapW(0x32, 0x00, 0xB2);
-       addToMapW(0x32, 0x20, 0x82);
-       addToMapW(0x32, 0xFF, 0x12);
-       addToMapW(0x33, 0x00, 0x33);
-       addToMapW(0x33, 0x00, 0xB3);
-       addToMapW(0x33, 0x00, 0xBE);
-       addToMapW(0x33, 0x20, 0x83);
-       addToMapW(0x33, 0xFF, 0x13);
-       addToMapW(0x34, 0x00, 0x34);
-       addToMapW(0x34, 0x20, 0x74);
-       addToMapW(0x34, 0x20, 0x84);
-       addToMapW(0x34, 0xFF, 0x14);
-       addToMapW(0x35, 0x00, 0x35);
-       addToMapW(0x35, 0x20, 0x75);
-       addToMapW(0x35, 0x20, 0x85);
-       addToMapW(0x35, 0xFF, 0x15);
-       addToMapW(0x36, 0x00, 0x36);
-       addToMapW(0x36, 0x20, 0x76);
-       addToMapW(0x36, 0x20, 0x86);
-       addToMapW(0x36, 0xFF, 0x16);
-       addToMapW(0x37, 0x00, 0x37);
-       addToMapW(0x37, 0x20, 0x77);
-       addToMapW(0x37, 0x20, 0x87);
-       addToMapW(0x37, 0xFF, 0x17);
-       addToMapW(0x38, 0x00, 0x38);
-       addToMapW(0x38, 0x20, 0x78);
-       addToMapW(0x38, 0x20, 0x88);
-       addToMapW(0x38, 0x22, 0x1E);
-       addToMapW(0x38, 0xFF, 0x18);
-       addToMapW(0x39, 0x00, 0x39);
-       addToMapW(0x39, 0x20, 0x78);
-       addToMapW(0x39, 0x20, 0x89);
-       addToMapW(0x39, 0xFF, 0x19);
-       addToMapW(0x3a, 0x00, 0x3A);
-       addToMapW(0x3a, 0x05, 0x89);
-       addToMapW(0x3a, 0x20, 0x26);
-       addToMapW(0x3a, 0x22, 0x36);
-       addToMapW(0x3a, 0xFF, 0x1A);
-       addToMapW(0x3b, 0x00, 0x3B);
-       addToMapW(0x3b, 0x03, 0x7E);
-       addToMapW(0x3b, 0xFF, 0x1B);
-       addToMapW(0x3c, 0x00, 0x3C);
-       addToMapW(0x3c, 0x00, 0xAB);
-       addToMapW(0x3c, 0x20, 0x39);
-       addToMapW(0x3c, 0x23, 0x29);
-       addToMapW(0x3c, 0x30, 0x08);
-       addToMapW(0x3c, 0xFF, 0x1C);
-       addToMapW(0x3d, 0x00, 0x3D);
-       addToMapW(0x3d, 0x22, 0x61);
-       addToMapW(0x3d, 0x22, 0x64);
-       addToMapW(0x3d, 0x22, 0x65);
-       addToMapW(0x3d, 0xFF, 0x1D);
-       addToMapW(0x3e, 0x00, 0x3E);
-       addToMapW(0x3e, 0x00, 0xBB);
-       addToMapW(0x3e, 0x20, 0x3A);
-       addToMapW(0x3e, 0x23, 0x2A);
-       addToMapW(0x3e, 0x30, 0x09);
-       addToMapW(0x3e, 0xFF, 0x1E);
-       addToMapW(0x3f, 0x00, 0x3F);
-       addToMapW(0x40, 0x00, 0x40);
-       addToMapW(0x40, 0xFF, 0x20);
-       addToMapW(0x41, 0x00, 0x41);
-       addToMapW(0x41, 0x00, 0x61);
-       addToMapW(0x41, 0x00, 0xAA);
-       addToMapW(0x41, 0x00, 0xC0);
-       addToMapW(0x41, 0x00, 0xC1);
-       addToMapW(0x41, 0x00, 0xC2);
-       addToMapW(0x41, 0x00, 0xC3);
-       addToMapW(0x41, 0x00, 0xC4);
-       addToMapW(0x41, 0x00, 0xC5);
-       addToMapW(0x41, 0x00, 0xC6);
-       addToMapW(0x41, 0x00, 0xE0);
-       addToMapW(0x41, 0x00, 0xE1);
-       addToMapW(0x41, 0x00, 0xE2);
-       addToMapW(0x41, 0x00, 0xE3);
-       addToMapW(0x41, 0x00, 0xE4);
-       addToMapW(0x41, 0x00, 0xE5);
-       addToMapW(0x41, 0x00, 0xE6);
-       addToMapW(0x41, 0x01, 0x00);
-       addToMapW(0x41, 0x01, 0x01);
-       addToMapW(0x41, 0x01, 0x02);
-       addToMapW(0x41, 0x01, 0x03);
-       addToMapW(0x41, 0x01, 0x04);
-       addToMapW(0x41, 0x01, 0x05);
-       addToMapW(0x41, 0x01, 0xCD);
-       addToMapW(0x41, 0x01, 0xCE);
-       addToMapW(0x41, 0x01, 0xDE);
-       addToMapW(0x41, 0x01, 0xDF);
-       addToMapW(0x41, 0x03, 0xB1);
-       addToMapW(0x41, 0x21, 0x2B);
-       addToMapW(0x41, 0xFF, 0x21);
-       addToMapW(0x41, 0xFF, 0x41);
-       addToMapW(0x42, 0x00, 0x42);
-       addToMapW(0x42, 0x00, 0x62);
-       addToMapW(0x42, 0x01, 0x80);
-       addToMapW(0x42, 0x21, 0x2C);
-       addToMapW(0x42, 0xFF, 0x22);
-       addToMapW(0x42, 0xFF, 0x42);
-       addToMapW(0x43, 0x00, 0x43);
-       addToMapW(0x43, 0x00, 0x63);
-       addToMapW(0x43, 0x00, 0xA2);
-       addToMapW(0x43, 0x00, 0xA9);
-       addToMapW(0x43, 0x00, 0xC7);
-       addToMapW(0x43, 0x00, 0xE7);
-       addToMapW(0x43, 0x00, 0xE8);
-       addToMapW(0x43, 0x01, 0x06);
-       addToMapW(0x43, 0x01, 0x07);
-       addToMapW(0x43, 0x01, 0x08);
-       addToMapW(0x43, 0x01, 0x09);
-       addToMapW(0x43, 0x01, 0x0A);
-       addToMapW(0x43, 0x01, 0x0B);
-       addToMapW(0x43, 0x01, 0x0C);
-       addToMapW(0x43, 0x01, 0x0D);
-       addToMapW(0x43, 0x21, 0x02);
-       addToMapW(0x43, 0x21, 0x2D);
-       addToMapW(0x43, 0xFF, 0x23);
-       addToMapW(0x43, 0xFF, 0x43);
-       addToMapW(0x44, 0x00, 0x44);
-       addToMapW(0x44, 0x00, 0x64);
-       addToMapW(0x44, 0x00, 0xD0);
-       addToMapW(0x44, 0x00, 0xF0);
-       addToMapW(0x44, 0x01, 0x0E);
-       addToMapW(0x44, 0x01, 0x0F);
-       addToMapW(0x44, 0x01, 0x10);
-       addToMapW(0x44, 0x01, 0x11);
-       addToMapW(0x44, 0x01, 0x89);
-       addToMapW(0x44, 0x03, 0xB4);
-       addToMapW(0x44, 0x26, 0x6A);
-       addToMapW(0x44, 0x26, 0x6B);
-       addToMapW(0x44, 0xFF, 0x24);
-       addToMapW(0x44, 0xFF, 0x44);
-       addToMapW(0x45, 0x00, 0x45);
-       addToMapW(0x45, 0x00, 0x65);
-       addToMapW(0x45, 0x00, 0xC8);
-       addToMapW(0x45, 0x00, 0xC9);
-       addToMapW(0x45, 0x00, 0xCA);
-       addToMapW(0x45, 0x00, 0xCB);
-       addToMapW(0x45, 0x00, 0xE8);
-       addToMapW(0x45, 0x00, 0xE9);
-       addToMapW(0x45, 0x00, 0xEA);
-       addToMapW(0x45, 0x00, 0xEB);
-       addToMapW(0x45, 0x01, 0x12);
-       addToMapW(0x45, 0x01, 0x13);
-       addToMapW(0x45, 0x01, 0x14);
-       addToMapW(0x45, 0x01, 0x15);
-       addToMapW(0x45, 0x01, 0x16);
-       addToMapW(0x45, 0x01, 0x17);
-       addToMapW(0x45, 0x01, 0x18);
-       addToMapW(0x45, 0x01, 0x19);
-       addToMapW(0x45, 0x01, 0x1A);
-       addToMapW(0x45, 0x01, 0x1B);
-       addToMapW(0x45, 0x03, 0xB5);
-       addToMapW(0x45, 0x21, 0x07);
-       addToMapW(0x45, 0x21, 0x2E);
-       addToMapW(0x45, 0x21, 0x2F);
-       addToMapW(0x45, 0x21, 0x30);
-       addToMapW(0x45, 0xFF, 0x25);
-       addToMapW(0x45, 0xFF, 0x45);
-       addToMapW(0x46, 0x00, 0x46);
-       addToMapW(0x46, 0x00, 0x66);
-       addToMapW(0x46, 0x01, 0x91);
-       addToMapW(0x46, 0x01, 0x92);
-       addToMapW(0x46, 0x03, 0xA6);
-       addToMapW(0x46, 0x03, 0xC6);
-       addToMapW(0x46, 0x21, 0x31);
-       addToMapW(0x46, 0xFF, 0x26);
-       addToMapW(0x46, 0xFF, 0x46);
-       addToMapW(0x47, 0x00, 0x47);
-       addToMapW(0x47, 0x00, 0x67);
-       addToMapW(0x47, 0x01, 0x1C);
-       addToMapW(0x47, 0x01, 0x1D);
-       addToMapW(0x47, 0x01, 0x1E);
-       addToMapW(0x47, 0x01, 0x1F);
-       addToMapW(0x47, 0x01, 0x20);
-       addToMapW(0x47, 0x01, 0x21);
-       addToMapW(0x47, 0x01, 0x22);
-       addToMapW(0x47, 0x01, 0x23);
-       addToMapW(0x47, 0x01, 0xE4);
-       addToMapW(0x47, 0x01, 0xE5);
-       addToMapW(0x47, 0x01, 0xE6);
-       addToMapW(0x47, 0x01, 0xE7);
-       addToMapW(0x47, 0x02, 0x61);
-       addToMapW(0x47, 0x03, 0x93);
-       addToMapW(0x47, 0x21, 0x0A);
-       addToMapW(0x47, 0xFF, 0x27);
-       addToMapW(0x47, 0xFF, 0x47);
-       addToMapW(0x48, 0x00, 0x48);
-       addToMapW(0x48, 0x00, 0x68);
-       addToMapW(0x48, 0x01, 0x24);
-       addToMapW(0x48, 0x01, 0x25);
-       addToMapW(0x48, 0x01, 0x26);
-       addToMapW(0x48, 0x01, 0x27);
-       addToMapW(0x48, 0x04, 0xBB);
-       addToMapW(0x48, 0x21, 0x0B);
-       addToMapW(0x48, 0x21, 0x0C);
-       addToMapW(0x48, 0x21, 0x0D);
-       addToMapW(0x48, 0x21, 0x0E);
-       addToMapW(0x48, 0xFF, 0x28);
-       addToMapW(0x48, 0xFF, 0x48);
-       addToMapW(0x49, 0x00, 0x49);
-       addToMapW(0x49, 0x00, 0x69);
-       addToMapW(0x49, 0x00, 0xCC);
-       addToMapW(0x49, 0x00, 0xCD);
-       addToMapW(0x49, 0x00, 0xCE);
-       addToMapW(0x49, 0x00, 0xCF);
-       addToMapW(0x49, 0x00, 0xEC);
-       addToMapW(0x49, 0x00, 0xED);
-       addToMapW(0x49, 0x00, 0xEE);
-       addToMapW(0x49, 0x00, 0xEF);
-       addToMapW(0x49, 0x01, 0x28);
-       addToMapW(0x49, 0x01, 0x29);
-       addToMapW(0x49, 0x01, 0x2A);
-       addToMapW(0x49, 0x01, 0x2B);
-       addToMapW(0x49, 0x01, 0x2C);
-       addToMapW(0x49, 0x01, 0x2D);
-       addToMapW(0x49, 0x01, 0x2E);
-       addToMapW(0x49, 0x01, 0x2F);
-       addToMapW(0x49, 0x01, 0x30);
-       addToMapW(0x49, 0x01, 0x31);
-       addToMapW(0x49, 0x01, 0x97);
-       addToMapW(0x49, 0x01, 0xCF);
-       addToMapW(0x49, 0x01, 0xD0);
-       addToMapW(0x49, 0x21, 0x10);
-       addToMapW(0x49, 0x21, 0x11);
-       addToMapW(0x49, 0xFF, 0x29);
-       addToMapW(0x49, 0xFF, 0x49);
-       addToMapW(0x4a, 0x00, 0x4A);
-       addToMapW(0x4a, 0x00, 0x6A);
-       addToMapW(0x4a, 0x01, 0x34);
-       addToMapW(0x4a, 0x01, 0x35);
-       addToMapW(0x4a, 0x01, 0xF0);
-       addToMapW(0x4a, 0xFF, 0x2A);
-       addToMapW(0x4a, 0xFF, 0x4A);
-       addToMapW(0x4b, 0x00, 0x4B);
-       addToMapW(0x4b, 0x00, 0x6B);
-       addToMapW(0x4b, 0x01, 0x36);
-       addToMapW(0x4b, 0x01, 0x37);
-       addToMapW(0x4b, 0x01, 0xE8);
-       addToMapW(0x4b, 0x01, 0xE9);
-       addToMapW(0x4b, 0x21, 0x2A);
-       addToMapW(0x4b, 0xFF, 0x2B);
-       addToMapW(0x4b, 0xFF, 0x4B);
-       addToMapW(0x4c, 0x00, 0x4C);
-       addToMapW(0x4c, 0x00, 0x6C);
-       addToMapW(0x4c, 0x00, 0xA3);
-       addToMapW(0x4c, 0x01, 0x39);
-       addToMapW(0x4c, 0x01, 0x3A);
-       addToMapW(0x4c, 0x01, 0x3B);
-       addToMapW(0x4c, 0x01, 0x3C);
-       addToMapW(0x4c, 0x01, 0x3D);
-       addToMapW(0x4c, 0x01, 0x3E);
-       addToMapW(0x4c, 0x01, 0x41);
-       addToMapW(0x4c, 0x01, 0x42);
-       addToMapW(0x4c, 0x01, 0x9A);
-       addToMapW(0x4c, 0x20, 0xA4);
-       addToMapW(0x4c, 0x21, 0x12);
-       addToMapW(0x4c, 0x21, 0x13);
-       addToMapW(0x4c, 0xFF, 0x2C);
-       addToMapW(0x4c, 0xFF, 0x4C);
-       addToMapW(0x4d, 0x00, 0x4D);
-       addToMapW(0x4d, 0x00, 0x6D);
-       addToMapW(0x4d, 0x21, 0x33);
-       addToMapW(0x4d, 0xFF, 0x2D);
-       addToMapW(0x4d, 0xFF, 0x4D);
-       addToMapW(0x4e, 0x00, 0x4E);
-       addToMapW(0x4e, 0x00, 0x6E);
-       addToMapW(0x4e, 0x00, 0xD1);
-       addToMapW(0x4e, 0x00, 0xF1);
-       addToMapW(0x4e, 0x01, 0x43);
-       addToMapW(0x4e, 0x01, 0x44);
-       addToMapW(0x4e, 0x01, 0x45);
-       addToMapW(0x4e, 0x01, 0x46);
-       addToMapW(0x4e, 0x01, 0x47);
-       addToMapW(0x4e, 0x01, 0x48);
-       addToMapW(0x4e, 0x20, 0x7F);
-       addToMapW(0x4e, 0x21, 0x15);
-       addToMapW(0x4e, 0x22, 0x29);
-       addToMapW(0x4e, 0xFF, 0x2E);
-       addToMapW(0x4e, 0xFF, 0x4E);
-       addToMapW(0x4f, 0x00, 0x4F);
-       addToMapW(0x4f, 0x00, 0x6F);
-       addToMapW(0x4f, 0x00, 0xB0);
-       addToMapW(0x4f, 0x00, 0xBA);
-       addToMapW(0x4f, 0x00, 0xD2);
-       addToMapW(0x4f, 0x00, 0xD3);
-       addToMapW(0x4f, 0x00, 0xD4);
-       addToMapW(0x4f, 0x00, 0xD5);
-       addToMapW(0x4f, 0x00, 0xD6);
-       addToMapW(0x4f, 0x00, 0xD8);
-       addToMapW(0x4f, 0x00, 0xF2);
-       addToMapW(0x4f, 0x00, 0xF3);
-       addToMapW(0x4f, 0x00, 0xF4);
-       addToMapW(0x4f, 0x00, 0xF5);
-       addToMapW(0x4f, 0x00, 0xF6);
-       addToMapW(0x4f, 0x00, 0xF8);
-       addToMapW(0x4f, 0x01, 0x4C);
-       addToMapW(0x4f, 0x01, 0x4D);
-       addToMapW(0x4f, 0x01, 0x4E);
-       addToMapW(0x4f, 0x01, 0x4F);
-       addToMapW(0x4f, 0x01, 0x50);
-       addToMapW(0x4f, 0x01, 0x51);
-       addToMapW(0x4f, 0x01, 0x52);
-       addToMapW(0x4f, 0x01, 0x53);
-       addToMapW(0x4f, 0x01, 0x9F);
-       addToMapW(0x4f, 0x01, 0xA0);
-       addToMapW(0x4f, 0x01, 0xA1);
-       addToMapW(0x4f, 0x01, 0xD1);
-       addToMapW(0x4f, 0x01, 0xD2);
-       addToMapW(0x4f, 0x01, 0xEA);
-       addToMapW(0x4f, 0x01, 0xEB);
-       addToMapW(0x4f, 0x01, 0xEC);
-       addToMapW(0x4f, 0x01, 0xED);
-       addToMapW(0x4f, 0x03, 0xA9);
-       addToMapW(0x4f, 0x20, 0xDD);
-       addToMapW(0x4f, 0x21, 0x26);
-       addToMapW(0x4f, 0x21, 0x34);
-       addToMapW(0x4f, 0x22, 0x05);
-       addToMapW(0x4f, 0x30, 0x07);
-       addToMapW(0x4f, 0xFF, 0x2F);
-       addToMapW(0x4f, 0xFF, 0x4F);
-       addToMapW(0x50, 0x00, 0x50);
-       addToMapW(0x50, 0x00, 0x70);
-       addToMapW(0x50, 0x03, 0xC0);
-       addToMapW(0x50, 0x20, 0xA7);
-       addToMapW(0x50, 0x21, 0x18);
-       addToMapW(0x50, 0x21, 0x19);
-       addToMapW(0x50, 0xFF, 0x30);
-       addToMapW(0x50, 0xFF, 0x50);
-       addToMapW(0x51, 0x00, 0x51);
-       addToMapW(0x51, 0x00, 0x71);
-       addToMapW(0x51, 0x21, 0x1A);
-       addToMapW(0x51, 0xFF, 0x31);
-       addToMapW(0x51, 0xFF, 0x51);
-       addToMapW(0x52, 0x00, 0x52);
-       addToMapW(0x52, 0x00, 0x72);
-       addToMapW(0x52, 0x00, 0xAE);
-       addToMapW(0x52, 0x01, 0x54);
-       addToMapW(0x52, 0x01, 0x55);
-       addToMapW(0x52, 0x01, 0x56);
-       addToMapW(0x52, 0x01, 0x57);
-       addToMapW(0x52, 0x01, 0x58);
-       addToMapW(0x52, 0x01, 0x59);
-       addToMapW(0x52, 0x21, 0x1B);
-       addToMapW(0x52, 0x21, 0x1C);
-       addToMapW(0x52, 0x21, 0x1D);
-       addToMapW(0x52, 0xFF, 0x32);
-       addToMapW(0x52, 0xFF, 0x52);
-       addToMapW(0x53, 0x00, 0x53);
-       addToMapW(0x53, 0x00, 0x73);
-       addToMapW(0x53, 0x00, 0xDF);
-       addToMapW(0x53, 0x01, 0x5A);
-       addToMapW(0x53, 0x01, 0x5B);
-       addToMapW(0x53, 0x01, 0x5C);
-       addToMapW(0x53, 0x01, 0x5D);
-       addToMapW(0x53, 0x01, 0x5E);
-       addToMapW(0x53, 0x01, 0x5F);
-       addToMapW(0x53, 0x01, 0x60);
-       addToMapW(0x53, 0x01, 0x61);
-       addToMapW(0x53, 0x01, 0xA9);
-       addToMapW(0x53, 0x03, 0xA3);
-       addToMapW(0x53, 0x03, 0xC3);
-       addToMapW(0x53, 0x22, 0x11);
-       addToMapW(0x53, 0xFF, 0x33);
-       addToMapW(0x53, 0xFF, 0x53);
-       addToMapW(0x54, 0x00, 0x54);
-       addToMapW(0x54, 0x00, 0x74);
-       addToMapW(0x54, 0x00, 0xDE);
-       addToMapW(0x54, 0x00, 0xFE);
-       addToMapW(0x54, 0x01, 0x62);
-       addToMapW(0x54, 0x01, 0x63);
-       addToMapW(0x54, 0x01, 0x64);
-       addToMapW(0x54, 0x01, 0x65);
-       addToMapW(0x54, 0x01, 0x66);
-       addToMapW(0x54, 0x01, 0x67);
-       addToMapW(0x54, 0x01, 0xAB);
-       addToMapW(0x54, 0x01, 0xAE);
-       addToMapW(0x54, 0x03, 0xC4);
-       addToMapW(0x54, 0x21, 0x22);
-       addToMapW(0x54, 0xFF, 0x34);
-       addToMapW(0x54, 0xFF, 0x54);
-       addToMapW(0x55, 0x00, 0x55);
-       addToMapW(0x55, 0x00, 0x75);
-       addToMapW(0x55, 0x00, 0xB5);
-       addToMapW(0x55, 0x00, 0xD9);
-       addToMapW(0x55, 0x00, 0xDA);
-       addToMapW(0x55, 0x00, 0xDB);
-       addToMapW(0x55, 0x00, 0xDC);
-       addToMapW(0x55, 0x00, 0xF9);
-       addToMapW(0x55, 0x00, 0xFA);
-       addToMapW(0x55, 0x00, 0xFB);
-       addToMapW(0x55, 0x00, 0xFC);
-       addToMapW(0x55, 0x01, 0x68);
-       addToMapW(0x55, 0x01, 0x69);
-       addToMapW(0x55, 0x01, 0x6A);
-       addToMapW(0x55, 0x01, 0x6B);
-       addToMapW(0x55, 0x01, 0x6C);
-       addToMapW(0x55, 0x01, 0x6D);
-       addToMapW(0x55, 0x01, 0x6E);
-       addToMapW(0x55, 0x01, 0x6F);
-       addToMapW(0x55, 0x01, 0x70);
-       addToMapW(0x55, 0x01, 0x71);
-       addToMapW(0x55, 0x01, 0x72);
-       addToMapW(0x55, 0x01, 0x73);
-       addToMapW(0x55, 0x01, 0xAF);
-       addToMapW(0x55, 0x01, 0xB0);
-       addToMapW(0x55, 0x01, 0xD3);
-       addToMapW(0x55, 0x01, 0xD4);
-       addToMapW(0x55, 0x01, 0xD5);
-       addToMapW(0x55, 0x01, 0xD6);
-       addToMapW(0x55, 0x01, 0xD7);
-       addToMapW(0x55, 0x01, 0xD8);
-       addToMapW(0x55, 0x01, 0xD9);
-       addToMapW(0x55, 0x01, 0xDA);
-       addToMapW(0x55, 0x01, 0xDB);
-       addToMapW(0x55, 0x01, 0xDC);
-       addToMapW(0x55, 0x03, 0xBC);
-       addToMapW(0x55, 0xFF, 0x35);
-       addToMapW(0x55, 0xFF, 0x55);
-       addToMapW(0x56, 0x00, 0x56);
-       addToMapW(0x56, 0x00, 0x76);
-       addToMapW(0x56, 0x22, 0x1A);
-       addToMapW(0x56, 0x27, 0x13);
-       addToMapW(0x56, 0xFF, 0x36);
-       addToMapW(0x56, 0xFF, 0x56);
-       addToMapW(0x57, 0x00, 0x57);
-       addToMapW(0x57, 0x00, 0x77);
-       addToMapW(0x57, 0x01, 0x74);
-       addToMapW(0x57, 0x01, 0x75);
-       addToMapW(0x57, 0xFF, 0x37);
-       addToMapW(0x57, 0xFF, 0x57);
-       addToMapW(0x58, 0x00, 0x58);
-       addToMapW(0x58, 0x00, 0x78);
-       addToMapW(0x58, 0x00, 0xD7);
-       addToMapW(0x58, 0xFF, 0x38);
-       addToMapW(0x58, 0xFF, 0x58);
-       addToMapW(0x59, 0x00, 0x59);
-       addToMapW(0x59, 0x00, 0x79);
-       addToMapW(0x59, 0x00, 0xA5);
-       addToMapW(0x59, 0x00, 0xDD);
-       addToMapW(0x59, 0x00, 0xFD);
-       addToMapW(0x59, 0x00, 0xFF);
-       addToMapW(0x59, 0x01, 0x76);
-       addToMapW(0x59, 0x01, 0x77);
-       addToMapW(0x59, 0x01, 0x78);
-       addToMapW(0x59, 0xFF, 0x39);
-       addToMapW(0x59, 0xFF, 0x59);
-       addToMapW(0x5a, 0x00, 0x5A);
-       addToMapW(0x5a, 0x00, 0x7A);
-       addToMapW(0x5a, 0x01, 0x79);
-       addToMapW(0x5a, 0x01, 0x7A);
-       addToMapW(0x5a, 0x01, 0x7B);
-       addToMapW(0x5a, 0x01, 0x7C);
-       addToMapW(0x5a, 0x01, 0x7D);
-       addToMapW(0x5a, 0x01, 0x7E);
-       addToMapW(0x5a, 0x01, 0xB6);
-       addToMapW(0x5a, 0x21, 0x24);
-       addToMapW(0x5a, 0x21, 0x28);
-       addToMapW(0x5a, 0xFF, 0x3A);
-       addToMapW(0x5a, 0xFF, 0x5A);
-       addToMapW(0x5b, 0x00, 0x5B);
-       addToMapW(0x5b, 0x30, 0x1A);
-       addToMapW(0x5b, 0xFF, 0x3B);
-       addToMapW(0x5c, 0x00, 0x5C);
-       addToMapW(0x5c, 0x00, 0xA5);
-       addToMapW(0x5c, 0x22, 0x16);
-       addToMapW(0x5c, 0xFF, 0x3C);
-       addToMapW(0x5d, 0x00, 0x5D);
-       addToMapW(0x5d, 0x30, 0x1B);
-       addToMapW(0x5d, 0xFF, 0x3D);
-       addToMapW(0x5e, 0x00, 0x5E);
-       addToMapW(0x5e, 0x02, 0xC4);
-       addToMapW(0x5e, 0x02, 0xC6);
-       addToMapW(0x5e, 0x02, 0xC7);
-       addToMapW(0x5e, 0x02, 0xD8);
-       addToMapW(0x5e, 0x03, 0x02);
-       addToMapW(0x5e, 0x03, 0x06);
-       addToMapW(0x5e, 0x03, 0x0C);
-       addToMapW(0x5e, 0x23, 0x03);
-       addToMapW(0x5e, 0xFF, 0x3E);
-       addToMapW(0x5f, 0x00, 0x5F);
-       addToMapW(0x5f, 0x00, 0xAF);
-       addToMapW(0x5f, 0x00, 0xBE);
-       addToMapW(0x5f, 0x00, 0xDE);
-       addToMapW(0x5f, 0x00, 0xFE);
-       addToMapW(0x5f, 0x02, 0xCD);
-       addToMapW(0x5f, 0x03, 0x31);
-       addToMapW(0x5f, 0x03, 0x32);
-       addToMapW(0x5f, 0x20, 0x17);
-       addToMapW(0x5f, 0x30, 0xFC);
-       addToMapW(0x5f, 0xFF, 0x3F);
-       addToMapW(0x60, 0x00, 0x60);
-       addToMapW(0x60, 0x02, 0xCB);
-       addToMapW(0x60, 0x03, 0x00);
-       addToMapW(0x60, 0x20, 0x18);
-       addToMapW(0x60, 0x20, 0x35);
-       addToMapW(0x60, 0xFF, 0x40);
-       addToMapW(0x7b, 0x00, 0x7B);
-       addToMapW(0x7b, 0xFF, 0x5B);
-       addToMapW(0x7c, 0x00, 0x7C);
-       addToMapW(0x7c, 0x00, 0xA6);
-       addToMapW(0x7c, 0x01, 0xC0);
-       addToMapW(0x7c, 0x22, 0x23);
-       addToMapW(0x7c, 0x27, 0x58);
-       addToMapW(0x7c, 0xFF, 0x5C);
-       addToMapW(0x7d, 0x00, 0x7D);
-       addToMapW(0x7d, 0x30, 0x1B);
-       addToMapW(0x7d, 0xFF, 0x5D);
-       addToMapW(0x7e, 0x00, 0x7E);
-       addToMapW(0x7e, 0x02, 0xDC);
-       addToMapW(0x7e, 0x03, 0x03);
-       addToMapW(0x7e, 0x22, 0x3C);
-       addToMapW(0x7e, 0x22, 0x48);
-       addToMapW(0x7e, 0xFF, 0x5E);
-       addToMapW(0x7f, 0x00, 0x7F);
-       addToMapW(0x7f, 0x23, 0x02);
-       addToMapW(0x7f, 0x26, 0x60);
-       addToMapW(0x7f, 0x26, 0x63);
-       addToMapW(0x7f, 0x26, 0x65);
-       addToMapW(0x7f, 0x26, 0x66);
-       addToMapW(0x80, 0x00, 0x80);
-       addToMapW(0x80, 0x00, 0xC7);
-       addToMapW(0x80, 0x00, 0xE7);
-       addToMapW(0x80, 0x01, 0x06);
-       addToMapW(0x80, 0x01, 0x07);
-       addToMapW(0x80, 0x03, 0x91);
-       addToMapW(0x80, 0x03, 0xB1);
-       addToMapW(0x80, 0x04, 0x10);
-       addToMapW(0x80, 0x04, 0x30);
-       addToMapW(0x80, 0x05, 0xD0);
-       addToMapW(0x80, 0x20, 0xAC);
-       addToMapW(0x81, 0x00, 0x81);
-       addToMapW(0x81, 0x03, 0x92);
-       addToMapW(0x81, 0x03, 0xB2);
-       addToMapW(0x81, 0x04, 0x02);
-       addToMapW(0x81, 0x04, 0x11);
-       addToMapW(0x81, 0x04, 0x31);
-       addToMapW(0x81, 0x04, 0x52);
-       addToMapW(0x81, 0x05, 0xD1);
-       addToMapW(0x82, 0x00, 0x82);
-       addToMapW(0x82, 0x03, 0x93);
-       addToMapW(0x82, 0x03, 0xB3);
-       addToMapW(0x82, 0x04, 0x12);
-       addToMapW(0x82, 0x04, 0x32);
-       addToMapW(0x82, 0x05, 0xD2);
-       addToMapW(0x82, 0x20, 0x1A);
-       addToMapW(0x83, 0x00, 0x83);
-       addToMapW(0x83, 0x03, 0x94);
-       addToMapW(0x83, 0x03, 0xB4);
-       addToMapW(0x83, 0x04, 0x03);
-       addToMapW(0x83, 0x04, 0x13);
-       addToMapW(0x83, 0x04, 0x33);
-       addToMapW(0x83, 0x04, 0x53);
-       addToMapW(0x83, 0x05, 0xD3);
-       addToMapW(0x84, 0x00, 0x84);
-       addToMapW(0x84, 0x03, 0x95);
-       addToMapW(0x84, 0x03, 0xB5);
-       addToMapW(0x84, 0x04, 0x14);
-       addToMapW(0x84, 0x04, 0x34);
-       addToMapW(0x84, 0x05, 0xD4);
-       addToMapW(0x84, 0x20, 0x1E);
-       addToMapW(0x85, 0x03, 0x96);
-       addToMapW(0x85, 0x03, 0xB6);
-       addToMapW(0x85, 0x04, 0x01);
-       addToMapW(0x85, 0x04, 0x15);
-       addToMapW(0x85, 0x04, 0x35);
-       addToMapW(0x85, 0x04, 0x51);
-       addToMapW(0x85, 0x05, 0xD5);
-       addToMapW(0x85, 0x20, 0x26);
-       addToMapW(0x86, 0x00, 0x86);
-       addToMapW(0x86, 0x03, 0x97);
-       addToMapW(0x86, 0x03, 0xB7);
-       addToMapW(0x86, 0x04, 0x16);
-       addToMapW(0x86, 0x04, 0x36);
-       addToMapW(0x86, 0x05, 0xD6);
-       addToMapW(0x86, 0x20, 0x20);
-       addToMapW(0x87, 0x00, 0x87);
-       addToMapW(0x87, 0x03, 0x98);
-       addToMapW(0x87, 0x03, 0xB8);
-       addToMapW(0x87, 0x04, 0x04);
-       addToMapW(0x87, 0x04, 0x17);
-       addToMapW(0x87, 0x04, 0x37);
-       addToMapW(0x87, 0x04, 0x54);
-       addToMapW(0x87, 0x05, 0xD7);
-       addToMapW(0x87, 0x20, 0x21);
-       addToMapW(0x88, 0x00, 0x88);
-       addToMapW(0x88, 0x02, 0xC6);
-       addToMapW(0x88, 0x03, 0x99);
-       addToMapW(0x88, 0x03, 0xB9);
-       addToMapW(0x88, 0x04, 0x18);
-       addToMapW(0x88, 0x04, 0x38);
-       addToMapW(0x88, 0x05, 0xD8);
-       addToMapW(0x89, 0x00, 0x89);
-       addToMapW(0x89, 0x03, 0x9A);
-       addToMapW(0x89, 0x03, 0xBA);
-       addToMapW(0x89, 0x04, 0x05);
-       addToMapW(0x89, 0x04, 0x19);
-       addToMapW(0x89, 0x04, 0x39);
-       addToMapW(0x89, 0x04, 0x55);
-       addToMapW(0x89, 0x05, 0xD9);
-       addToMapW(0x89, 0x20, 0x30);
-       addToMapW(0x8a, 0x00, 0x8A);
-       addToMapW(0x8a, 0x01, 0x50);
-       addToMapW(0x8a, 0x01, 0x51);
-       addToMapW(0x8a, 0x01, 0x56);
-       addToMapW(0x8a, 0x01, 0x57);
-       addToMapW(0x8a, 0x03, 0x9B);
-       addToMapW(0x8a, 0x03, 0xBB);
-       addToMapW(0x8a, 0x04, 0x1A);
-       addToMapW(0x8a, 0x04, 0x3A);
-       addToMapW(0x8a, 0x05, 0xDA);
-       addToMapW(0x8b, 0x00, 0x8B);
-       addToMapW(0x8b, 0x03, 0x9C);
-       addToMapW(0x8b, 0x03, 0xBC);
-       addToMapW(0x8b, 0x04, 0x06);
-       addToMapW(0x8b, 0x04, 0x1B);
-       addToMapW(0x8b, 0x04, 0x3B);
-       addToMapW(0x8b, 0x04, 0x56);
-       addToMapW(0x8b, 0x05, 0xDB);
-       addToMapW(0x8b, 0x20, 0x39);
-       addToMapW(0x8c, 0x00, 0x8C);
-       addToMapW(0x8c, 0x01, 0x52);
-       addToMapW(0x8c, 0x01, 0x53);
-       addToMapW(0x8c, 0x03, 0x9D);
-       addToMapW(0x8c, 0x03, 0xBD);
-       addToMapW(0x8c, 0x04, 0x1C);
-       addToMapW(0x8c, 0x04, 0x3C);
-       addToMapW(0x8c, 0x05, 0xDC);
-       addToMapW(0x8d, 0x00, 0x8D);
-       addToMapW(0x8d, 0x01, 0x31);
-       addToMapW(0x8d, 0x01, 0x79);
-       addToMapW(0x8d, 0x01, 0x7A);
-       addToMapW(0x8d, 0x03, 0x9E);
-       addToMapW(0x8d, 0x03, 0xBE);
-       addToMapW(0x8d, 0x04, 0x07);
-       addToMapW(0x8d, 0x04, 0x1D);
-       addToMapW(0x8d, 0x04, 0x3D);
-       addToMapW(0x8d, 0x04, 0x57);
-       addToMapW(0x8d, 0x05, 0xDD);
-       addToMapW(0x8e, 0x00, 0x8E);
-       addToMapW(0x8e, 0x00, 0xC4);
-       addToMapW(0x8e, 0x00, 0xE4);
-       addToMapW(0x8e, 0x03, 0x9F);
-       addToMapW(0x8e, 0x03, 0xBF);
-       addToMapW(0x8e, 0x04, 0x1E);
-       addToMapW(0x8e, 0x04, 0x3E);
-       addToMapW(0x8e, 0x05, 0xDE);
-       addToMapW(0x8f, 0x00, 0x8F);
-       addToMapW(0x8f, 0x00, 0xC5);
-       addToMapW(0x8f, 0x00, 0xE5);
-       addToMapW(0x8f, 0x01, 0x06);
-       addToMapW(0x8f, 0x01, 0x07);
-       addToMapW(0x8f, 0x03, 0xA0);
-       addToMapW(0x8f, 0x03, 0xC0);
-       addToMapW(0x8f, 0x04, 0x08);
-       addToMapW(0x8f, 0x04, 0x1F);
-       addToMapW(0x8f, 0x04, 0x3F);
-       addToMapW(0x8f, 0x04, 0x58);
-       addToMapW(0x8f, 0x05, 0xDF);
-       addToMapW(0x8f, 0x21, 0x2B);
-       addToMapW(0x90, 0x00, 0x90);
-       addToMapW(0x90, 0x00, 0xC9);
-       addToMapW(0x90, 0x00, 0xE9);
-       addToMapW(0x90, 0x03, 0xA1);
-       addToMapW(0x90, 0x03, 0xC1);
-       addToMapW(0x90, 0x04, 0x20);
-       addToMapW(0x90, 0x04, 0x40);
-       addToMapW(0x90, 0x05, 0xE0);
-       addToMapW(0x91, 0x01, 0x39);
-       addToMapW(0x91, 0x01, 0x3A);
-       addToMapW(0x91, 0x03, 0xA3);
-       addToMapW(0x91, 0x03, 0xC2);
-       addToMapW(0x91, 0x03, 0xC3);
-       addToMapW(0x91, 0x04, 0x09);
-       addToMapW(0x91, 0x04, 0x21);
-       addToMapW(0x91, 0x04, 0x41);
-       addToMapW(0x91, 0x04, 0x59);
-       addToMapW(0x91, 0x05, 0xE1);
-       addToMapW(0x91, 0x06, 0x51);
-       addToMapW(0x91, 0x20, 0x18);
-       addToMapW(0x91, 0xFE, 0x7C);
-       addToMapW(0x91, 0xFE, 0x7D);
-       addToMapW(0x92, 0x00, 0xC6);
-       addToMapW(0x92, 0x00, 0xE6);
-       addToMapW(0x92, 0x03, 0xA4);
-       addToMapW(0x92, 0x03, 0xC4);
-       addToMapW(0x92, 0x04, 0x22);
-       addToMapW(0x92, 0x04, 0x42);
-       addToMapW(0x92, 0x05, 0xE2);
-       addToMapW(0x92, 0x06, 0x52);
-       addToMapW(0x92, 0x20, 0x19);
-       addToMapW(0x92, 0xFE, 0x7E);
-       addToMapW(0x92, 0xFE, 0x7F);
-       addToMapW(0x93, 0x03, 0xA5);
-       addToMapW(0x93, 0x03, 0xC5);
-       addToMapW(0x93, 0x04, 0x0A);
-       addToMapW(0x93, 0x04, 0x23);
-       addToMapW(0x93, 0x04, 0x43);
-       addToMapW(0x93, 0x04, 0x5A);
-       addToMapW(0x93, 0x05, 0xE3);
-       addToMapW(0x93, 0x20, 0x1C);
-       addToMapW(0x94, 0x00, 0xA4);
-       addToMapW(0x94, 0x03, 0xA6);
-       addToMapW(0x94, 0x03, 0xC6);
-       addToMapW(0x94, 0x04, 0x24);
-       addToMapW(0x94, 0x04, 0x44);
-       addToMapW(0x94, 0x05, 0xE4);
-       addToMapW(0x94, 0x20, 0x1D);
-       addToMapW(0x95, 0x01, 0x22);
-       addToMapW(0x95, 0x01, 0x23);
-       addToMapW(0x95, 0x01, 0x3D);
-       addToMapW(0x95, 0x01, 0x3E);
-       addToMapW(0x95, 0x03, 0xA7);
-       addToMapW(0x95, 0x03, 0xC7);
-       addToMapW(0x95, 0x04, 0x0B);
-       addToMapW(0x95, 0x04, 0x25);
-       addToMapW(0x95, 0x04, 0x45);
-       addToMapW(0x95, 0x04, 0x5B);
-       addToMapW(0x95, 0x05, 0xE5);
-       addToMapW(0x95, 0x06, 0x40);
-       addToMapW(0x95, 0x20, 0x22);
-       addToMapW(0x96, 0x00, 0xA2);
-       addToMapW(0x96, 0x03, 0xA8);
-       addToMapW(0x96, 0x03, 0xC8);
-       addToMapW(0x96, 0x04, 0x26);
-       addToMapW(0x96, 0x04, 0x46);
-       addToMapW(0x96, 0x05, 0xE6);
-       addToMapW(0x96, 0x20, 0x13);
-       addToMapW(0x97, 0x00, 0xB5);
-       addToMapW(0x97, 0x01, 0x5A);
-       addToMapW(0x97, 0x01, 0x5B);
-       addToMapW(0x97, 0x03, 0xA9);
-       addToMapW(0x97, 0x03, 0xC9);
-       addToMapW(0x97, 0x04, 0x0C);
-       addToMapW(0x97, 0x04, 0x27);
-       addToMapW(0x97, 0x04, 0x47);
-       addToMapW(0x97, 0x04, 0x5C);
-       addToMapW(0x97, 0x05, 0xE7);
-       addToMapW(0x97, 0x20, 0x14);
-       addToMapW(0x98, 0x00, 0x98);
-       addToMapW(0x98, 0x01, 0x30);
-       addToMapW(0x98, 0x02, 0xDC);
-       addToMapW(0x98, 0x04, 0x28);
-       addToMapW(0x98, 0x04, 0x48);
-       addToMapW(0x98, 0x05, 0xE8);
-       addToMapW(0x98, 0x06, 0x21);
-       addToMapW(0x98, 0xFE, 0x80);
-       addToMapW(0x99, 0x00, 0x99);
-       addToMapW(0x99, 0x00, 0xD6);
-       addToMapW(0x99, 0x00, 0xF6);
-       addToMapW(0x99, 0x04, 0x0E);
-       addToMapW(0x99, 0x04, 0x29);
-       addToMapW(0x99, 0x04, 0x49);
-       addToMapW(0x99, 0x04, 0x5E);
-       addToMapW(0x99, 0x05, 0xE9);
-       addToMapW(0x99, 0x06, 0x22);
-       addToMapW(0x99, 0x21, 0x22);
-       addToMapW(0x99, 0xFE, 0x81);
-       addToMapW(0x99, 0xFE, 0x82);
-       addToMapW(0x9a, 0x00, 0x9A);
-       addToMapW(0x9a, 0x00, 0xDC);
-       addToMapW(0x9a, 0x00, 0xFC);
-       addToMapW(0x9a, 0x04, 0x2A);
-       addToMapW(0x9a, 0x04, 0x4A);
-       addToMapW(0x9a, 0x05, 0xEA);
-       addToMapW(0x9a, 0x06, 0x23);
-       addToMapW(0x9a, 0xFE, 0x83);
-       addToMapW(0x9a, 0xFE, 0x84);
-       addToMapW(0x9b, 0x00, 0x9B);
-       addToMapW(0x9b, 0x00, 0xA2);
-       addToMapW(0x9b, 0x01, 0x64);
-       addToMapW(0x9b, 0x01, 0x65);
-       addToMapW(0x9b, 0x04, 0x0F);
-       addToMapW(0x9b, 0x04, 0x2B);
-       addToMapW(0x9b, 0x04, 0x4B);
-       addToMapW(0x9b, 0x04, 0x5F);
-       addToMapW(0x9b, 0x06, 0x24);
-       addToMapW(0x9b, 0x20, 0x3A);
-       addToMapW(0x9b, 0xFE, 0x85);
-       addToMapW(0x9b, 0xFE, 0x86);
-       addToMapW(0x9c, 0x00, 0x9C);
-       addToMapW(0x9c, 0x00, 0xA3);
-       addToMapW(0x9c, 0x04, 0x2C);
-       addToMapW(0x9c, 0x04, 0x4C);
-       addToMapW(0x9c, 0x20, 0xA4);
-       addToMapW(0x9d, 0x00, 0x9D);
-       addToMapW(0x9d, 0x00, 0xA5);
-       addToMapW(0x9d, 0x00, 0xD8);
-       addToMapW(0x9d, 0x00, 0xF8);
-       addToMapW(0x9d, 0x01, 0x41);
-       addToMapW(0x9d, 0x01, 0x42);
-       addToMapW(0x9d, 0x02, 0x78);
-       addToMapW(0x9d, 0x03, 0x98);
-       addToMapW(0x9d, 0x04, 0x2D);
-       addToMapW(0x9d, 0x04, 0x2E);
-       addToMapW(0x9d, 0x04, 0x4D);
-       addToMapW(0x9d, 0x04, 0x4E);
-       addToMapW(0x9d, 0x06, 0x25);
-       addToMapW(0x9d, 0x22, 0x05);
-       addToMapW(0x9d, 0xFE, 0x87);
-       addToMapW(0x9d, 0xFE, 0x88);
-       addToMapW(0x9e, 0x00, 0x9E);
-       addToMapW(0x9e, 0x00, 0xD7);
-       addToMapW(0x9e, 0x01, 0x5E);
-       addToMapW(0x9e, 0x01, 0x5F);
-       addToMapW(0x9e, 0x04, 0x2E);
-       addToMapW(0x9e, 0x04, 0x4E);
-       addToMapW(0x9e, 0x06, 0x26);
-       addToMapW(0x9e, 0x20, 0xA7);
-       addToMapW(0x9e, 0xFE, 0x89);
-       addToMapW(0x9e, 0xFE, 0x8A);
-       addToMapW(0x9e, 0xFE, 0x8B);
-       addToMapW(0x9e, 0xFE, 0x8C);
-       addToMapW(0x9f, 0x00, 0x9F);
-       addToMapW(0x9f, 0x00, 0xA4);
-       addToMapW(0x9f, 0x00, 0xFF);
-       addToMapW(0x9f, 0x01, 0x78);
-       addToMapW(0x9f, 0x01, 0x91);
-       addToMapW(0x9f, 0x01, 0x92);
-       addToMapW(0x9f, 0x04, 0x2A);
-       addToMapW(0x9f, 0x04, 0x2F);
-       addToMapW(0x9f, 0x04, 0x4A);
-       addToMapW(0x9f, 0x04, 0x4F);
-       addToMapW(0x9f, 0x06, 0x27);
-       addToMapW(0x9f, 0xFE, 0x8D);
-       addToMapW(0x9f, 0xFE, 0x8E);
-       addToMapW(0xa0, 0x00, 0xA0);
-       addToMapW(0xa0, 0x01, 0x00);
-       addToMapW(0xa0, 0x01, 0x01);
-       addToMapW(0xa0, 0x06, 0x28);
-       addToMapW(0xa0, 0xF8, 0xF0);
-       addToMapW(0xa0, 0xFE, 0x8F);
-       addToMapW(0xa0, 0xFE, 0x90);
-       addToMapW(0xa0, 0xFE, 0x91);
-       addToMapW(0xa0, 0xFE, 0x92);
-       addToMapW(0xa1, 0x00, 0xA1);
-       addToMapW(0xa1, 0x01, 0x2A);
-       addToMapW(0xa1, 0x01, 0x2B);
-       addToMapW(0xa1, 0x04, 0x10);
-       addToMapW(0xa1, 0x04, 0x30);
-       addToMapW(0xa1, 0x06, 0x29);
-       addToMapW(0xa1, 0x0E, 0x01);
-       addToMapW(0xa1, 0xFE, 0x93);
-       addToMapW(0xa1, 0xFE, 0x94);
-       addToMapW(0xa1, 0xFF, 0x61);
-       addToMapW(0xa2, 0x00, 0xA2);
-       addToMapW(0xa2, 0x06, 0x2A);
-       addToMapW(0xa2, 0x0E, 0x02);
-       addToMapW(0xa2, 0xFE, 0x95);
-       addToMapW(0xa2, 0xFE, 0x96);
-       addToMapW(0xa2, 0xFE, 0x97);
-       addToMapW(0xa2, 0xFE, 0x98);
-       addToMapW(0xa2, 0xFF, 0x62);
-       addToMapW(0xa3, 0x00, 0xA3);
-       addToMapW(0xa3, 0x01, 0x7B);
-       addToMapW(0xa3, 0x01, 0x7C);
-       addToMapW(0xa3, 0x04, 0x11);
-       addToMapW(0xa3, 0x04, 0x31);
-       addToMapW(0xa3, 0x06, 0x2B);
-       addToMapW(0xa3, 0x0E, 0x03);
-       addToMapW(0xa3, 0xFE, 0x99);
-       addToMapW(0xa3, 0xFE, 0x9A);
-       addToMapW(0xa3, 0xFE, 0x9B);
-       addToMapW(0xa3, 0xFE, 0x9C);
-       addToMapW(0xa3, 0xFF, 0x63);
-       addToMapW(0xa4, 0x00, 0xA4);
-       addToMapW(0xa4, 0x01, 0x04);
-       addToMapW(0xa4, 0x01, 0x05);
-       addToMapW(0xa4, 0x06, 0x2C);
-       addToMapW(0xa4, 0x0E, 0x04);
-       addToMapW(0xa4, 0xFE, 0x9D);
-       addToMapW(0xa4, 0xFE, 0x9E);
-       addToMapW(0xa4, 0xFE, 0x9F);
-       addToMapW(0xa4, 0xFE, 0xA0);
-       addToMapW(0xa4, 0xFF, 0x64);
-       addToMapW(0xa5, 0x00, 0xA5);
-       addToMapW(0xa5, 0x00, 0xD1);
-       addToMapW(0xa5, 0x00, 0xF1);
-       addToMapW(0xa5, 0x04, 0x26);
-       addToMapW(0xa5, 0x04, 0x46);
-       addToMapW(0xa5, 0x06, 0x2D);
-       addToMapW(0xa5, 0x0E, 0x05);
-       addToMapW(0xa5, 0xFE, 0xA1);
-       addToMapW(0xa5, 0xFE, 0xA2);
-       addToMapW(0xa5, 0xFE, 0xA3);
-       addToMapW(0xa5, 0xFE, 0xA4);
-       addToMapW(0xa5, 0xFF, 0x65);
-       addToMapW(0xa6, 0x00, 0xA6);
-       addToMapW(0xa6, 0x00, 0xAA);
-       addToMapW(0xa6, 0x01, 0x1E);
-       addToMapW(0xa6, 0x01, 0x1F);
-       addToMapW(0xa6, 0x01, 0x7D);
-       addToMapW(0xa6, 0x01, 0x7E);
-       addToMapW(0xa6, 0x06, 0x2E);
-       addToMapW(0xa6, 0x0E, 0x06);
-       addToMapW(0xa6, 0x20, 0x1D);
-       addToMapW(0xa6, 0xFE, 0xA5);
-       addToMapW(0xa6, 0xFE, 0xA6);
-       addToMapW(0xa6, 0xFE, 0xA7);
-       addToMapW(0xa6, 0xFE, 0xA8);
-       addToMapW(0xa6, 0xFF, 0x66);
-       addToMapW(0xa7, 0x00, 0xA6);
-       addToMapW(0xa7, 0x00, 0xA7);
-       addToMapW(0xa7, 0x00, 0xBA);
-       addToMapW(0xa7, 0x04, 0x14);
-       addToMapW(0xa7, 0x04, 0x34);
-       addToMapW(0xa7, 0x06, 0x2F);
-       addToMapW(0xa7, 0x0E, 0x07);
-       addToMapW(0xa7, 0xFE, 0xA9);
-       addToMapW(0xa7, 0xFE, 0xAA);
-       addToMapW(0xa7, 0xFF, 0x67);
-       addToMapW(0xa8, 0x00, 0xA8);
-       addToMapW(0xa8, 0x00, 0xA9);
-       addToMapW(0xa8, 0x00, 0xBF);
-       addToMapW(0xa8, 0x01, 0x18);
-       addToMapW(0xa8, 0x01, 0x19);
-       addToMapW(0xa8, 0x06, 0x30);
-       addToMapW(0xa8, 0x0E, 0x08);
-       addToMapW(0xa8, 0xFE, 0xAB);
-       addToMapW(0xa8, 0xFE, 0xAC);
-       addToMapW(0xa8, 0xFF, 0x68);
-       addToMapW(0xa9, 0x00, 0xA9);
-       addToMapW(0xa9, 0x00, 0xAE);
-       addToMapW(0xa9, 0x04, 0x15);
-       addToMapW(0xa9, 0x04, 0x35);
-       addToMapW(0xa9, 0x06, 0x31);
-       addToMapW(0xa9, 0x0E, 0x09);
-       addToMapW(0xa9, 0x23, 0x10);
-       addToMapW(0xa9, 0xFE, 0xAD);
-       addToMapW(0xa9, 0xFE, 0xAE);
-       addToMapW(0xa9, 0xFF, 0x69);
-       addToMapW(0xaa, 0x00, 0xAA);
-       addToMapW(0xaa, 0x00, 0xAC);
-       addToMapW(0xaa, 0x06, 0x32);
-       addToMapW(0xaa, 0x0E, 0x0A);
-       addToMapW(0xaa, 0x23, 0x10);
-       addToMapW(0xaa, 0xFE, 0xAF);
-       addToMapW(0xaa, 0xFE, 0xB0);
-       addToMapW(0xaa, 0xFF, 0x6A);
-       addToMapW(0xab, 0x00, 0xAB);
-       addToMapW(0xab, 0x00, 0xBD);
-       addToMapW(0xab, 0x04, 0x24);
-       addToMapW(0xab, 0x04, 0x44);
-       addToMapW(0xab, 0x06, 0x33);
-       addToMapW(0xab, 0x0E, 0x0B);
-       addToMapW(0xab, 0xFE, 0xB1);
-       addToMapW(0xab, 0xFE, 0xB2);
-       addToMapW(0xab, 0xFE, 0xB3);
-       addToMapW(0xab, 0xFE, 0xB4);
-       addToMapW(0xab, 0xFF, 0x6B);
-       addToMapW(0xac, 0x00, 0xAC);
-       addToMapW(0xac, 0x00, 0xBC);
-       addToMapW(0xac, 0x01, 0x0C);
-       addToMapW(0xac, 0x01, 0x0D);
-       addToMapW(0xac, 0x06, 0x34);
-       addToMapW(0xac, 0x0E, 0x0C);
-       addToMapW(0xac, 0xFE, 0xB5);
-       addToMapW(0xac, 0xFE, 0xB6);
-       addToMapW(0xac, 0xFE, 0xB7);
-       addToMapW(0xac, 0xFE, 0xB8);
-       addToMapW(0xac, 0xFF, 0x6C);
-       addToMapW(0xad, 0x00, 0xA1);
-       addToMapW(0xad, 0x00, 0xAD);
-       addToMapW(0xad, 0x01, 0x41);
-       addToMapW(0xad, 0x01, 0x42);
-       addToMapW(0xad, 0x04, 0x13);
-       addToMapW(0xad, 0x04, 0x33);
-       addToMapW(0xad, 0x06, 0x35);
-       addToMapW(0xad, 0x0E, 0x0D);
-       addToMapW(0xad, 0xFE, 0xB9);
-       addToMapW(0xad, 0xFE, 0xBA);
-       addToMapW(0xad, 0xFE, 0xBB);
-       addToMapW(0xad, 0xFE, 0xBC);
-       addToMapW(0xad, 0xFF, 0x6D);
-       addToMapW(0xae, 0x00, 0xAB);
-       addToMapW(0xae, 0x00, 0xAE);
-       addToMapW(0xae, 0x0E, 0x0E);
-       addToMapW(0xae, 0x22, 0x6A);
-       addToMapW(0xae, 0x30, 0x0A);
-       addToMapW(0xae, 0xFF, 0x6E);
-       addToMapW(0xaf, 0x00, 0xAF);
-       addToMapW(0xaf, 0x00, 0xBB);
-       addToMapW(0xaf, 0x0E, 0x0F);
-       addToMapW(0xaf, 0x22, 0x6B);
-       addToMapW(0xaf, 0x30, 0x0B);
-       addToMapW(0xaf, 0xFF, 0x6F);
-       addToMapW(0xb0, 0x00, 0xB0);
-       addToMapW(0xb0, 0x0E, 0x10);
-       addToMapW(0xb0, 0x25, 0x91);
-       addToMapW(0xb0, 0xFF, 0x70);
-       addToMapW(0xb1, 0x00, 0xB1);
-       addToMapW(0xb1, 0x0E, 0x11);
-       addToMapW(0xb1, 0x25, 0x92);
-       addToMapW(0xb1, 0xFF, 0x71);
-       addToMapW(0xb2, 0x00, 0xB2);
-       addToMapW(0xb2, 0x0E, 0x12);
-       addToMapW(0xb2, 0x25, 0x93);
-       addToMapW(0xb2, 0xFF, 0x72);
-       addToMapW(0xb3, 0x00, 0xA6);
-       addToMapW(0xb3, 0x00, 0xB3);
-       addToMapW(0xb3, 0x01, 0xC0);
-       addToMapW(0xb3, 0x0E, 0x13);
-       addToMapW(0xb3, 0x22, 0x23);
-       addToMapW(0xb3, 0x25, 0x02);
-       addToMapW(0xb3, 0x27, 0x58);
-       addToMapW(0xb3, 0xFF, 0x73);
-       addToMapW(0xb4, 0x00, 0xB4);
-       addToMapW(0xb4, 0x0E, 0x14);
-       addToMapW(0xb4, 0x25, 0x24);
-       addToMapW(0xb4, 0xFF, 0x74);
-       addToMapW(0xb5, 0x00, 0xB5);
-       addToMapW(0xb5, 0x00, 0xC1);
-       addToMapW(0xb5, 0x00, 0xE1);
-       addToMapW(0xb5, 0x01, 0x04);
-       addToMapW(0xb5, 0x01, 0x05);
-       addToMapW(0xb5, 0x0E, 0x15);
-       addToMapW(0xb5, 0x25, 0x61);
-       addToMapW(0xb5, 0xFF, 0x75);
-       addToMapW(0xb6, 0x00, 0xB6);
-       addToMapW(0xb6, 0x00, 0xC2);
-       addToMapW(0xb6, 0x00, 0xE2);
-       addToMapW(0xb6, 0x01, 0x0C);
-       addToMapW(0xb6, 0x01, 0x0D);
-       addToMapW(0xb6, 0x04, 0x25);
-       addToMapW(0xb6, 0x04, 0x45);
-       addToMapW(0xb6, 0x0E, 0x16);
-       addToMapW(0xb6, 0x25, 0x62);
-       addToMapW(0xb6, 0xFF, 0x76);
-       addToMapW(0xb7, 0x00, 0xB7);
-       addToMapW(0xb7, 0x00, 0xC0);
-       addToMapW(0xb7, 0x00, 0xE0);
-       addToMapW(0xb7, 0x01, 0x18);
-       addToMapW(0xb7, 0x01, 0x19);
-       addToMapW(0xb7, 0x01, 0x1A);
-       addToMapW(0xb7, 0x01, 0x1B);
-       addToMapW(0xb7, 0x0E, 0x17);
-       addToMapW(0xb7, 0x25, 0x56);
-       addToMapW(0xb7, 0xFF, 0x77);
-       addToMapW(0xb8, 0x00, 0xA9);
-       addToMapW(0xb8, 0x00, 0xB8);
-       addToMapW(0xb8, 0x01, 0x16);
-       addToMapW(0xb8, 0x01, 0x17);
-       addToMapW(0xb8, 0x01, 0x5E);
-       addToMapW(0xb8, 0x01, 0x5F);
-       addToMapW(0xb8, 0x04, 0x18);
-       addToMapW(0xb8, 0x04, 0x38);
-       addToMapW(0xb8, 0x0E, 0x18);
-       addToMapW(0xb8, 0x25, 0x55);
-       addToMapW(0xb8, 0xFF, 0x78);
-       addToMapW(0xb9, 0x00, 0xB9);
-       addToMapW(0xb9, 0x0E, 0x19);
-       addToMapW(0xb9, 0x25, 0x61);
-       addToMapW(0xb9, 0x25, 0x62);
-       addToMapW(0xb9, 0x25, 0x63);
-       addToMapW(0xb9, 0xFF, 0x79);
-       addToMapW(0xba, 0x00, 0xBA);
-       addToMapW(0xba, 0x0E, 0x1A);
-       addToMapW(0xba, 0x25, 0x51);
-       addToMapW(0xba, 0xFF, 0x7A);
-       addToMapW(0xbb, 0x00, 0xBB);
-       addToMapW(0xbb, 0x0E, 0x1B);
-       addToMapW(0xbb, 0x25, 0x55);
-       addToMapW(0xbb, 0x25, 0x56);
-       addToMapW(0xbb, 0x25, 0x57);
-       addToMapW(0xbb, 0xFF, 0x7B);
-       addToMapW(0xbc, 0x00, 0xBC);
-       addToMapW(0xbc, 0x0E, 0x1C);
-       addToMapW(0xbc, 0x25, 0x5B);
-       addToMapW(0xbc, 0x25, 0x5C);
-       addToMapW(0xbc, 0x25, 0x5D);
-       addToMapW(0xbc, 0xFF, 0x7C);
-       addToMapW(0xbd, 0x00, 0xA2);
-       addToMapW(0xbd, 0x00, 0xBD);
-       addToMapW(0xbd, 0x01, 0x2E);
-       addToMapW(0xbd, 0x01, 0x2F);
-       addToMapW(0xbd, 0x01, 0x7B);
-       addToMapW(0xbd, 0x01, 0x7C);
-       addToMapW(0xbd, 0x0E, 0x1D);
-       addToMapW(0xbd, 0x25, 0x5C);
-       addToMapW(0xbd, 0xFF, 0x7D);
-       addToMapW(0xbe, 0x00, 0xA5);
-       addToMapW(0xbe, 0x00, 0xBE);
-       addToMapW(0xbe, 0x01, 0x60);
-       addToMapW(0xbe, 0x01, 0x61);
-       addToMapW(0xbe, 0x04, 0x19);
-       addToMapW(0xbe, 0x04, 0x39);
-       addToMapW(0xbe, 0x0E, 0x1E);
-       addToMapW(0xbe, 0x25, 0x5B);
-       addToMapW(0xbe, 0xFF, 0x7E);
-       addToMapW(0xbf, 0x00, 0xAC);
-       addToMapW(0xbf, 0x00, 0xBF);
-       addToMapW(0xbf, 0x0E, 0x1F);
-       addToMapW(0xbf, 0x25, 0x10);
-       addToMapW(0xbf, 0xFF, 0x7F);
-       addToMapW(0xc0, 0x00, 0xC0);
-       addToMapW(0xc0, 0x00, 0xE0);
-       addToMapW(0xc0, 0x0E, 0x20);
-       addToMapW(0xc0, 0x25, 0x14);
-       addToMapW(0xc0, 0xFF, 0x80);
-       addToMapW(0xc1, 0x00, 0xC1);
-       addToMapW(0xc1, 0x00, 0xE1);
-       addToMapW(0xc1, 0x0E, 0x21);
-       addToMapW(0xc1, 0x25, 0x34);
-       addToMapW(0xc1, 0xFF, 0x81);
-       addToMapW(0xc2, 0x00, 0xC2);
-       addToMapW(0xc2, 0x00, 0xE2);
-       addToMapW(0xc2, 0x0E, 0x22);
-       addToMapW(0xc2, 0x25, 0x2C);
-       addToMapW(0xc2, 0xFF, 0x82);
-       addToMapW(0xc3, 0x01, 0x02);
-       addToMapW(0xc3, 0x01, 0x03);
-       addToMapW(0xc3, 0x0E, 0x23);
-       addToMapW(0xc3, 0x25, 0x1C);
-       addToMapW(0xc3, 0xFF, 0x83);
-       addToMapW(0xc4, 0x00, 0xAF);
-       addToMapW(0xc4, 0x00, 0xC4);
-       addToMapW(0xc4, 0x00, 0xE4);
-       addToMapW(0xc4, 0x02, 0xC9);
-       addToMapW(0xc4, 0x03, 0x04);
-       addToMapW(0xc4, 0x03, 0x05);
-       addToMapW(0xc4, 0x0E, 0x24);
-       addToMapW(0xc4, 0x25, 0x00);
-       addToMapW(0xc4, 0xFF, 0x84);
-       addToMapW(0xc5, 0x00, 0xC5);
-       addToMapW(0xc5, 0x00, 0xE5);
-       addToMapW(0xc5, 0x0E, 0x25);
-       addToMapW(0xc5, 0x20, 0x20);
-       addToMapW(0xc5, 0x20, 0x21);
-       addToMapW(0xc5, 0x25, 0x3C);
-       addToMapW(0xc5, 0xFF, 0x85);
-       addToMapW(0xc6, 0x00, 0xC6);
-       addToMapW(0xc6, 0x00, 0xE6);
-       addToMapW(0xc6, 0x01, 0x02);
-       addToMapW(0xc6, 0x01, 0x03);
-       addToMapW(0xc6, 0x01, 0x72);
-       addToMapW(0xc6, 0x01, 0x73);
-       addToMapW(0xc6, 0x0E, 0x26);
-       addToMapW(0xc6, 0x25, 0x5E);
-       addToMapW(0xc6, 0xFF, 0x86);
-       addToMapW(0xc7, 0x00, 0xC3);
-       addToMapW(0xc7, 0x00, 0xC7);
-       addToMapW(0xc7, 0x00, 0xE3);
-       addToMapW(0xc7, 0x00, 0xE7);
-       addToMapW(0xc7, 0x01, 0x6A);
-       addToMapW(0xc7, 0x01, 0x6B);
-       addToMapW(0xc7, 0x04, 0x1A);
-       addToMapW(0xc7, 0x04, 0x3A);
-       addToMapW(0xc7, 0x0E, 0x27);
-       addToMapW(0xc7, 0x25, 0x5F);
-       addToMapW(0xc7, 0xFF, 0x87);
-       addToMapW(0xc8, 0x00, 0xC8);
-       addToMapW(0xc8, 0x00, 0xE8);
-       addToMapW(0xc8, 0x0E, 0x28);
-       addToMapW(0xc8, 0x25, 0x58);
-       addToMapW(0xc8, 0x25, 0x59);
-       addToMapW(0xc8, 0x25, 0x5A);
-       addToMapW(0xc8, 0xFF, 0x88);
-       addToMapW(0xc9, 0x00, 0xC9);
-       addToMapW(0xc9, 0x00, 0xE9);
-       addToMapW(0xc9, 0x0E, 0x29);
-       addToMapW(0xc9, 0x25, 0x52);
-       addToMapW(0xc9, 0x25, 0x53);
-       addToMapW(0xc9, 0x25, 0x54);
-       addToMapW(0xc9, 0xFF, 0x89);
-       addToMapW(0xca, 0x00, 0xCA);
-       addToMapW(0xca, 0x00, 0xEA);
-       addToMapW(0xca, 0x0E, 0x2A);
-       addToMapW(0xca, 0x25, 0x67);
-       addToMapW(0xca, 0x25, 0x68);
-       addToMapW(0xca, 0x25, 0x69);
-       addToMapW(0xca, 0xFF, 0x8A);
-       addToMapW(0xcb, 0x00, 0xCB);
-       addToMapW(0xcb, 0x00, 0xEB);
-       addToMapW(0xcb, 0x0E, 0x2B);
-       addToMapW(0xcb, 0x25, 0x64);
-       addToMapW(0xcb, 0x25, 0x65);
-       addToMapW(0xcb, 0x25, 0x66);
-       addToMapW(0xcb, 0xFF, 0x8B);
-       addToMapW(0xcc, 0x03, 0x00);
-       addToMapW(0xcc, 0x0E, 0x2C);
-       addToMapW(0xcc, 0x25, 0x5E);
-       addToMapW(0xcc, 0x25, 0x5F);
-       addToMapW(0xcc, 0x25, 0x60);
-       addToMapW(0xcc, 0xFF, 0x8C);
-       addToMapW(0xcd, 0x00, 0xCD);
-       addToMapW(0xcd, 0x00, 0xED);
-       addToMapW(0xcd, 0x0E, 0x2D);
-       addToMapW(0xcd, 0x25, 0x50);
-       addToMapW(0xcd, 0xFF, 0x8D);
-       addToMapW(0xce, 0x00, 0xCE);
-       addToMapW(0xce, 0x00, 0xEE);
-       addToMapW(0xce, 0x0E, 0x2E);
-       addToMapW(0xce, 0x20, 0x21);
-       addToMapW(0xce, 0x25, 0x6A);
-       addToMapW(0xce, 0x25, 0x6B);
-       addToMapW(0xce, 0x25, 0x6C);
-       addToMapW(0xce, 0xFF, 0x8E);
-       addToMapW(0xcf, 0x00, 0xA4);
-       addToMapW(0xcf, 0x00, 0xCF);
-       addToMapW(0xcf, 0x00, 0xEF);
-       addToMapW(0xcf, 0x01, 0x7D);
-       addToMapW(0xcf, 0x01, 0x7E);
-       addToMapW(0xcf, 0x0E, 0x2F);
-       addToMapW(0xcf, 0x25, 0x67);
-       addToMapW(0xcf, 0xFF, 0x8F);
-       addToMapW(0xd0, 0x00, 0xBA);
-       addToMapW(0xd0, 0x01, 0x10);
-       addToMapW(0xd0, 0x01, 0x11);
-       addToMapW(0xd0, 0x0E, 0x30);
-       addToMapW(0xd0, 0x25, 0x68);
-       addToMapW(0xd0, 0xFF, 0x90);
-       addToMapW(0xd1, 0x00, 0xAA);
-       addToMapW(0xd1, 0x00, 0xD0);
-       addToMapW(0xd1, 0x00, 0xD1);
-       addToMapW(0xd1, 0x00, 0xF0);
-       addToMapW(0xd1, 0x00, 0xF1);
-       addToMapW(0xd1, 0x01, 0x10);
-       addToMapW(0xd1, 0x01, 0x11);
-       addToMapW(0xd1, 0x01, 0x89);
-       addToMapW(0xd1, 0x04, 0x1B);
-       addToMapW(0xd1, 0x04, 0x3B);
-       addToMapW(0xd1, 0x0E, 0x31);
-       addToMapW(0xd1, 0x25, 0x64);
-       addToMapW(0xd1, 0xFF, 0x91);
-       addToMapW(0xd2, 0x00, 0xCA);
-       addToMapW(0xd2, 0x00, 0xEA);
-       addToMapW(0xd2, 0x01, 0x0E);
-       addToMapW(0xd2, 0x01, 0x0F);
-       addToMapW(0xd2, 0x03, 0x09);
-       addToMapW(0xd2, 0x0E, 0x32);
-       addToMapW(0xd2, 0x25, 0x65);
-       addToMapW(0xd2, 0xFF, 0x92);
-       addToMapW(0xd3, 0x00, 0xCB);
-       addToMapW(0xd3, 0x00, 0xD3);
-       addToMapW(0xd3, 0x00, 0xEB);
-       addToMapW(0xd3, 0x00, 0xF3);
-       addToMapW(0xd3, 0x04, 0x1C);
-       addToMapW(0xd3, 0x04, 0x3C);
-       addToMapW(0xd3, 0x0E, 0x33);
-       addToMapW(0xd3, 0x25, 0x59);
-       addToMapW(0xd3, 0xFF, 0x93);
-       addToMapW(0xd4, 0x00, 0xC8);
-       addToMapW(0xd4, 0x00, 0xD4);
-       addToMapW(0xd4, 0x00, 0xE8);
-       addToMapW(0xd4, 0x00, 0xF4);
-       addToMapW(0xd4, 0x0E, 0x34);
-       addToMapW(0xd4, 0x25, 0x58);
-       addToMapW(0xd4, 0xFF, 0x94);
-       addToMapW(0xd5, 0x01, 0x31);
-       addToMapW(0xd5, 0x01, 0x47);
-       addToMapW(0xd5, 0x01, 0x48);
-       addToMapW(0xd5, 0x01, 0xA0);
-       addToMapW(0xd5, 0x01, 0xA1);
-       addToMapW(0xd5, 0x04, 0x1D);
-       addToMapW(0xd5, 0x04, 0x3D);
-       addToMapW(0xd5, 0x0E, 0x35);
-       addToMapW(0xd5, 0x25, 0x52);
-       addToMapW(0xd5, 0xF8, 0xBB);
-       addToMapW(0xd5, 0xFF, 0x95);
-       addToMapW(0xd6, 0x00, 0xCD);
-       addToMapW(0xd6, 0x00, 0xD6);
-       addToMapW(0xd6, 0x00, 0xED);
-       addToMapW(0xd6, 0x00, 0xF6);
-       addToMapW(0xd6, 0x0E, 0x36);
-       addToMapW(0xd6, 0x25, 0x53);
-       addToMapW(0xd6, 0xFF, 0x96);
-       addToMapW(0xd7, 0x00, 0xCE);
-       addToMapW(0xd7, 0x00, 0xD7);
-       addToMapW(0xd7, 0x00, 0xEE);
-       addToMapW(0xd7, 0x04, 0x1E);
-       addToMapW(0xd7, 0x04, 0x3E);
-       addToMapW(0xd7, 0x0E, 0x37);
-       addToMapW(0xd7, 0x25, 0x6B);
-       addToMapW(0xd7, 0xFF, 0x97);
-       addToMapW(0xd8, 0x00, 0xCF);
-       addToMapW(0xd8, 0x00, 0xD8);
-       addToMapW(0xd8, 0x00, 0xEF);
-       addToMapW(0xd8, 0x00, 0xF8);
-       addToMapW(0xd8, 0x0E, 0x38);
-       addToMapW(0xd8, 0x20, 0x21);
-       addToMapW(0xd8, 0x25, 0x6A);
-       addToMapW(0xd8, 0xFF, 0x98);
-       addToMapW(0xd9, 0x00, 0xD9);
-       addToMapW(0xd9, 0x00, 0xF9);
-       addToMapW(0xd9, 0x0E, 0x39);
-       addToMapW(0xd9, 0x25, 0x18);
-       addToMapW(0xd9, 0xFF, 0x99);
-       addToMapW(0xda, 0x00, 0xDA);
-       addToMapW(0xda, 0x00, 0xFA);
-       addToMapW(0xda, 0x0E, 0x3A);
-       addToMapW(0xda, 0x25, 0x0C);
-       addToMapW(0xda, 0xFF, 0x9A);
-       addToMapW(0xdb, 0x00, 0xDB);
-       addToMapW(0xdb, 0x00, 0xFB);
-       addToMapW(0xdb, 0x25, 0x88);
-       addToMapW(0xdb, 0x25, 0x8C);
-       addToMapW(0xdb, 0x25, 0x90);
-       addToMapW(0xdb, 0xF8, 0xC1);
-       addToMapW(0xdb, 0xFF, 0x9B);
-       addToMapW(0xdc, 0x00, 0xDC);
-       addToMapW(0xdc, 0x00, 0xFC);
-       addToMapW(0xdc, 0x25, 0x84);
-       addToMapW(0xdc, 0xF8, 0xC2);
-       addToMapW(0xdc, 0xFF, 0x9C);
-       addToMapW(0xdd, 0x00, 0xA6);
-       addToMapW(0xdd, 0x01, 0x62);
-       addToMapW(0xdd, 0x01, 0x63);
-       addToMapW(0xdd, 0x01, 0xAF);
-       addToMapW(0xdd, 0x01, 0xB0);
-       addToMapW(0xdd, 0x04, 0x1F);
-       addToMapW(0xdd, 0x04, 0x3F);
-       addToMapW(0xdd, 0x25, 0x8C);
-       addToMapW(0xdd, 0xF8, 0xC3);
-       addToMapW(0xdd, 0xFF, 0x9D);
-       addToMapW(0xde, 0x00, 0xCC);
-       addToMapW(0xde, 0x00, 0xEC);
-       addToMapW(0xde, 0x01, 0x6E);
-       addToMapW(0xde, 0x01, 0x6F);
-       addToMapW(0xde, 0x03, 0x03);
-       addToMapW(0xde, 0x25, 0x90);
-       addToMapW(0xde, 0xF8, 0xC4);
-       addToMapW(0xde, 0xFF, 0x9E);
-       addToMapW(0xdf, 0x00, 0xDF);
-       addToMapW(0xdf, 0x0E, 0x3F);
-       addToMapW(0xdf, 0x25, 0x80);
-       addToMapW(0xdf, 0xFF, 0x9F);
-       addToMapW(0xe0, 0x00, 0xD3);
-       addToMapW(0xe0, 0x00, 0xF3);
-       addToMapW(0xe0, 0x03, 0x91);
-       addToMapW(0xe0, 0x03, 0xB1);
-       addToMapW(0xe0, 0x04, 0x2F);
-       addToMapW(0xe0, 0x04, 0x4F);
-       addToMapW(0xe0, 0x06, 0x36);
-       addToMapW(0xe0, 0x0E, 0x40);
-       addToMapW(0xe0, 0xFE, 0xBD);
-       addToMapW(0xe0, 0xFE, 0xBE);
-       addToMapW(0xe0, 0xFE, 0xBF);
-       addToMapW(0xe0, 0xFE, 0xC0);
-       addToMapW(0xe1, 0x00, 0xDF);
-       addToMapW(0xe1, 0x03, 0xB2);
-       addToMapW(0xe1, 0x06, 0x37);
-       addToMapW(0xe1, 0x0E, 0x41);
-       addToMapW(0xe1, 0xFE, 0xC1);
-       addToMapW(0xe1, 0xFE, 0xC2);
-       addToMapW(0xe1, 0xFE, 0xC3);
-       addToMapW(0xe1, 0xFE, 0xC4);
-       addToMapW(0xe2, 0x00, 0xD4);
-       addToMapW(0xe2, 0x00, 0xF4);
-       addToMapW(0xe2, 0x01, 0x4C);
-       addToMapW(0xe2, 0x01, 0x4D);
-       addToMapW(0xe2, 0x03, 0x93);
-       addToMapW(0xe2, 0x04, 0x20);
-       addToMapW(0xe2, 0x04, 0x40);
-       addToMapW(0xe2, 0x06, 0x38);
-       addToMapW(0xe2, 0x0E, 0x42);
-       addToMapW(0xe2, 0xFE, 0xC5);
-       addToMapW(0xe2, 0xFE, 0xC6);
-       addToMapW(0xe2, 0xFE, 0xC7);
-       addToMapW(0xe2, 0xFE, 0xC8);
-       addToMapW(0xe3, 0x00, 0xD2);
-       addToMapW(0xe3, 0x00, 0xF2);
-       addToMapW(0xe3, 0x01, 0x43);
-       addToMapW(0xe3, 0x01, 0x44);
-       addToMapW(0xe3, 0x03, 0xA0);
-       addToMapW(0xe3, 0x03, 0xC0);
-       addToMapW(0xe3, 0x06, 0x39);
-       addToMapW(0xe3, 0x0E, 0x43);
-       addToMapW(0xe3, 0xFE, 0xC9);
-       addToMapW(0xe3, 0xFE, 0xCA);
-       addToMapW(0xe3, 0xFE, 0xCB);
-       addToMapW(0xe3, 0xFE, 0xCC);
-       addToMapW(0xe4, 0x01, 0xA9);
-       addToMapW(0xe4, 0x03, 0xA3);
-       addToMapW(0xe4, 0x03, 0xC3);
-       addToMapW(0xe4, 0x04, 0x21);
-       addToMapW(0xe4, 0x04, 0x41);
-       addToMapW(0xe4, 0x06, 0x3A);
-       addToMapW(0xe4, 0x0E, 0x44);
-       addToMapW(0xe4, 0x22, 0x11);
-       addToMapW(0xe4, 0xFE, 0xCD);
-       addToMapW(0xe4, 0xFE, 0xCE);
-       addToMapW(0xe4, 0xFE, 0xCF);
-       addToMapW(0xe4, 0xFE, 0xD0);
-       addToMapW(0xe5, 0x00, 0xD5);
-       addToMapW(0xe5, 0x00, 0xF5);
-       addToMapW(0xe5, 0x06, 0x41);
-       addToMapW(0xe5, 0x0E, 0x45);
-       addToMapW(0xe5, 0xFE, 0xD1);
-       addToMapW(0xe5, 0xFE, 0xD2);
-       addToMapW(0xe5, 0xFE, 0xD3);
-       addToMapW(0xe5, 0xFE, 0xD4);
-       addToMapW(0xe6, 0x00, 0xB5);
-       addToMapW(0xe6, 0x01, 0x60);
-       addToMapW(0xe6, 0x01, 0x61);
-       addToMapW(0xe6, 0x03, 0xBC);
-       addToMapW(0xe6, 0x04, 0x22);
-       addToMapW(0xe6, 0x04, 0x42);
-       addToMapW(0xe6, 0x0E, 0x46);
-       addToMapW(0xe7, 0x03, 0xA4);
-       addToMapW(0xe7, 0x03, 0xC4);
-       addToMapW(0xe7, 0x06, 0x42);
-       addToMapW(0xe7, 0x0E, 0x47);
-       addToMapW(0xe7, 0xF8, 0xBC);
-       addToMapW(0xe7, 0xFE, 0xD5);
-       addToMapW(0xe7, 0xFE, 0xD6);
-       addToMapW(0xe7, 0xFE, 0xD7);
-       addToMapW(0xe7, 0xFE, 0xD8);
-       addToMapW(0xe8, 0x00, 0xD7);
-       addToMapW(0xe8, 0x00, 0xDE);
-       addToMapW(0xe8, 0x00, 0xFE);
-       addToMapW(0xe8, 0x01, 0x36);
-       addToMapW(0xe8, 0x01, 0x37);
-       addToMapW(0xe8, 0x01, 0x54);
-       addToMapW(0xe8, 0x01, 0x55);
-       addToMapW(0xe8, 0x02, 0x78);
-       addToMapW(0xe8, 0x03, 0xA6);
-       addToMapW(0xe8, 0x03, 0xC6);
-       addToMapW(0xe8, 0x04, 0x23);
-       addToMapW(0xe8, 0x04, 0x43);
-       addToMapW(0xe8, 0x06, 0x43);
-       addToMapW(0xe8, 0x0E, 0x48);
-       addToMapW(0xe8, 0x22, 0x05);
-       addToMapW(0xe8, 0xFE, 0xD9);
-       addToMapW(0xe8, 0xFE, 0xDA);
-       addToMapW(0xe8, 0xFE, 0xDB);
-       addToMapW(0xe8, 0xFE, 0xDC);
-       addToMapW(0xe9, 0x00, 0xDA);
-       addToMapW(0xe9, 0x00, 0xFA);
-       addToMapW(0xe9, 0x03, 0x98);
-       addToMapW(0xe9, 0x06, 0x44);
-       addToMapW(0xe9, 0x0E, 0x49);
-       addToMapW(0xe9, 0xFE, 0xDD);
-       addToMapW(0xe9, 0xFE, 0xDE);
-       addToMapW(0xe9, 0xFE, 0xDF);
-       addToMapW(0xe9, 0xFE, 0xE0);
-       addToMapW(0xea, 0x00, 0xDB);
-       addToMapW(0xea, 0x00, 0xFB);
-       addToMapW(0xea, 0x01, 0x3B);
-       addToMapW(0xea, 0x01, 0x3C);
-       addToMapW(0xea, 0x03, 0x86);
-       addToMapW(0xea, 0x03, 0xA9);
-       addToMapW(0xea, 0x03, 0xAC);
-       addToMapW(0xea, 0x04, 0x16);
-       addToMapW(0xea, 0x04, 0x36);
-       addToMapW(0xea, 0x06, 0x45);
-       addToMapW(0xea, 0x0E, 0x4A);
-       addToMapW(0xea, 0x21, 0x26);
-       addToMapW(0xea, 0xFE, 0xE1);
-       addToMapW(0xea, 0xFE, 0xE2);
-       addToMapW(0xea, 0xFE, 0xE3);
-       addToMapW(0xea, 0xFE, 0xE4);
-       addToMapW(0xeb, 0x00, 0xD9);
-       addToMapW(0xeb, 0x00, 0xF9);
-       addToMapW(0xeb, 0x01, 0x70);
-       addToMapW(0xeb, 0x01, 0x71);
-       addToMapW(0xeb, 0x03, 0x88);
-       addToMapW(0xeb, 0x03, 0x94);
-       addToMapW(0xeb, 0x03, 0xAD);
-       addToMapW(0xeb, 0x03, 0xB4);
-       addToMapW(0xeb, 0x06, 0x46);
-       addToMapW(0xeb, 0x0E, 0x4B);
-       addToMapW(0xeb, 0xFE, 0xE5);
-       addToMapW(0xeb, 0xFE, 0xE6);
-       addToMapW(0xeb, 0xFE, 0xE7);
-       addToMapW(0xeb, 0xFE, 0xE8);
-       addToMapW(0xec, 0x03, 0x01);
-       addToMapW(0xec, 0x03, 0x89);
-       addToMapW(0xec, 0x03, 0xAE);
-       addToMapW(0xec, 0x04, 0x12);
-       addToMapW(0xec, 0x04, 0x32);
-       addToMapW(0xec, 0x06, 0x47);
-       addToMapW(0xec, 0x0E, 0x4C);
-       addToMapW(0xec, 0x22, 0x1E);
-       addToMapW(0xec, 0xFE, 0xE9);
-       addToMapW(0xec, 0xFE, 0xEA);
-       addToMapW(0xec, 0xFE, 0xEB);
-       addToMapW(0xec, 0xFE, 0xEC);
-       addToMapW(0xed, 0x00, 0xDD);
-       addToMapW(0xed, 0x00, 0xFD);
-       addToMapW(0xed, 0x01, 0x12);
-       addToMapW(0xed, 0x01, 0x13);
-       addToMapW(0xed, 0x03, 0x8A);
-       addToMapW(0xed, 0x03, 0xAF);
-       addToMapW(0xed, 0x06, 0x48);
-       addToMapW(0xed, 0x0E, 0x4D);
-       addToMapW(0xed, 0xFE, 0xED);
-       addToMapW(0xed, 0xFE, 0xEE);
-       addToMapW(0xee, 0x00, 0xAF);
-       addToMapW(0xee, 0x01, 0x45);
-       addToMapW(0xee, 0x01, 0x46);
-       addToMapW(0xee, 0x03, 0x04);
-       addToMapW(0xee, 0x03, 0x05);
-       addToMapW(0xee, 0x03, 0x8C);
-       addToMapW(0xee, 0x03, 0x95);
-       addToMapW(0xee, 0x03, 0xB5);
-       addToMapW(0xee, 0x03, 0xCC);
-       addToMapW(0xee, 0x04, 0x2C);
-       addToMapW(0xee, 0x04, 0x4C);
-       addToMapW(0xee, 0x06, 0x49);
-       addToMapW(0xee, 0x0E, 0x4E);
-       addToMapW(0xee, 0xFE, 0xEF);
-       addToMapW(0xee, 0xFE, 0xF0);
-       addToMapW(0xef, 0x00, 0xB4);
-       addToMapW(0xef, 0x02, 0xB9);
-       addToMapW(0xef, 0x02, 0xCA);
-       addToMapW(0xef, 0x03, 0x01);
-       addToMapW(0xef, 0x03, 0x8E);
-       addToMapW(0xef, 0x03, 0xCD);
-       addToMapW(0xef, 0x06, 0x4A);
-       addToMapW(0xef, 0x0E, 0x4F);
-       addToMapW(0xef, 0x20, 0x19);
-       addToMapW(0xef, 0x20, 0x32);
-       addToMapW(0xef, 0x20, 0x35);
-       addToMapW(0xef, 0x21, 0x16);
-       addToMapW(0xef, 0x22, 0x29);
-       addToMapW(0xef, 0xFE, 0xF1);
-       addToMapW(0xef, 0xFE, 0xF2);
-       addToMapW(0xef, 0xFE, 0xF3);
-       addToMapW(0xef, 0xFE, 0xF4);
-       addToMapW(0xf0, 0x00, 0xAD);
-       addToMapW(0xf0, 0x03, 0x8F);
-       addToMapW(0xf0, 0x03, 0xCE);
-       addToMapW(0xf0, 0x04, 0x01);
-       addToMapW(0xf0, 0x04, 0x51);
-       addToMapW(0xf0, 0x0E, 0x50);
-       addToMapW(0xf0, 0x22, 0x61);
-       addToMapW(0xf1, 0x00, 0xB1);
-       addToMapW(0xf1, 0x02, 0xDD);
-       addToMapW(0xf1, 0x06, 0x4B);
-       addToMapW(0xf1, 0x0E, 0x51);
-       addToMapW(0xf1, 0x22, 0x13);
-       addToMapW(0xf1, 0xFE, 0x70);
-       addToMapW(0xf1, 0xFE, 0x71);
-       addToMapW(0xf2, 0x02, 0xDB);
-       addToMapW(0xf2, 0x03, 0x23);
-       addToMapW(0xf2, 0x04, 0x04);
-       addToMapW(0xf2, 0x04, 0x2B);
-       addToMapW(0xf2, 0x04, 0x4B);
-       addToMapW(0xf2, 0x04, 0x54);
-       addToMapW(0xf2, 0x06, 0x4C);
-       addToMapW(0xf2, 0x0E, 0x52);
-       addToMapW(0xf2, 0x20, 0x17);
-       addToMapW(0xf2, 0x20, 0x1C);
-       addToMapW(0xf2, 0x22, 0x65);
-       addToMapW(0xf2, 0xF8, 0xBD);
-       addToMapW(0xf2, 0xFE, 0x72);
-       addToMapW(0xf3, 0x00, 0xBE);
-       addToMapW(0xf3, 0x02, 0xC7);
-       addToMapW(0xf3, 0x03, 0x0C);
-       addToMapW(0xf3, 0x06, 0x4D);
-       addToMapW(0xf3, 0x0E, 0x53);
-       addToMapW(0xf3, 0x22, 0x64);
-       addToMapW(0xf3, 0xFE, 0x74);
-       addToMapW(0xf4, 0x00, 0xB6);
-       addToMapW(0xf4, 0x02, 0xD8);
-       addToMapW(0xf4, 0x03, 0x06);
-       addToMapW(0xf4, 0x03, 0xAA);
-       addToMapW(0xf4, 0x03, 0xCA);
-       addToMapW(0xf4, 0x04, 0x07);
-       addToMapW(0xf4, 0x04, 0x17);
-       addToMapW(0xf4, 0x04, 0x37);
-       addToMapW(0xf4, 0x04, 0x57);
-       addToMapW(0xf4, 0x06, 0x4E);
-       addToMapW(0xf4, 0x0E, 0x54);
-       addToMapW(0xf4, 0x23, 0x20);
-       addToMapW(0xf4, 0xFE, 0x76);
-       addToMapW(0xf4, 0xFE, 0x77);
-       addToMapW(0xf5, 0x00, 0xA7);
-       addToMapW(0xf5, 0x03, 0xAB);
-       addToMapW(0xf5, 0x03, 0xCB);
-       addToMapW(0xf5, 0x06, 0x4F);
-       addToMapW(0xf5, 0x0E, 0x55);
-       addToMapW(0xf5, 0x23, 0x21);
-       addToMapW(0xf5, 0xFE, 0x78);
-       addToMapW(0xf5, 0xFE, 0x79);
-       addToMapW(0xf6, 0x00, 0xF7);
-       addToMapW(0xf6, 0x04, 0x0E);
-       addToMapW(0xf6, 0x04, 0x28);
-       addToMapW(0xf6, 0x04, 0x48);
-       addToMapW(0xf6, 0x04, 0x5E);
-       addToMapW(0xf6, 0x06, 0x50);
-       addToMapW(0xf6, 0x0E, 0x56);
-       addToMapW(0xf6, 0xFE, 0x7A);
-       addToMapW(0xf6, 0xFE, 0x7B);
-       addToMapW(0xf7, 0x00, 0xB8);
-       addToMapW(0xf7, 0x00, 0xF7);
-       addToMapW(0xf7, 0x02, 0xDB);
-       addToMapW(0xf7, 0x03, 0x27);
-       addToMapW(0xf7, 0x0E, 0x57);
-       addToMapW(0xf7, 0x20, 0x1E);
-       addToMapW(0xf7, 0x22, 0x48);
-       addToMapW(0xf8, 0x00, 0xB0);
-       addToMapW(0xf8, 0x02, 0xDA);
-       addToMapW(0xf8, 0x03, 0x0A);
-       addToMapW(0xf8, 0x04, 0x2D);
-       addToMapW(0xf8, 0x04, 0x4D);
-       addToMapW(0xf8, 0x0E, 0x58);
-       addToMapW(0xf8, 0x20, 0x70);
-       addToMapW(0xf8, 0x22, 0x18);
-       addToMapW(0xf9, 0x00, 0xA8);
-       addToMapW(0xf9, 0x02, 0xDD);
-       addToMapW(0xf9, 0x03, 0x08);
-       addToMapW(0xf9, 0x0E, 0x59);
-       addToMapW(0xf9, 0x22, 0x19);
-       addToMapW(0xfa, 0x00, 0xB7);
-       addToMapW(0xfa, 0x02, 0xD9);
-       addToMapW(0xfa, 0x03, 0x07);
-       addToMapW(0xfa, 0x04, 0x29);
-       addToMapW(0xfa, 0x04, 0x49);
-       addToMapW(0xfa, 0x0E, 0x5A);
-       addToMapW(0xfa, 0x20, 0x24);
-       addToMapW(0xfa, 0x22, 0xC5);
-       addToMapW(0xfa, 0x30, 0xFB);
-       addToMapW(0xfb, 0x00, 0xB9);
-       addToMapW(0xfb, 0x0E, 0x5B);
-       addToMapW(0xfb, 0x20, 0x81);
-       addToMapW(0xfb, 0x22, 0x1A);
-       addToMapW(0xfb, 0x27, 0x13);
-       addToMapW(0xfc, 0x00, 0xB3);
-       addToMapW(0xfc, 0x01, 0x58);
-       addToMapW(0xfc, 0x01, 0x59);
-       addToMapW(0xfc, 0x04, 0x27);
-       addToMapW(0xfc, 0x04, 0x47);
-       addToMapW(0xfc, 0x20, 0x7F);
-       addToMapW(0xfc, 0x20, 0x83);
-       addToMapW(0xfc, 0x21, 0x16);
-       addToMapW(0xfc, 0xF8, 0xC5);
-       addToMapW(0xfd, 0x00, 0xA4);
-       addToMapW(0xfd, 0x00, 0xA7);
-       addToMapW(0xfd, 0x00, 0xB2);
-       addToMapW(0xfd, 0x20, 0x82);
-       addToMapW(0xfd, 0xF8, 0xC6);
-       addToMapW(0xfd, 0xF8, 0xF1);
-       addToMapW(0xfe, 0x20, 0xAB);
-       addToMapW(0xfe, 0x25, 0xA0);
-       addToMapW(0xfe, 0xF8, 0xC7);
-       addToMapW(0xfe, 0xF8, 0xF2);
-       addToMapW(0xff, 0x00, 0xA0);
-       addToMapW(0xff, 0xF8, 0xC8);
-       addToMapW(0xff, 0xF8, 0xF3);
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "lm2ntlm.h"\r
+\r
+LM2NTLMcorrector::LM2NTLMcorrector()\r
+{\r
+       progressCurrentCombination = 0;\r
+       totalCurrentCombination = 1;\r
+       counterOverall = 0;\r
+       countCombinations = 0;\r
+       countTotalCombinations = 0;\r
+       counter = 0;\r
+       fillMapW();\r
+       aborting = false;\r
+       sBinary = "";\r
+\r
+}\r
+\r
+string LM2NTLMcorrector::getBinary()\r
+{\r
+       return sBinary;\r
+}\r
+\r
+bool LM2NTLMcorrector::LMPasswordCorrectUnicode(string hexPassword, unsigned char* pNTLMHash, string& sNTLMPassword) //, unsigned char* pLMPassword\r
+{\r
+       string sPlain = "";\r
+\r
+       uint32 i;\r
+       for (i = 0; i < hexPassword.size() / 2; i++)\r
+       {\r
+               string sSub = hexPassword.substr(i * 2, 2);\r
+               int nValue;\r
+               sscanf(sSub.c_str(), "%02x", &nValue);\r
+               sPlain += (unsigned char)nValue;\r
+       }\r
+\r
+       memcpy(NTLMHash, pNTLMHash, MD4_DIGEST_LENGTH);\r
+\r
+\r
+       unsigned long int tmpLength = sPlain.size() * 2;\r
+       unsigned char* pLMPassword = new unsigned char[tmpLength];\r
+\r
+       //printf("Searching for unicode password.\n");\r
+       printf("Failed case correction, trying unicode correction for: %s\n", sPlain.c_str());\r
+       //printf("NTLM hash:          %s\n\n", sNTLMHash.c_str());\r
+       \r
+       setvbuf(stdout, NULL, _IONBF,0);\r
+\r
+       startClock = clock();\r
+       previousClock = clock();\r
+\r
+#ifndef _WIN32\r
+       tty_init();\r
+#endif\r
+\r
+       if (startCorrecting(sPlain, sNTLMPassword, pLMPassword))\r
+       {\r
+               sBinary = ByteToStr(pLMPassword, tmpLength).c_str();\r
+               //printf("\nFound unicode password: %s\n", sNTLMPassword.c_str());\r
+               //printf("Password in hex: %s\n", sBinary.c_str());\r
+               writeEndStats();\r
+#ifndef _WIN32\r
+               tty_done();\r
+#endif\r
+               return true;\r
+       }\r
+       else\r
+       {\r
+               //printf("\ncase correction for password %s fail!\n", sPlain.c_str());\r
+               writeEndStats();\r
+#ifndef _WIN32\r
+               tty_done();\r
+#endif\r
+               return false;\r
+       }\r
+}\r
+\r
+bool LM2NTLMcorrector::startCorrecting(string sLMPassword, string& sNTLMPassword, unsigned char* pLMPassword)\r
+{\r
+       if (sLMPassword.size() == 0)\r
+       {\r
+               sNTLMPassword = "";\r
+               return true;\r
+       }\r
+\r
+       string muteMe = sLMPassword;\r
+       int length = muteMe.size();\r
+\r
+       unsigned char* pMuteMe = new unsigned char[length];\r
+       unsigned char* pTempMute = new unsigned char[length * 2];\r
+\r
+       int i;\r
+       for (i = 0; i < length; i++)\r
+       {\r
+               pMuteMe[i] = muteMe[i];\r
+               pTempMute[i * 2    ] = muteMe[i];\r
+               pTempMute[i * 2 + 1] = 0x00;\r
+               unsigned char muteChar = pMuteMe[i];\r
+               int sizeMapForChar = m_mapChar[muteChar].size();\r
+               int j;\r
+               for (j = 0; j < sizeMapForChar; j++)\r
+               {\r
+                       currentCharmap[i][j] = m_mapChar[muteChar][j];\r
+               }\r
+       }\r
+       \r
+       int* jAtPos = new int[length];\r
+       int* sizeAtPos = new int[length];\r
+       bool* fullAtPos = new bool[length];\r
+\r
+       int setSize;\r
+       for (setSize = 0; setSize <= length; setSize++)\r
+       {\r
+               int cntFull = 0;\r
+\r
+               // clear all 'fullatpos' before new setSize\r
+               int i;\r
+               for (i=0; i < length; i++)\r
+               {\r
+                       fullAtPos[i] = false;\r
+               }\r
+\r
+               //printf("Trying full unicode map for %d/%d characters...\t\t\n", setSize, length);\r
+               printf("Trying full unicode map for %d/%d characters...%-20s\n", setSize, length, "");\r
+\r
+               bool notFirst = true;\r
+\r
+               // start at end and set 'full' combination\r
+               countCombinations = 0;\r
+               countTotalCombinations = calculateTotalCombinations(length, setSize);\r
+\r
+               int sPos = length - 1;\r
+               while (sPos >= 0 && notFirst) // finding combinations for current 'setSize'\r
+               {\r
+                       if (aborting)\r
+                               return false;\r
+\r
+                       if (cntFull < setSize)\r
+                       {\r
+                               if (fullAtPos[sPos] == false)\r
+                               {\r
+                                       fullAtPos[sPos] = true;\r
+                                       cntFull++;\r
+                               }\r
+                               sPos--;\r
+                       }\r
+                       else\r
+                       {\r
+                               if (fullAtPos[sPos] == false && setSize > 0)\r
+                               {\r
+                                       fullAtPos[sPos] = true;\r
+                                       cntFull++;\r
+                                       \r
+                                       // reset positions after sPos\r
+                                       int k;\r
+                                       for (k = sPos+1; k < length; k++)\r
+                                       {\r
+                                               if (fullAtPos[k] == true)\r
+                                               {\r
+                                                       fullAtPos[k] = false;\r
+                                                       cntFull--;\r
+                                               }\r
+                                       }\r
+                                       // start at end again\r
+                                       sPos = length - 1;\r
+                               }\r
+                               else\r
+                               {\r
+                                       sPos--;\r
+                               }\r
+                       }\r
+                       // we have a combination\r
+                       if (cntFull == setSize)\r
+                       {\r
+                               countCombinations++;\r
+\r
+                               setupCombinationAtPositions(length, pMuteMe, pTempMute, jAtPos, fullAtPos, sizeAtPos);\r
+\r
+                               if (checkPermutations(length, pTempMute, jAtPos, sizeAtPos, pLMPassword, sNTLMPassword))\r
+                               {\r
+                                       return true;\r
+                               }\r
+                       }\r
+\r
+                       if (setSize == 0)\r
+                               notFirst = false;\r
+               }\r
+       }\r
+       return false;\r
+}\r
+\r
+// set up combination at positions\r
+void LM2NTLMcorrector::setupCombinationAtPositions(int length, unsigned char* pMuteMe, unsigned char* pTempMute, int* jAtPos, bool* fullAtPos, int* sizeAtPos)\r
+{\r
+       progressCurrentCombination = 0;\r
+       totalCurrentCombination = 1;\r
+\r
+       int i;\r
+       for (i=0; i < length; i++)\r
+       {\r
+               pTempMute[i*2] = currentCharmap[i][0];\r
+               pTempMute[i*2+1] = currentCharmap[i][1]; // reset to first char in map\r
+       \r
+               jAtPos[i] = 0; // reset charcounter for this char (that is all chars)\r
+\r
+               // based on combination, set full map or only upper/lowercase\r
+               if (fullAtPos[i] == true)\r
+               {\r
+                       unsigned char muteChar = pMuteMe[i];\r
+                       long unsigned int sizeMapForChar = m_mapChar[muteChar].size()/2; // 2 bytes per char\r
+                       sizeAtPos[i] = sizeMapForChar;\r
+               }\r
+               else\r
+               {\r
+                       sizeAtPos[i] = 2;\r
+               }\r
+\r
+               totalCurrentCombination *= sizeAtPos[i];\r
+       }\r
+       //printf("Trying %I64u passwords for current combination\t\t\r", totalCurrentCombination);\r
+}\r
+\r
+// go check all permutations for this combination\r
+bool LM2NTLMcorrector::checkPermutations(int length, unsigned char* pTempMute, int* jAtPos, int* sizeAtPos, unsigned char* pLMPassword, string& sNTLMPassword)\r
+{\r
+       int pos = length - 1;\r
+\r
+       while (pos >= 0)\r
+       {\r
+               counter++;\r
+\r
+               pos = length - 1;\r
+\r
+               int jAtCurPos = jAtPos[pos];\r
+               int sizeMapForCharPos = sizeAtPos[pos];\r
+               // move to start of string and find character with permutations left\r
+               while (jAtCurPos >= sizeMapForCharPos-1 && pos >= -1)\r
+               {\r
+                       pos--;\r
+                       if (pos >= 0 )\r
+                       {\r
+                               jAtCurPos = jAtPos[pos];\r
+                               sizeMapForCharPos = sizeAtPos[pos];\r
+                       }\r
+               }\r
+               if (pos < 0)\r
+                       continue;\r
+\r
+               // next permutation for character\r
+               jAtCurPos++;\r
+               jAtPos[pos] = jAtCurPos;\r
+               \r
+               pTempMute[pos*2] = currentCharmap[pos][jAtCurPos*2];\r
+               pTempMute[pos*2+1] = currentCharmap[pos][jAtCurPos*2+1];\r
+               \r
+               // reset positions after pos\r
+               int k;\r
+               for (k = pos+1; k < length; k++)\r
+               {\r
+                       jAtPos[k] = 0;\r
+                       pTempMute[k*2] = currentCharmap[k][0]; // reset to first char in map\r
+                       pTempMute[k*2+1] = currentCharmap[k][1];\r
+               }\r
+\r
+               if (checkNTLMPassword(pTempMute, length, sNTLMPassword) == true)\r
+               {\r
+                       int i;\r
+                       for (i = 0; i < length*2; i++)\r
+                               pLMPassword[i] = pTempMute[i];\r
+                       return true;\r
+               }\r
+\r
+               if (counter > 10000) // don't check clocks too often\r
+               {\r
+                       clock_t currentClock = clock();\r
+                       float fTime = 1.0f * (currentClock - previousClock);\r
+                       if (fTime > 1.0f * CLOCKS_PER_SEC)\r
+                       {\r
+                               float progressPercentageCurrentCombination = progressCurrentCombination * 100.0f / totalCurrentCombination;\r
+                               float fTime = 1.0f * (currentClock - startClock) / CLOCKS_PER_SEC;\r
+                               float currentSpeed = (counterOverall + progressCurrentCombination) / fTime / 1000000;\r
+\r
+                               //printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)\t\t\t\t\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed);\r
+                               printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)%-30s\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed, "");\r
+\r
+                               previousClock = clock();\r
+                               #ifdef _WIN32\r
+                               if (_kbhit())\r
+                               {\r
+                                       int ch = _getch();\r
+                                       ch = toupper(ch);\r
+                                       if (ch == 'S')\r
+                                       {\r
+                                               aborting = true;\r
+                                               printf( "\nAborting unicode correction for this hash...\n");\r
+                                       }\r
+                                       else\r
+                                       {\r
+                                               printf( "\nPress 'S' to skip unicode correction for this hash...\n");\r
+                                       }\r
+                               }\r
+                               #else\r
+                               int c = tty_getchar();\r
+                               if (c >= 0) {\r
+                                       tty_flush();\r
+                                       if (c==115) { // = s\r
+                                               aborting = true;\r
+                                               printf( "\nAborting unicode correction for this hash...\n");\r
+                                       }\r
+                                       else {\r
+                                               printf( "\nPress 's' to skip unicode correction for this hash...\n");\r
+                                       }\r
+                               }\r
+                               #endif\r
+                               if (aborting)\r
+                                       return false;\r
+                       }\r
+                       counter = 0;\r
+               }\r
+               \r
+               progressCurrentCombination++;\r
+               counterOverall++;\r
+       }\r
+       return false;\r
+}\r
+\r
+// check password, maybe integrate this function in checkPermutations() for performance reasons.\r
+bool LM2NTLMcorrector::checkNTLMPassword(unsigned char* pLMPassword, int nLMPasswordLen, string& sNTLMPassword)\r
+{\r
+       unsigned char md[MD4_DIGEST_LENGTH];\r
+\r
+       //MD4(pLMPassword, nLMPasswordLen * 2, md);\r
+       /*\r
+       MD4_CTX ctx;\r
+       MD4_Init(&ctx);\r
+       MD4_Update(&ctx, pLMPassword, nLMPasswordLen * 2);\r
+       MD4_Final(md, &ctx);*/ \r
+\r
+       MD4_NEW( pLMPassword, nLMPasswordLen * 2, md );\r
+\r
+       if (memcmp(md, NTLMHash, MD4_DIGEST_LENGTH) == 0)\r
+       {\r
+               sNTLMPassword = "";\r
+               int i;\r
+               for (i = 0; i < nLMPasswordLen; i++) {\r
+                       sNTLMPassword += char(pLMPassword[i * 2]);\r
+               }\r
+               return true;\r
+       }\r
+       else\r
+               return false;\r
+}\r
+\r
+void LM2NTLMcorrector::checkAbort()\r
+{\r
+#ifdef _WIN32\r
+       if (_kbhit())\r
+       {\r
+               int ch = _getch();\r
+               ch = toupper(ch);\r
+               if (ch == 'S')\r
+               {\r
+                       aborting = true;\r
+                       printf( "\nAborting unicode correction for this hash...\n");\r
+               }\r
+               else\r
+               {\r
+                       printf( "\nPress 'S' to skip unicode correction for this hash...\n");\r
+               }\r
+       }\r
+#endif\r
+}\r
+\r
+void LM2NTLMcorrector::writeEndStats()\r
+{\r
+       clock_t endClock = clock();\r
+       if (endClock - startClock > 0)\r
+       {\r
+               float fTime = 1.0f * (endClock - startClock) / CLOCKS_PER_SEC;\r
+               float speedOverall = counterOverall / fTime / 1000000;\r
+               printf("\nTried %s passwords in %.2f s (%.2f Mhashes/s)\n", uint64tostr(counterOverall).c_str(), fTime, speedOverall);\r
+       }\r
+\r
+       printf("\n");\r
+}\r
+\r
+int LM2NTLMcorrector::calculateTotalCombinations(int length, int setSize)\r
+{\r
+       return factorial(length) / (factorial(setSize) * factorial(length-setSize));\r
+}\r
+\r
+int LM2NTLMcorrector::factorial (int num)\r
+{\r
+       int result = 1;\r
+       int i;\r
+       for (i = 1; i <= num; ++i)\r
+               result *= i;\r
+       return result;\r
+}\r
+\r
+// convert some bytes into a string\r
+string LM2NTLMcorrector::ByteToStr(const unsigned char* pData, int nLen)\r
+{\r
+       string sRet = "";\r
+       int i;\r
+       for (i = 0; i < nLen/2; i++)\r
+       {\r
+               char szByte[3];\r
+               sprintf(szByte, "%02x", pData[i*2+1]); // swap 2-byte characters again\r
+               sRet += szByte;\r
+               sprintf(szByte, "%02x", pData[i*2]);\r
+               sRet += szByte;\r
+       }\r
+\r
+       return sRet;\r
+}\r
+\r
+void LM2NTLMcorrector::addToMapW(unsigned char key, unsigned char value1, unsigned char value2)\r
+{\r
+       unsigned long int cnt = m_mapChar[key].size();\r
+       m_mapChar[key][cnt] = value2;\r
+       m_mapChar[key][cnt+1] = value1; //reverse for endiannes\r
+}\r
+\r
+// construct the mappings, would be nicer in a separate (importable) file\r
+void LM2NTLMcorrector::fillMapW()\r
+{\r
+       addToMapW(0x01, 0x00, 0x01);\r
+       addToMapW(0x01, 0x26, 0x3A);\r
+       addToMapW(0x02, 0x00, 0x02);\r
+       addToMapW(0x02, 0x26, 0x3B);\r
+       addToMapW(0x03, 0x00, 0x03);\r
+       addToMapW(0x03, 0x26, 0x65);\r
+       addToMapW(0x04, 0x00, 0x04);\r
+       addToMapW(0x04, 0x26, 0x66);\r
+       addToMapW(0x05, 0x00, 0x05);\r
+       addToMapW(0x05, 0x26, 0x63);\r
+       addToMapW(0x06, 0x00, 0x06);\r
+       addToMapW(0x06, 0x26, 0x60);\r
+       addToMapW(0x07, 0x00, 0x07);\r
+       addToMapW(0x07, 0x00, 0xB7);\r
+       addToMapW(0x07, 0x20, 0x22);\r
+       addToMapW(0x07, 0x20, 0x24);\r
+       addToMapW(0x07, 0x20, 0x26);\r
+       addToMapW(0x07, 0x22, 0x19);\r
+       addToMapW(0x07, 0x22, 0xC5);\r
+       addToMapW(0x07, 0x30, 0xFB);\r
+       addToMapW(0x08, 0x00, 0x08);\r
+       addToMapW(0x08, 0x25, 0xD8);\r
+       addToMapW(0x09, 0x00, 0x09);\r
+       addToMapW(0x09, 0x20, 0xDD);\r
+       addToMapW(0x09, 0x25, 0xCB);\r
+       addToMapW(0x09, 0x30, 0x07);\r
+       addToMapW(0x0a, 0x00, 0x0A);\r
+       addToMapW(0x0a, 0x25, 0xD9);\r
+       addToMapW(0x0b, 0x00, 0x0B);\r
+       addToMapW(0x0b, 0x26, 0x42);\r
+       addToMapW(0x0c, 0x00, 0x0C);\r
+       addToMapW(0x0c, 0x26, 0x40);\r
+       addToMapW(0x0d, 0x00, 0x0D);\r
+       addToMapW(0x0d, 0x26, 0x6A);\r
+       addToMapW(0x0e, 0x00, 0x0E);\r
+       addToMapW(0x0e, 0x26, 0x6B);\r
+       addToMapW(0x0f, 0x00, 0x0F);\r
+       addToMapW(0x0f, 0x00, 0xA4);\r
+       addToMapW(0x0f, 0x26, 0x3C);\r
+       addToMapW(0x10, 0x00, 0x10);\r
+       addToMapW(0x10, 0x25, 0xBA);\r
+       addToMapW(0x11, 0x00, 0x11);\r
+       addToMapW(0x11, 0x25, 0xC4);\r
+       addToMapW(0x12, 0x00, 0x12);\r
+       addToMapW(0x12, 0x21, 0x95);\r
+       addToMapW(0x13, 0x00, 0x13);\r
+       addToMapW(0x13, 0x20, 0x3C);\r
+       addToMapW(0x14, 0x00, 0x14);\r
+       addToMapW(0x14, 0x00, 0xB6);\r
+       addToMapW(0x15, 0x00, 0x15);\r
+       addToMapW(0x15, 0x00, 0xA7);\r
+       addToMapW(0x16, 0x00, 0x16);\r
+       addToMapW(0x16, 0x02, 0xC9);\r
+       addToMapW(0x16, 0x25, 0xAC);\r
+       addToMapW(0x17, 0x00, 0x17);\r
+       addToMapW(0x17, 0x21, 0xA8);\r
+       addToMapW(0x18, 0x00, 0x18);\r
+       addToMapW(0x18, 0x21, 0x91);\r
+       addToMapW(0x19, 0x00, 0x19);\r
+       addToMapW(0x19, 0x21, 0x93);\r
+       addToMapW(0x1a, 0x00, 0x1A);\r
+       addToMapW(0x1a, 0x21, 0x92);\r
+       addToMapW(0x1b, 0x00, 0x1B);\r
+       addToMapW(0x1b, 0x21, 0x90);\r
+       addToMapW(0x1c, 0x00, 0x1C);\r
+       addToMapW(0x1c, 0x22, 0x1F);\r
+       addToMapW(0x1d, 0x00, 0x1D);\r
+       addToMapW(0x1d, 0x21, 0x94);\r
+       addToMapW(0x1e, 0x00, 0x1E);\r
+       addToMapW(0x1e, 0x25, 0xB2);\r
+       addToMapW(0x1f, 0x00, 0x1F);\r
+       addToMapW(0x1f, 0x25, 0xBC);\r
+       addToMapW(0x20, 0x00, 0x20);\r
+       addToMapW(0x20, 0x20, 0x00);\r
+       addToMapW(0x20, 0x20, 0x01);\r
+       addToMapW(0x20, 0x20, 0x02);\r
+       addToMapW(0x20, 0x20, 0x03);\r
+       addToMapW(0x20, 0x20, 0x04);\r
+       addToMapW(0x20, 0x20, 0x05);\r
+       addToMapW(0x20, 0x20, 0x06);\r
+       addToMapW(0x20, 0x30, 0x00);\r
+       addToMapW(0x21, 0x00, 0x21);\r
+       addToMapW(0x21, 0x00, 0xA1);\r
+       addToMapW(0x21, 0x01, 0xC3);\r
+       addToMapW(0x21, 0xFF, 0x01);\r
+       addToMapW(0x22, 0x00, 0x22);\r
+       addToMapW(0x22, 0x00, 0xA8);\r
+       addToMapW(0x22, 0x02, 0xBA);\r
+       addToMapW(0x22, 0x03, 0x08);\r
+       addToMapW(0x22, 0x03, 0x0E);\r
+       addToMapW(0x22, 0x20, 0x1C);\r
+       addToMapW(0x22, 0x20, 0x1D);\r
+       addToMapW(0x22, 0x20, 0x1E);\r
+       addToMapW(0x22, 0x20, 0x33);\r
+       addToMapW(0x22, 0x20, 0x35);\r
+       addToMapW(0x22, 0x27, 0x5D);\r
+       addToMapW(0x22, 0x27, 0x5E);\r
+       addToMapW(0x22, 0x30, 0x1D);\r
+       addToMapW(0x22, 0x30, 0x1E);\r
+       addToMapW(0x22, 0x30, 0x1F);\r
+       addToMapW(0x22, 0xFF, 0x02);\r
+       addToMapW(0x23, 0x00, 0x23);\r
+       addToMapW(0x23, 0xFF, 0x03);\r
+       addToMapW(0x24, 0x00, 0x24);\r
+       addToMapW(0x24, 0xFF, 0x04);\r
+       addToMapW(0x25, 0x00, 0x25);\r
+       addToMapW(0x25, 0x06, 0x6A);\r
+       addToMapW(0x25, 0x20, 0x30);\r
+       addToMapW(0x25, 0xFF, 0x05);\r
+       addToMapW(0x26, 0x00, 0x26);\r
+       addToMapW(0x26, 0xFF, 0x06);\r
+       addToMapW(0x27, 0x00, 0x27);\r
+       addToMapW(0x27, 0x00, 0xB4);\r
+       addToMapW(0x27, 0x02, 0xB9);\r
+       addToMapW(0x27, 0x02, 0xBB);\r
+       addToMapW(0x27, 0x02, 0xBC);\r
+       addToMapW(0x27, 0x02, 0xC8);\r
+       addToMapW(0x27, 0x02, 0xCA);\r
+       addToMapW(0x27, 0x02, 0xCB);\r
+       addToMapW(0x27, 0x03, 0x00);\r
+       addToMapW(0x27, 0x03, 0x01);\r
+       addToMapW(0x27, 0x20, 0x18);\r
+       addToMapW(0x27, 0x20, 0x19);\r
+       addToMapW(0x27, 0x20, 0x1A);\r
+       addToMapW(0x27, 0x20, 0x32);\r
+       addToMapW(0x27, 0x27, 0x5B);\r
+       addToMapW(0x27, 0x27, 0x5C);\r
+       addToMapW(0x27, 0xFF, 0x07);\r
+       addToMapW(0x28, 0x00, 0x28);\r
+       addToMapW(0x28, 0x23, 0x20);\r
+       addToMapW(0x28, 0xFF, 0x08);\r
+       addToMapW(0x29, 0x00, 0x29);\r
+       addToMapW(0x29, 0x23, 0x21);\r
+       addToMapW(0x29, 0xFF, 0x09);\r
+       addToMapW(0x2a, 0x00, 0x2A);\r
+       addToMapW(0x2a, 0x22, 0x17);\r
+       addToMapW(0x2a, 0xFF, 0x0A);\r
+       addToMapW(0x2b, 0x00, 0x2B);\r
+       addToMapW(0x2b, 0x00, 0xB1);\r
+       addToMapW(0x2b, 0x20, 0x20);\r
+       addToMapW(0x2b, 0x20, 0x21);\r
+       addToMapW(0x2b, 0xFF, 0x0B);\r
+       addToMapW(0x2c, 0x00, 0x2C);\r
+       addToMapW(0x2c, 0x00, 0xB8);\r
+       addToMapW(0x2c, 0x03, 0x27);\r
+       addToMapW(0x2c, 0x20, 0x1A);\r
+       addToMapW(0x2c, 0x20, 0x1E);\r
+       addToMapW(0x2c, 0xFF, 0x0C);\r
+       addToMapW(0x2d, 0x00, 0x2D);\r
+       addToMapW(0x2d, 0x00, 0xAC);\r
+       addToMapW(0x2d, 0x00, 0xAD);\r
+       addToMapW(0x2d, 0x20, 0x10);\r
+       addToMapW(0x2d, 0x20, 0x11);\r
+       addToMapW(0x2d, 0x20, 0x13);\r
+       addToMapW(0x2d, 0x20, 0x14);\r
+       addToMapW(0x2d, 0x22, 0x12);\r
+       addToMapW(0x2d, 0x22, 0x13);\r
+       addToMapW(0x2d, 0xFF, 0x0D);\r
+       addToMapW(0x2e, 0x00, 0x2E);\r
+       addToMapW(0x2e, 0x20, 0x26);\r
+       addToMapW(0x2e, 0xFF, 0x0E);\r
+       addToMapW(0x2f, 0x00, 0x2F);\r
+       addToMapW(0x2f, 0x20, 0x44);\r
+       addToMapW(0x2f, 0x22, 0x15);\r
+       addToMapW(0x2f, 0x22, 0x16);\r
+       addToMapW(0x2f, 0xFF, 0x0F);\r
+       addToMapW(0x30, 0x00, 0x30);\r
+       addToMapW(0x30, 0x20, 0x70);\r
+       addToMapW(0x30, 0x20, 0x80);\r
+       addToMapW(0x30, 0xFF, 0x10);\r
+       addToMapW(0x31, 0x00, 0x31);\r
+       addToMapW(0x31, 0x00, 0xB9);\r
+       addToMapW(0x31, 0x00, 0xBC);\r
+       addToMapW(0x31, 0x00, 0xBD);\r
+       addToMapW(0x31, 0x20, 0x81);\r
+       addToMapW(0x31, 0xFF, 0x11);\r
+       addToMapW(0x32, 0x00, 0x32);\r
+       addToMapW(0x32, 0x00, 0xB2);\r
+       addToMapW(0x32, 0x20, 0x82);\r
+       addToMapW(0x32, 0xFF, 0x12);\r
+       addToMapW(0x33, 0x00, 0x33);\r
+       addToMapW(0x33, 0x00, 0xB3);\r
+       addToMapW(0x33, 0x00, 0xBE);\r
+       addToMapW(0x33, 0x20, 0x83);\r
+       addToMapW(0x33, 0xFF, 0x13);\r
+       addToMapW(0x34, 0x00, 0x34);\r
+       addToMapW(0x34, 0x20, 0x74);\r
+       addToMapW(0x34, 0x20, 0x84);\r
+       addToMapW(0x34, 0xFF, 0x14);\r
+       addToMapW(0x35, 0x00, 0x35);\r
+       addToMapW(0x35, 0x20, 0x75);\r
+       addToMapW(0x35, 0x20, 0x85);\r
+       addToMapW(0x35, 0xFF, 0x15);\r
+       addToMapW(0x36, 0x00, 0x36);\r
+       addToMapW(0x36, 0x20, 0x76);\r
+       addToMapW(0x36, 0x20, 0x86);\r
+       addToMapW(0x36, 0xFF, 0x16);\r
+       addToMapW(0x37, 0x00, 0x37);\r
+       addToMapW(0x37, 0x20, 0x77);\r
+       addToMapW(0x37, 0x20, 0x87);\r
+       addToMapW(0x37, 0xFF, 0x17);\r
+       addToMapW(0x38, 0x00, 0x38);\r
+       addToMapW(0x38, 0x20, 0x78);\r
+       addToMapW(0x38, 0x20, 0x88);\r
+       addToMapW(0x38, 0x22, 0x1E);\r
+       addToMapW(0x38, 0xFF, 0x18);\r
+       addToMapW(0x39, 0x00, 0x39);\r
+       addToMapW(0x39, 0x20, 0x78);\r
+       addToMapW(0x39, 0x20, 0x89);\r
+       addToMapW(0x39, 0xFF, 0x19);\r
+       addToMapW(0x3a, 0x00, 0x3A);\r
+       addToMapW(0x3a, 0x05, 0x89);\r
+       addToMapW(0x3a, 0x20, 0x26);\r
+       addToMapW(0x3a, 0x22, 0x36);\r
+       addToMapW(0x3a, 0xFF, 0x1A);\r
+       addToMapW(0x3b, 0x00, 0x3B);\r
+       addToMapW(0x3b, 0x03, 0x7E);\r
+       addToMapW(0x3b, 0xFF, 0x1B);\r
+       addToMapW(0x3c, 0x00, 0x3C);\r
+       addToMapW(0x3c, 0x00, 0xAB);\r
+       addToMapW(0x3c, 0x20, 0x39);\r
+       addToMapW(0x3c, 0x23, 0x29);\r
+       addToMapW(0x3c, 0x30, 0x08);\r
+       addToMapW(0x3c, 0xFF, 0x1C);\r
+       addToMapW(0x3d, 0x00, 0x3D);\r
+       addToMapW(0x3d, 0x22, 0x61);\r
+       addToMapW(0x3d, 0x22, 0x64);\r
+       addToMapW(0x3d, 0x22, 0x65);\r
+       addToMapW(0x3d, 0xFF, 0x1D);\r
+       addToMapW(0x3e, 0x00, 0x3E);\r
+       addToMapW(0x3e, 0x00, 0xBB);\r
+       addToMapW(0x3e, 0x20, 0x3A);\r
+       addToMapW(0x3e, 0x23, 0x2A);\r
+       addToMapW(0x3e, 0x30, 0x09);\r
+       addToMapW(0x3e, 0xFF, 0x1E);\r
+       addToMapW(0x3f, 0x00, 0x3F);\r
+       addToMapW(0x40, 0x00, 0x40);\r
+       addToMapW(0x40, 0xFF, 0x20);\r
+       addToMapW(0x41, 0x00, 0x41);\r
+       addToMapW(0x41, 0x00, 0x61);\r
+       addToMapW(0x41, 0x00, 0xAA);\r
+       addToMapW(0x41, 0x00, 0xC0);\r
+       addToMapW(0x41, 0x00, 0xC1);\r
+       addToMapW(0x41, 0x00, 0xC2);\r
+       addToMapW(0x41, 0x00, 0xC3);\r
+       addToMapW(0x41, 0x00, 0xC4);\r
+       addToMapW(0x41, 0x00, 0xC5);\r
+       addToMapW(0x41, 0x00, 0xC6);\r
+       addToMapW(0x41, 0x00, 0xE0);\r
+       addToMapW(0x41, 0x00, 0xE1);\r
+       addToMapW(0x41, 0x00, 0xE2);\r
+       addToMapW(0x41, 0x00, 0xE3);\r
+       addToMapW(0x41, 0x00, 0xE4);\r
+       addToMapW(0x41, 0x00, 0xE5);\r
+       addToMapW(0x41, 0x00, 0xE6);\r
+       addToMapW(0x41, 0x01, 0x00);\r
+       addToMapW(0x41, 0x01, 0x01);\r
+       addToMapW(0x41, 0x01, 0x02);\r
+       addToMapW(0x41, 0x01, 0x03);\r
+       addToMapW(0x41, 0x01, 0x04);\r
+       addToMapW(0x41, 0x01, 0x05);\r
+       addToMapW(0x41, 0x01, 0xCD);\r
+       addToMapW(0x41, 0x01, 0xCE);\r
+       addToMapW(0x41, 0x01, 0xDE);\r
+       addToMapW(0x41, 0x01, 0xDF);\r
+       addToMapW(0x41, 0x03, 0xB1);\r
+       addToMapW(0x41, 0x21, 0x2B);\r
+       addToMapW(0x41, 0xFF, 0x21);\r
+       addToMapW(0x41, 0xFF, 0x41);\r
+       addToMapW(0x42, 0x00, 0x42);\r
+       addToMapW(0x42, 0x00, 0x62);\r
+       addToMapW(0x42, 0x01, 0x80);\r
+       addToMapW(0x42, 0x21, 0x2C);\r
+       addToMapW(0x42, 0xFF, 0x22);\r
+       addToMapW(0x42, 0xFF, 0x42);\r
+       addToMapW(0x43, 0x00, 0x43);\r
+       addToMapW(0x43, 0x00, 0x63);\r
+       addToMapW(0x43, 0x00, 0xA2);\r
+       addToMapW(0x43, 0x00, 0xA9);\r
+       addToMapW(0x43, 0x00, 0xC7);\r
+       addToMapW(0x43, 0x00, 0xE7);\r
+       addToMapW(0x43, 0x00, 0xE8);\r
+       addToMapW(0x43, 0x01, 0x06);\r
+       addToMapW(0x43, 0x01, 0x07);\r
+       addToMapW(0x43, 0x01, 0x08);\r
+       addToMapW(0x43, 0x01, 0x09);\r
+       addToMapW(0x43, 0x01, 0x0A);\r
+       addToMapW(0x43, 0x01, 0x0B);\r
+       addToMapW(0x43, 0x01, 0x0C);\r
+       addToMapW(0x43, 0x01, 0x0D);\r
+       addToMapW(0x43, 0x21, 0x02);\r
+       addToMapW(0x43, 0x21, 0x2D);\r
+       addToMapW(0x43, 0xFF, 0x23);\r
+       addToMapW(0x43, 0xFF, 0x43);\r
+       addToMapW(0x44, 0x00, 0x44);\r
+       addToMapW(0x44, 0x00, 0x64);\r
+       addToMapW(0x44, 0x00, 0xD0);\r
+       addToMapW(0x44, 0x00, 0xF0);\r
+       addToMapW(0x44, 0x01, 0x0E);\r
+       addToMapW(0x44, 0x01, 0x0F);\r
+       addToMapW(0x44, 0x01, 0x10);\r
+       addToMapW(0x44, 0x01, 0x11);\r
+       addToMapW(0x44, 0x01, 0x89);\r
+       addToMapW(0x44, 0x03, 0xB4);\r
+       addToMapW(0x44, 0x26, 0x6A);\r
+       addToMapW(0x44, 0x26, 0x6B);\r
+       addToMapW(0x44, 0xFF, 0x24);\r
+       addToMapW(0x44, 0xFF, 0x44);\r
+       addToMapW(0x45, 0x00, 0x45);\r
+       addToMapW(0x45, 0x00, 0x65);\r
+       addToMapW(0x45, 0x00, 0xC8);\r
+       addToMapW(0x45, 0x00, 0xC9);\r
+       addToMapW(0x45, 0x00, 0xCA);\r
+       addToMapW(0x45, 0x00, 0xCB);\r
+       addToMapW(0x45, 0x00, 0xE8);\r
+       addToMapW(0x45, 0x00, 0xE9);\r
+       addToMapW(0x45, 0x00, 0xEA);\r
+       addToMapW(0x45, 0x00, 0xEB);\r
+       addToMapW(0x45, 0x01, 0x12);\r
+       addToMapW(0x45, 0x01, 0x13);\r
+       addToMapW(0x45, 0x01, 0x14);\r
+       addToMapW(0x45, 0x01, 0x15);\r
+       addToMapW(0x45, 0x01, 0x16);\r
+       addToMapW(0x45, 0x01, 0x17);\r
+       addToMapW(0x45, 0x01, 0x18);\r
+       addToMapW(0x45, 0x01, 0x19);\r
+       addToMapW(0x45, 0x01, 0x1A);\r
+       addToMapW(0x45, 0x01, 0x1B);\r
+       addToMapW(0x45, 0x03, 0xB5);\r
+       addToMapW(0x45, 0x21, 0x07);\r
+       addToMapW(0x45, 0x21, 0x2E);\r
+       addToMapW(0x45, 0x21, 0x2F);\r
+       addToMapW(0x45, 0x21, 0x30);\r
+       addToMapW(0x45, 0xFF, 0x25);\r
+       addToMapW(0x45, 0xFF, 0x45);\r
+       addToMapW(0x46, 0x00, 0x46);\r
+       addToMapW(0x46, 0x00, 0x66);\r
+       addToMapW(0x46, 0x01, 0x91);\r
+       addToMapW(0x46, 0x01, 0x92);\r
+       addToMapW(0x46, 0x03, 0xA6);\r
+       addToMapW(0x46, 0x03, 0xC6);\r
+       addToMapW(0x46, 0x21, 0x31);\r
+       addToMapW(0x46, 0xFF, 0x26);\r
+       addToMapW(0x46, 0xFF, 0x46);\r
+       addToMapW(0x47, 0x00, 0x47);\r
+       addToMapW(0x47, 0x00, 0x67);\r
+       addToMapW(0x47, 0x01, 0x1C);\r
+       addToMapW(0x47, 0x01, 0x1D);\r
+       addToMapW(0x47, 0x01, 0x1E);\r
+       addToMapW(0x47, 0x01, 0x1F);\r
+       addToMapW(0x47, 0x01, 0x20);\r
+       addToMapW(0x47, 0x01, 0x21);\r
+       addToMapW(0x47, 0x01, 0x22);\r
+       addToMapW(0x47, 0x01, 0x23);\r
+       addToMapW(0x47, 0x01, 0xE4);\r
+       addToMapW(0x47, 0x01, 0xE5);\r
+       addToMapW(0x47, 0x01, 0xE6);\r
+       addToMapW(0x47, 0x01, 0xE7);\r
+       addToMapW(0x47, 0x02, 0x61);\r
+       addToMapW(0x47, 0x03, 0x93);\r
+       addToMapW(0x47, 0x21, 0x0A);\r
+       addToMapW(0x47, 0xFF, 0x27);\r
+       addToMapW(0x47, 0xFF, 0x47);\r
+       addToMapW(0x48, 0x00, 0x48);\r
+       addToMapW(0x48, 0x00, 0x68);\r
+       addToMapW(0x48, 0x01, 0x24);\r
+       addToMapW(0x48, 0x01, 0x25);\r
+       addToMapW(0x48, 0x01, 0x26);\r
+       addToMapW(0x48, 0x01, 0x27);\r
+       addToMapW(0x48, 0x04, 0xBB);\r
+       addToMapW(0x48, 0x21, 0x0B);\r
+       addToMapW(0x48, 0x21, 0x0C);\r
+       addToMapW(0x48, 0x21, 0x0D);\r
+       addToMapW(0x48, 0x21, 0x0E);\r
+       addToMapW(0x48, 0xFF, 0x28);\r
+       addToMapW(0x48, 0xFF, 0x48);\r
+       addToMapW(0x49, 0x00, 0x49);\r
+       addToMapW(0x49, 0x00, 0x69);\r
+       addToMapW(0x49, 0x00, 0xCC);\r
+       addToMapW(0x49, 0x00, 0xCD);\r
+       addToMapW(0x49, 0x00, 0xCE);\r
+       addToMapW(0x49, 0x00, 0xCF);\r
+       addToMapW(0x49, 0x00, 0xEC);\r
+       addToMapW(0x49, 0x00, 0xED);\r
+       addToMapW(0x49, 0x00, 0xEE);\r
+       addToMapW(0x49, 0x00, 0xEF);\r
+       addToMapW(0x49, 0x01, 0x28);\r
+       addToMapW(0x49, 0x01, 0x29);\r
+       addToMapW(0x49, 0x01, 0x2A);\r
+       addToMapW(0x49, 0x01, 0x2B);\r
+       addToMapW(0x49, 0x01, 0x2C);\r
+       addToMapW(0x49, 0x01, 0x2D);\r
+       addToMapW(0x49, 0x01, 0x2E);\r
+       addToMapW(0x49, 0x01, 0x2F);\r
+       addToMapW(0x49, 0x01, 0x30);\r
+       addToMapW(0x49, 0x01, 0x31);\r
+       addToMapW(0x49, 0x01, 0x97);\r
+       addToMapW(0x49, 0x01, 0xCF);\r
+       addToMapW(0x49, 0x01, 0xD0);\r
+       addToMapW(0x49, 0x21, 0x10);\r
+       addToMapW(0x49, 0x21, 0x11);\r
+       addToMapW(0x49, 0xFF, 0x29);\r
+       addToMapW(0x49, 0xFF, 0x49);\r
+       addToMapW(0x4a, 0x00, 0x4A);\r
+       addToMapW(0x4a, 0x00, 0x6A);\r
+       addToMapW(0x4a, 0x01, 0x34);\r
+       addToMapW(0x4a, 0x01, 0x35);\r
+       addToMapW(0x4a, 0x01, 0xF0);\r
+       addToMapW(0x4a, 0xFF, 0x2A);\r
+       addToMapW(0x4a, 0xFF, 0x4A);\r
+       addToMapW(0x4b, 0x00, 0x4B);\r
+       addToMapW(0x4b, 0x00, 0x6B);\r
+       addToMapW(0x4b, 0x01, 0x36);\r
+       addToMapW(0x4b, 0x01, 0x37);\r
+       addToMapW(0x4b, 0x01, 0xE8);\r
+       addToMapW(0x4b, 0x01, 0xE9);\r
+       addToMapW(0x4b, 0x21, 0x2A);\r
+       addToMapW(0x4b, 0xFF, 0x2B);\r
+       addToMapW(0x4b, 0xFF, 0x4B);\r
+       addToMapW(0x4c, 0x00, 0x4C);\r
+       addToMapW(0x4c, 0x00, 0x6C);\r
+       addToMapW(0x4c, 0x00, 0xA3);\r
+       addToMapW(0x4c, 0x01, 0x39);\r
+       addToMapW(0x4c, 0x01, 0x3A);\r
+       addToMapW(0x4c, 0x01, 0x3B);\r
+       addToMapW(0x4c, 0x01, 0x3C);\r
+       addToMapW(0x4c, 0x01, 0x3D);\r
+       addToMapW(0x4c, 0x01, 0x3E);\r
+       addToMapW(0x4c, 0x01, 0x41);\r
+       addToMapW(0x4c, 0x01, 0x42);\r
+       addToMapW(0x4c, 0x01, 0x9A);\r
+       addToMapW(0x4c, 0x20, 0xA4);\r
+       addToMapW(0x4c, 0x21, 0x12);\r
+       addToMapW(0x4c, 0x21, 0x13);\r
+       addToMapW(0x4c, 0xFF, 0x2C);\r
+       addToMapW(0x4c, 0xFF, 0x4C);\r
+       addToMapW(0x4d, 0x00, 0x4D);\r
+       addToMapW(0x4d, 0x00, 0x6D);\r
+       addToMapW(0x4d, 0x21, 0x33);\r
+       addToMapW(0x4d, 0xFF, 0x2D);\r
+       addToMapW(0x4d, 0xFF, 0x4D);\r
+       addToMapW(0x4e, 0x00, 0x4E);\r
+       addToMapW(0x4e, 0x00, 0x6E);\r
+       addToMapW(0x4e, 0x00, 0xD1);\r
+       addToMapW(0x4e, 0x00, 0xF1);\r
+       addToMapW(0x4e, 0x01, 0x43);\r
+       addToMapW(0x4e, 0x01, 0x44);\r
+       addToMapW(0x4e, 0x01, 0x45);\r
+       addToMapW(0x4e, 0x01, 0x46);\r
+       addToMapW(0x4e, 0x01, 0x47);\r
+       addToMapW(0x4e, 0x01, 0x48);\r
+       addToMapW(0x4e, 0x20, 0x7F);\r
+       addToMapW(0x4e, 0x21, 0x15);\r
+       addToMapW(0x4e, 0x22, 0x29);\r
+       addToMapW(0x4e, 0xFF, 0x2E);\r
+       addToMapW(0x4e, 0xFF, 0x4E);\r
+       addToMapW(0x4f, 0x00, 0x4F);\r
+       addToMapW(0x4f, 0x00, 0x6F);\r
+       addToMapW(0x4f, 0x00, 0xB0);\r
+       addToMapW(0x4f, 0x00, 0xBA);\r
+       addToMapW(0x4f, 0x00, 0xD2);\r
+       addToMapW(0x4f, 0x00, 0xD3);\r
+       addToMapW(0x4f, 0x00, 0xD4);\r
+       addToMapW(0x4f, 0x00, 0xD5);\r
+       addToMapW(0x4f, 0x00, 0xD6);\r
+       addToMapW(0x4f, 0x00, 0xD8);\r
+       addToMapW(0x4f, 0x00, 0xF2);\r
+       addToMapW(0x4f, 0x00, 0xF3);\r
+       addToMapW(0x4f, 0x00, 0xF4);\r
+       addToMapW(0x4f, 0x00, 0xF5);\r
+       addToMapW(0x4f, 0x00, 0xF6);\r
+       addToMapW(0x4f, 0x00, 0xF8);\r
+       addToMapW(0x4f, 0x01, 0x4C);\r
+       addToMapW(0x4f, 0x01, 0x4D);\r
+       addToMapW(0x4f, 0x01, 0x4E);\r
+       addToMapW(0x4f, 0x01, 0x4F);\r
+       addToMapW(0x4f, 0x01, 0x50);\r
+       addToMapW(0x4f, 0x01, 0x51);\r
+       addToMapW(0x4f, 0x01, 0x52);\r
+       addToMapW(0x4f, 0x01, 0x53);\r
+       addToMapW(0x4f, 0x01, 0x9F);\r
+       addToMapW(0x4f, 0x01, 0xA0);\r
+       addToMapW(0x4f, 0x01, 0xA1);\r
+       addToMapW(0x4f, 0x01, 0xD1);\r
+       addToMapW(0x4f, 0x01, 0xD2);\r
+       addToMapW(0x4f, 0x01, 0xEA);\r
+       addToMapW(0x4f, 0x01, 0xEB);\r
+       addToMapW(0x4f, 0x01, 0xEC);\r
+       addToMapW(0x4f, 0x01, 0xED);\r
+       addToMapW(0x4f, 0x03, 0xA9);\r
+       addToMapW(0x4f, 0x20, 0xDD);\r
+       addToMapW(0x4f, 0x21, 0x26);\r
+       addToMapW(0x4f, 0x21, 0x34);\r
+       addToMapW(0x4f, 0x22, 0x05);\r
+       addToMapW(0x4f, 0x30, 0x07);\r
+       addToMapW(0x4f, 0xFF, 0x2F);\r
+       addToMapW(0x4f, 0xFF, 0x4F);\r
+       addToMapW(0x50, 0x00, 0x50);\r
+       addToMapW(0x50, 0x00, 0x70);\r
+       addToMapW(0x50, 0x03, 0xC0);\r
+       addToMapW(0x50, 0x20, 0xA7);\r
+       addToMapW(0x50, 0x21, 0x18);\r
+       addToMapW(0x50, 0x21, 0x19);\r
+       addToMapW(0x50, 0xFF, 0x30);\r
+       addToMapW(0x50, 0xFF, 0x50);\r
+       addToMapW(0x51, 0x00, 0x51);\r
+       addToMapW(0x51, 0x00, 0x71);\r
+       addToMapW(0x51, 0x21, 0x1A);\r
+       addToMapW(0x51, 0xFF, 0x31);\r
+       addToMapW(0x51, 0xFF, 0x51);\r
+       addToMapW(0x52, 0x00, 0x52);\r
+       addToMapW(0x52, 0x00, 0x72);\r
+       addToMapW(0x52, 0x00, 0xAE);\r
+       addToMapW(0x52, 0x01, 0x54);\r
+       addToMapW(0x52, 0x01, 0x55);\r
+       addToMapW(0x52, 0x01, 0x56);\r
+       addToMapW(0x52, 0x01, 0x57);\r
+       addToMapW(0x52, 0x01, 0x58);\r
+       addToMapW(0x52, 0x01, 0x59);\r
+       addToMapW(0x52, 0x21, 0x1B);\r
+       addToMapW(0x52, 0x21, 0x1C);\r
+       addToMapW(0x52, 0x21, 0x1D);\r
+       addToMapW(0x52, 0xFF, 0x32);\r
+       addToMapW(0x52, 0xFF, 0x52);\r
+       addToMapW(0x53, 0x00, 0x53);\r
+       addToMapW(0x53, 0x00, 0x73);\r
+       addToMapW(0x53, 0x00, 0xDF);\r
+       addToMapW(0x53, 0x01, 0x5A);\r
+       addToMapW(0x53, 0x01, 0x5B);\r
+       addToMapW(0x53, 0x01, 0x5C);\r
+       addToMapW(0x53, 0x01, 0x5D);\r
+       addToMapW(0x53, 0x01, 0x5E);\r
+       addToMapW(0x53, 0x01, 0x5F);\r
+       addToMapW(0x53, 0x01, 0x60);\r
+       addToMapW(0x53, 0x01, 0x61);\r
+       addToMapW(0x53, 0x01, 0xA9);\r
+       addToMapW(0x53, 0x03, 0xA3);\r
+       addToMapW(0x53, 0x03, 0xC3);\r
+       addToMapW(0x53, 0x22, 0x11);\r
+       addToMapW(0x53, 0xFF, 0x33);\r
+       addToMapW(0x53, 0xFF, 0x53);\r
+       addToMapW(0x54, 0x00, 0x54);\r
+       addToMapW(0x54, 0x00, 0x74);\r
+       addToMapW(0x54, 0x00, 0xDE);\r
+       addToMapW(0x54, 0x00, 0xFE);\r
+       addToMapW(0x54, 0x01, 0x62);\r
+       addToMapW(0x54, 0x01, 0x63);\r
+       addToMapW(0x54, 0x01, 0x64);\r
+       addToMapW(0x54, 0x01, 0x65);\r
+       addToMapW(0x54, 0x01, 0x66);\r
+       addToMapW(0x54, 0x01, 0x67);\r
+       addToMapW(0x54, 0x01, 0xAB);\r
+       addToMapW(0x54, 0x01, 0xAE);\r
+       addToMapW(0x54, 0x03, 0xC4);\r
+       addToMapW(0x54, 0x21, 0x22);\r
+       addToMapW(0x54, 0xFF, 0x34);\r
+       addToMapW(0x54, 0xFF, 0x54);\r
+       addToMapW(0x55, 0x00, 0x55);\r
+       addToMapW(0x55, 0x00, 0x75);\r
+       addToMapW(0x55, 0x00, 0xB5);\r
+       addToMapW(0x55, 0x00, 0xD9);\r
+       addToMapW(0x55, 0x00, 0xDA);\r
+       addToMapW(0x55, 0x00, 0xDB);\r
+       addToMapW(0x55, 0x00, 0xDC);\r
+       addToMapW(0x55, 0x00, 0xF9);\r
+       addToMapW(0x55, 0x00, 0xFA);\r
+       addToMapW(0x55, 0x00, 0xFB);\r
+       addToMapW(0x55, 0x00, 0xFC);\r
+       addToMapW(0x55, 0x01, 0x68);\r
+       addToMapW(0x55, 0x01, 0x69);\r
+       addToMapW(0x55, 0x01, 0x6A);\r
+       addToMapW(0x55, 0x01, 0x6B);\r
+       addToMapW(0x55, 0x01, 0x6C);\r
+       addToMapW(0x55, 0x01, 0x6D);\r
+       addToMapW(0x55, 0x01, 0x6E);\r
+       addToMapW(0x55, 0x01, 0x6F);\r
+       addToMapW(0x55, 0x01, 0x70);\r
+       addToMapW(0x55, 0x01, 0x71);\r
+       addToMapW(0x55, 0x01, 0x72);\r
+       addToMapW(0x55, 0x01, 0x73);\r
+       addToMapW(0x55, 0x01, 0xAF);\r
+       addToMapW(0x55, 0x01, 0xB0);\r
+       addToMapW(0x55, 0x01, 0xD3);\r
+       addToMapW(0x55, 0x01, 0xD4);\r
+       addToMapW(0x55, 0x01, 0xD5);\r
+       addToMapW(0x55, 0x01, 0xD6);\r
+       addToMapW(0x55, 0x01, 0xD7);\r
+       addToMapW(0x55, 0x01, 0xD8);\r
+       addToMapW(0x55, 0x01, 0xD9);\r
+       addToMapW(0x55, 0x01, 0xDA);\r
+       addToMapW(0x55, 0x01, 0xDB);\r
+       addToMapW(0x55, 0x01, 0xDC);\r
+       addToMapW(0x55, 0x03, 0xBC);\r
+       addToMapW(0x55, 0xFF, 0x35);\r
+       addToMapW(0x55, 0xFF, 0x55);\r
+       addToMapW(0x56, 0x00, 0x56);\r
+       addToMapW(0x56, 0x00, 0x76);\r
+       addToMapW(0x56, 0x22, 0x1A);\r
+       addToMapW(0x56, 0x27, 0x13);\r
+       addToMapW(0x56, 0xFF, 0x36);\r
+       addToMapW(0x56, 0xFF, 0x56);\r
+       addToMapW(0x57, 0x00, 0x57);\r
+       addToMapW(0x57, 0x00, 0x77);\r
+       addToMapW(0x57, 0x01, 0x74);\r
+       addToMapW(0x57, 0x01, 0x75);\r
+       addToMapW(0x57, 0xFF, 0x37);\r
+       addToMapW(0x57, 0xFF, 0x57);\r
+       addToMapW(0x58, 0x00, 0x58);\r
+       addToMapW(0x58, 0x00, 0x78);\r
+       addToMapW(0x58, 0x00, 0xD7);\r
+       addToMapW(0x58, 0xFF, 0x38);\r
+       addToMapW(0x58, 0xFF, 0x58);\r
+       addToMapW(0x59, 0x00, 0x59);\r
+       addToMapW(0x59, 0x00, 0x79);\r
+       addToMapW(0x59, 0x00, 0xA5);\r
+       addToMapW(0x59, 0x00, 0xDD);\r
+       addToMapW(0x59, 0x00, 0xFD);\r
+       addToMapW(0x59, 0x00, 0xFF);\r
+       addToMapW(0x59, 0x01, 0x76);\r
+       addToMapW(0x59, 0x01, 0x77);\r
+       addToMapW(0x59, 0x01, 0x78);\r
+       addToMapW(0x59, 0xFF, 0x39);\r
+       addToMapW(0x59, 0xFF, 0x59);\r
+       addToMapW(0x5a, 0x00, 0x5A);\r
+       addToMapW(0x5a, 0x00, 0x7A);\r
+       addToMapW(0x5a, 0x01, 0x79);\r
+       addToMapW(0x5a, 0x01, 0x7A);\r
+       addToMapW(0x5a, 0x01, 0x7B);\r
+       addToMapW(0x5a, 0x01, 0x7C);\r
+       addToMapW(0x5a, 0x01, 0x7D);\r
+       addToMapW(0x5a, 0x01, 0x7E);\r
+       addToMapW(0x5a, 0x01, 0xB6);\r
+       addToMapW(0x5a, 0x21, 0x24);\r
+       addToMapW(0x5a, 0x21, 0x28);\r
+       addToMapW(0x5a, 0xFF, 0x3A);\r
+       addToMapW(0x5a, 0xFF, 0x5A);\r
+       addToMapW(0x5b, 0x00, 0x5B);\r
+       addToMapW(0x5b, 0x30, 0x1A);\r
+       addToMapW(0x5b, 0xFF, 0x3B);\r
+       addToMapW(0x5c, 0x00, 0x5C);\r
+       addToMapW(0x5c, 0x00, 0xA5);\r
+       addToMapW(0x5c, 0x22, 0x16);\r
+       addToMapW(0x5c, 0xFF, 0x3C);\r
+       addToMapW(0x5d, 0x00, 0x5D);\r
+       addToMapW(0x5d, 0x30, 0x1B);\r
+       addToMapW(0x5d, 0xFF, 0x3D);\r
+       addToMapW(0x5e, 0x00, 0x5E);\r
+       addToMapW(0x5e, 0x02, 0xC4);\r
+       addToMapW(0x5e, 0x02, 0xC6);\r
+       addToMapW(0x5e, 0x02, 0xC7);\r
+       addToMapW(0x5e, 0x02, 0xD8);\r
+       addToMapW(0x5e, 0x03, 0x02);\r
+       addToMapW(0x5e, 0x03, 0x06);\r
+       addToMapW(0x5e, 0x03, 0x0C);\r
+       addToMapW(0x5e, 0x23, 0x03);\r
+       addToMapW(0x5e, 0xFF, 0x3E);\r
+       addToMapW(0x5f, 0x00, 0x5F);\r
+       addToMapW(0x5f, 0x00, 0xAF);\r
+       addToMapW(0x5f, 0x00, 0xBE);\r
+       addToMapW(0x5f, 0x00, 0xDE);\r
+       addToMapW(0x5f, 0x00, 0xFE);\r
+       addToMapW(0x5f, 0x02, 0xCD);\r
+       addToMapW(0x5f, 0x03, 0x31);\r
+       addToMapW(0x5f, 0x03, 0x32);\r
+       addToMapW(0x5f, 0x20, 0x17);\r
+       addToMapW(0x5f, 0x30, 0xFC);\r
+       addToMapW(0x5f, 0xFF, 0x3F);\r
+       addToMapW(0x60, 0x00, 0x60);\r
+       addToMapW(0x60, 0x02, 0xCB);\r
+       addToMapW(0x60, 0x03, 0x00);\r
+       addToMapW(0x60, 0x20, 0x18);\r
+       addToMapW(0x60, 0x20, 0x35);\r
+       addToMapW(0x60, 0xFF, 0x40);\r
+       addToMapW(0x7b, 0x00, 0x7B);\r
+       addToMapW(0x7b, 0xFF, 0x5B);\r
+       addToMapW(0x7c, 0x00, 0x7C);\r
+       addToMapW(0x7c, 0x00, 0xA6);\r
+       addToMapW(0x7c, 0x01, 0xC0);\r
+       addToMapW(0x7c, 0x22, 0x23);\r
+       addToMapW(0x7c, 0x27, 0x58);\r
+       addToMapW(0x7c, 0xFF, 0x5C);\r
+       addToMapW(0x7d, 0x00, 0x7D);\r
+       addToMapW(0x7d, 0x30, 0x1B);\r
+       addToMapW(0x7d, 0xFF, 0x5D);\r
+       addToMapW(0x7e, 0x00, 0x7E);\r
+       addToMapW(0x7e, 0x02, 0xDC);\r
+       addToMapW(0x7e, 0x03, 0x03);\r
+       addToMapW(0x7e, 0x22, 0x3C);\r
+       addToMapW(0x7e, 0x22, 0x48);\r
+       addToMapW(0x7e, 0xFF, 0x5E);\r
+       addToMapW(0x7f, 0x00, 0x7F);\r
+       addToMapW(0x7f, 0x23, 0x02);\r
+       addToMapW(0x7f, 0x26, 0x60);\r
+       addToMapW(0x7f, 0x26, 0x63);\r
+       addToMapW(0x7f, 0x26, 0x65);\r
+       addToMapW(0x7f, 0x26, 0x66);\r
+       addToMapW(0x80, 0x00, 0x80);\r
+       addToMapW(0x80, 0x00, 0xC7);\r
+       addToMapW(0x80, 0x00, 0xE7);\r
+       addToMapW(0x80, 0x01, 0x06);\r
+       addToMapW(0x80, 0x01, 0x07);\r
+       addToMapW(0x80, 0x03, 0x91);\r
+       addToMapW(0x80, 0x03, 0xB1);\r
+       addToMapW(0x80, 0x04, 0x10);\r
+       addToMapW(0x80, 0x04, 0x30);\r
+       addToMapW(0x80, 0x05, 0xD0);\r
+       addToMapW(0x80, 0x20, 0xAC);\r
+       addToMapW(0x81, 0x00, 0x81);\r
+       addToMapW(0x81, 0x03, 0x92);\r
+       addToMapW(0x81, 0x03, 0xB2);\r
+       addToMapW(0x81, 0x04, 0x02);\r
+       addToMapW(0x81, 0x04, 0x11);\r
+       addToMapW(0x81, 0x04, 0x31);\r
+       addToMapW(0x81, 0x04, 0x52);\r
+       addToMapW(0x81, 0x05, 0xD1);\r
+       addToMapW(0x82, 0x00, 0x82);\r
+       addToMapW(0x82, 0x03, 0x93);\r
+       addToMapW(0x82, 0x03, 0xB3);\r
+       addToMapW(0x82, 0x04, 0x12);\r
+       addToMapW(0x82, 0x04, 0x32);\r
+       addToMapW(0x82, 0x05, 0xD2);\r
+       addToMapW(0x82, 0x20, 0x1A);\r
+       addToMapW(0x83, 0x00, 0x83);\r
+       addToMapW(0x83, 0x03, 0x94);\r
+       addToMapW(0x83, 0x03, 0xB4);\r
+       addToMapW(0x83, 0x04, 0x03);\r
+       addToMapW(0x83, 0x04, 0x13);\r
+       addToMapW(0x83, 0x04, 0x33);\r
+       addToMapW(0x83, 0x04, 0x53);\r
+       addToMapW(0x83, 0x05, 0xD3);\r
+       addToMapW(0x84, 0x00, 0x84);\r
+       addToMapW(0x84, 0x03, 0x95);\r
+       addToMapW(0x84, 0x03, 0xB5);\r
+       addToMapW(0x84, 0x04, 0x14);\r
+       addToMapW(0x84, 0x04, 0x34);\r
+       addToMapW(0x84, 0x05, 0xD4);\r
+       addToMapW(0x84, 0x20, 0x1E);\r
+       addToMapW(0x85, 0x03, 0x96);\r
+       addToMapW(0x85, 0x03, 0xB6);\r
+       addToMapW(0x85, 0x04, 0x01);\r
+       addToMapW(0x85, 0x04, 0x15);\r
+       addToMapW(0x85, 0x04, 0x35);\r
+       addToMapW(0x85, 0x04, 0x51);\r
+       addToMapW(0x85, 0x05, 0xD5);\r
+       addToMapW(0x85, 0x20, 0x26);\r
+       addToMapW(0x86, 0x00, 0x86);\r
+       addToMapW(0x86, 0x03, 0x97);\r
+       addToMapW(0x86, 0x03, 0xB7);\r
+       addToMapW(0x86, 0x04, 0x16);\r
+       addToMapW(0x86, 0x04, 0x36);\r
+       addToMapW(0x86, 0x05, 0xD6);\r
+       addToMapW(0x86, 0x20, 0x20);\r
+       addToMapW(0x87, 0x00, 0x87);\r
+       addToMapW(0x87, 0x03, 0x98);\r
+       addToMapW(0x87, 0x03, 0xB8);\r
+       addToMapW(0x87, 0x04, 0x04);\r
+       addToMapW(0x87, 0x04, 0x17);\r
+       addToMapW(0x87, 0x04, 0x37);\r
+       addToMapW(0x87, 0x04, 0x54);\r
+       addToMapW(0x87, 0x05, 0xD7);\r
+       addToMapW(0x87, 0x20, 0x21);\r
+       addToMapW(0x88, 0x00, 0x88);\r
+       addToMapW(0x88, 0x02, 0xC6);\r
+       addToMapW(0x88, 0x03, 0x99);\r
+       addToMapW(0x88, 0x03, 0xB9);\r
+       addToMapW(0x88, 0x04, 0x18);\r
+       addToMapW(0x88, 0x04, 0x38);\r
+       addToMapW(0x88, 0x05, 0xD8);\r
+       addToMapW(0x89, 0x00, 0x89);\r
+       addToMapW(0x89, 0x03, 0x9A);\r
+       addToMapW(0x89, 0x03, 0xBA);\r
+       addToMapW(0x89, 0x04, 0x05);\r
+       addToMapW(0x89, 0x04, 0x19);\r
+       addToMapW(0x89, 0x04, 0x39);\r
+       addToMapW(0x89, 0x04, 0x55);\r
+       addToMapW(0x89, 0x05, 0xD9);\r
+       addToMapW(0x89, 0x20, 0x30);\r
+       addToMapW(0x8a, 0x00, 0x8A);\r
+       addToMapW(0x8a, 0x01, 0x50);\r
+       addToMapW(0x8a, 0x01, 0x51);\r
+       addToMapW(0x8a, 0x01, 0x56);\r
+       addToMapW(0x8a, 0x01, 0x57);\r
+       addToMapW(0x8a, 0x03, 0x9B);\r
+       addToMapW(0x8a, 0x03, 0xBB);\r
+       addToMapW(0x8a, 0x04, 0x1A);\r
+       addToMapW(0x8a, 0x04, 0x3A);\r
+       addToMapW(0x8a, 0x05, 0xDA);\r
+       addToMapW(0x8b, 0x00, 0x8B);\r
+       addToMapW(0x8b, 0x03, 0x9C);\r
+       addToMapW(0x8b, 0x03, 0xBC);\r
+       addToMapW(0x8b, 0x04, 0x06);\r
+       addToMapW(0x8b, 0x04, 0x1B);\r
+       addToMapW(0x8b, 0x04, 0x3B);\r
+       addToMapW(0x8b, 0x04, 0x56);\r
+       addToMapW(0x8b, 0x05, 0xDB);\r
+       addToMapW(0x8b, 0x20, 0x39);\r
+       addToMapW(0x8c, 0x00, 0x8C);\r
+       addToMapW(0x8c, 0x01, 0x52);\r
+       addToMapW(0x8c, 0x01, 0x53);\r
+       addToMapW(0x8c, 0x03, 0x9D);\r
+       addToMapW(0x8c, 0x03, 0xBD);\r
+       addToMapW(0x8c, 0x04, 0x1C);\r
+       addToMapW(0x8c, 0x04, 0x3C);\r
+       addToMapW(0x8c, 0x05, 0xDC);\r
+       addToMapW(0x8d, 0x00, 0x8D);\r
+       addToMapW(0x8d, 0x01, 0x31);\r
+       addToMapW(0x8d, 0x01, 0x79);\r
+       addToMapW(0x8d, 0x01, 0x7A);\r
+       addToMapW(0x8d, 0x03, 0x9E);\r
+       addToMapW(0x8d, 0x03, 0xBE);\r
+       addToMapW(0x8d, 0x04, 0x07);\r
+       addToMapW(0x8d, 0x04, 0x1D);\r
+       addToMapW(0x8d, 0x04, 0x3D);\r
+       addToMapW(0x8d, 0x04, 0x57);\r
+       addToMapW(0x8d, 0x05, 0xDD);\r
+       addToMapW(0x8e, 0x00, 0x8E);\r
+       addToMapW(0x8e, 0x00, 0xC4);\r
+       addToMapW(0x8e, 0x00, 0xE4);\r
+       addToMapW(0x8e, 0x03, 0x9F);\r
+       addToMapW(0x8e, 0x03, 0xBF);\r
+       addToMapW(0x8e, 0x04, 0x1E);\r
+       addToMapW(0x8e, 0x04, 0x3E);\r
+       addToMapW(0x8e, 0x05, 0xDE);\r
+       addToMapW(0x8f, 0x00, 0x8F);\r
+       addToMapW(0x8f, 0x00, 0xC5);\r
+       addToMapW(0x8f, 0x00, 0xE5);\r
+       addToMapW(0x8f, 0x01, 0x06);\r
+       addToMapW(0x8f, 0x01, 0x07);\r
+       addToMapW(0x8f, 0x03, 0xA0);\r
+       addToMapW(0x8f, 0x03, 0xC0);\r
+       addToMapW(0x8f, 0x04, 0x08);\r
+       addToMapW(0x8f, 0x04, 0x1F);\r
+       addToMapW(0x8f, 0x04, 0x3F);\r
+       addToMapW(0x8f, 0x04, 0x58);\r
+       addToMapW(0x8f, 0x05, 0xDF);\r
+       addToMapW(0x8f, 0x21, 0x2B);\r
+       addToMapW(0x90, 0x00, 0x90);\r
+       addToMapW(0x90, 0x00, 0xC9);\r
+       addToMapW(0x90, 0x00, 0xE9);\r
+       addToMapW(0x90, 0x03, 0xA1);\r
+       addToMapW(0x90, 0x03, 0xC1);\r
+       addToMapW(0x90, 0x04, 0x20);\r
+       addToMapW(0x90, 0x04, 0x40);\r
+       addToMapW(0x90, 0x05, 0xE0);\r
+       addToMapW(0x91, 0x01, 0x39);\r
+       addToMapW(0x91, 0x01, 0x3A);\r
+       addToMapW(0x91, 0x03, 0xA3);\r
+       addToMapW(0x91, 0x03, 0xC2);\r
+       addToMapW(0x91, 0x03, 0xC3);\r
+       addToMapW(0x91, 0x04, 0x09);\r
+       addToMapW(0x91, 0x04, 0x21);\r
+       addToMapW(0x91, 0x04, 0x41);\r
+       addToMapW(0x91, 0x04, 0x59);\r
+       addToMapW(0x91, 0x05, 0xE1);\r
+       addToMapW(0x91, 0x06, 0x51);\r
+       addToMapW(0x91, 0x20, 0x18);\r
+       addToMapW(0x91, 0xFE, 0x7C);\r
+       addToMapW(0x91, 0xFE, 0x7D);\r
+       addToMapW(0x92, 0x00, 0xC6);\r
+       addToMapW(0x92, 0x00, 0xE6);\r
+       addToMapW(0x92, 0x03, 0xA4);\r
+       addToMapW(0x92, 0x03, 0xC4);\r
+       addToMapW(0x92, 0x04, 0x22);\r
+       addToMapW(0x92, 0x04, 0x42);\r
+       addToMapW(0x92, 0x05, 0xE2);\r
+       addToMapW(0x92, 0x06, 0x52);\r
+       addToMapW(0x92, 0x20, 0x19);\r
+       addToMapW(0x92, 0xFE, 0x7E);\r
+       addToMapW(0x92, 0xFE, 0x7F);\r
+       addToMapW(0x93, 0x03, 0xA5);\r
+       addToMapW(0x93, 0x03, 0xC5);\r
+       addToMapW(0x93, 0x04, 0x0A);\r
+       addToMapW(0x93, 0x04, 0x23);\r
+       addToMapW(0x93, 0x04, 0x43);\r
+       addToMapW(0x93, 0x04, 0x5A);\r
+       addToMapW(0x93, 0x05, 0xE3);\r
+       addToMapW(0x93, 0x20, 0x1C);\r
+       addToMapW(0x94, 0x00, 0xA4);\r
+       addToMapW(0x94, 0x03, 0xA6);\r
+       addToMapW(0x94, 0x03, 0xC6);\r
+       addToMapW(0x94, 0x04, 0x24);\r
+       addToMapW(0x94, 0x04, 0x44);\r
+       addToMapW(0x94, 0x05, 0xE4);\r
+       addToMapW(0x94, 0x20, 0x1D);\r
+       addToMapW(0x95, 0x01, 0x22);\r
+       addToMapW(0x95, 0x01, 0x23);\r
+       addToMapW(0x95, 0x01, 0x3D);\r
+       addToMapW(0x95, 0x01, 0x3E);\r
+       addToMapW(0x95, 0x03, 0xA7);\r
+       addToMapW(0x95, 0x03, 0xC7);\r
+       addToMapW(0x95, 0x04, 0x0B);\r
+       addToMapW(0x95, 0x04, 0x25);\r
+       addToMapW(0x95, 0x04, 0x45);\r
+       addToMapW(0x95, 0x04, 0x5B);\r
+       addToMapW(0x95, 0x05, 0xE5);\r
+       addToMapW(0x95, 0x06, 0x40);\r
+       addToMapW(0x95, 0x20, 0x22);\r
+       addToMapW(0x96, 0x00, 0xA2);\r
+       addToMapW(0x96, 0x03, 0xA8);\r
+       addToMapW(0x96, 0x03, 0xC8);\r
+       addToMapW(0x96, 0x04, 0x26);\r
+       addToMapW(0x96, 0x04, 0x46);\r
+       addToMapW(0x96, 0x05, 0xE6);\r
+       addToMapW(0x96, 0x20, 0x13);\r
+       addToMapW(0x97, 0x00, 0xB5);\r
+       addToMapW(0x97, 0x01, 0x5A);\r
+       addToMapW(0x97, 0x01, 0x5B);\r
+       addToMapW(0x97, 0x03, 0xA9);\r
+       addToMapW(0x97, 0x03, 0xC9);\r
+       addToMapW(0x97, 0x04, 0x0C);\r
+       addToMapW(0x97, 0x04, 0x27);\r
+       addToMapW(0x97, 0x04, 0x47);\r
+       addToMapW(0x97, 0x04, 0x5C);\r
+       addToMapW(0x97, 0x05, 0xE7);\r
+       addToMapW(0x97, 0x20, 0x14);\r
+       addToMapW(0x98, 0x00, 0x98);\r
+       addToMapW(0x98, 0x01, 0x30);\r
+       addToMapW(0x98, 0x02, 0xDC);\r
+       addToMapW(0x98, 0x04, 0x28);\r
+       addToMapW(0x98, 0x04, 0x48);\r
+       addToMapW(0x98, 0x05, 0xE8);\r
+       addToMapW(0x98, 0x06, 0x21);\r
+       addToMapW(0x98, 0xFE, 0x80);\r
+       addToMapW(0x99, 0x00, 0x99);\r
+       addToMapW(0x99, 0x00, 0xD6);\r
+       addToMapW(0x99, 0x00, 0xF6);\r
+       addToMapW(0x99, 0x04, 0x0E);\r
+       addToMapW(0x99, 0x04, 0x29);\r
+       addToMapW(0x99, 0x04, 0x49);\r
+       addToMapW(0x99, 0x04, 0x5E);\r
+       addToMapW(0x99, 0x05, 0xE9);\r
+       addToMapW(0x99, 0x06, 0x22);\r
+       addToMapW(0x99, 0x21, 0x22);\r
+       addToMapW(0x99, 0xFE, 0x81);\r
+       addToMapW(0x99, 0xFE, 0x82);\r
+       addToMapW(0x9a, 0x00, 0x9A);\r
+       addToMapW(0x9a, 0x00, 0xDC);\r
+       addToMapW(0x9a, 0x00, 0xFC);\r
+       addToMapW(0x9a, 0x04, 0x2A);\r
+       addToMapW(0x9a, 0x04, 0x4A);\r
+       addToMapW(0x9a, 0x05, 0xEA);\r
+       addToMapW(0x9a, 0x06, 0x23);\r
+       addToMapW(0x9a, 0xFE, 0x83);\r
+       addToMapW(0x9a, 0xFE, 0x84);\r
+       addToMapW(0x9b, 0x00, 0x9B);\r
+       addToMapW(0x9b, 0x00, 0xA2);\r
+       addToMapW(0x9b, 0x01, 0x64);\r
+       addToMapW(0x9b, 0x01, 0x65);\r
+       addToMapW(0x9b, 0x04, 0x0F);\r
+       addToMapW(0x9b, 0x04, 0x2B);\r
+       addToMapW(0x9b, 0x04, 0x4B);\r
+       addToMapW(0x9b, 0x04, 0x5F);\r
+       addToMapW(0x9b, 0x06, 0x24);\r
+       addToMapW(0x9b, 0x20, 0x3A);\r
+       addToMapW(0x9b, 0xFE, 0x85);\r
+       addToMapW(0x9b, 0xFE, 0x86);\r
+       addToMapW(0x9c, 0x00, 0x9C);\r
+       addToMapW(0x9c, 0x00, 0xA3);\r
+       addToMapW(0x9c, 0x04, 0x2C);\r
+       addToMapW(0x9c, 0x04, 0x4C);\r
+       addToMapW(0x9c, 0x20, 0xA4);\r
+       addToMapW(0x9d, 0x00, 0x9D);\r
+       addToMapW(0x9d, 0x00, 0xA5);\r
+       addToMapW(0x9d, 0x00, 0xD8);\r
+       addToMapW(0x9d, 0x00, 0xF8);\r
+       addToMapW(0x9d, 0x01, 0x41);\r
+       addToMapW(0x9d, 0x01, 0x42);\r
+       addToMapW(0x9d, 0x02, 0x78);\r
+       addToMapW(0x9d, 0x03, 0x98);\r
+       addToMapW(0x9d, 0x04, 0x2D);\r
+       addToMapW(0x9d, 0x04, 0x2E);\r
+       addToMapW(0x9d, 0x04, 0x4D);\r
+       addToMapW(0x9d, 0x04, 0x4E);\r
+       addToMapW(0x9d, 0x06, 0x25);\r
+       addToMapW(0x9d, 0x22, 0x05);\r
+       addToMapW(0x9d, 0xFE, 0x87);\r
+       addToMapW(0x9d, 0xFE, 0x88);\r
+       addToMapW(0x9e, 0x00, 0x9E);\r
+       addToMapW(0x9e, 0x00, 0xD7);\r
+       addToMapW(0x9e, 0x01, 0x5E);\r
+       addToMapW(0x9e, 0x01, 0x5F);\r
+       addToMapW(0x9e, 0x04, 0x2E);\r
+       addToMapW(0x9e, 0x04, 0x4E);\r
+       addToMapW(0x9e, 0x06, 0x26);\r
+       addToMapW(0x9e, 0x20, 0xA7);\r
+       addToMapW(0x9e, 0xFE, 0x89);\r
+       addToMapW(0x9e, 0xFE, 0x8A);\r
+       addToMapW(0x9e, 0xFE, 0x8B);\r
+       addToMapW(0x9e, 0xFE, 0x8C);\r
+       addToMapW(0x9f, 0x00, 0x9F);\r
+       addToMapW(0x9f, 0x00, 0xA4);\r
+       addToMapW(0x9f, 0x00, 0xFF);\r
+       addToMapW(0x9f, 0x01, 0x78);\r
+       addToMapW(0x9f, 0x01, 0x91);\r
+       addToMapW(0x9f, 0x01, 0x92);\r
+       addToMapW(0x9f, 0x04, 0x2A);\r
+       addToMapW(0x9f, 0x04, 0x2F);\r
+       addToMapW(0x9f, 0x04, 0x4A);\r
+       addToMapW(0x9f, 0x04, 0x4F);\r
+       addToMapW(0x9f, 0x06, 0x27);\r
+       addToMapW(0x9f, 0xFE, 0x8D);\r
+       addToMapW(0x9f, 0xFE, 0x8E);\r
+       addToMapW(0xa0, 0x00, 0xA0);\r
+       addToMapW(0xa0, 0x01, 0x00);\r
+       addToMapW(0xa0, 0x01, 0x01);\r
+       addToMapW(0xa0, 0x06, 0x28);\r
+       addToMapW(0xa0, 0xF8, 0xF0);\r
+       addToMapW(0xa0, 0xFE, 0x8F);\r
+       addToMapW(0xa0, 0xFE, 0x90);\r
+       addToMapW(0xa0, 0xFE, 0x91);\r
+       addToMapW(0xa0, 0xFE, 0x92);\r
+       addToMapW(0xa1, 0x00, 0xA1);\r
+       addToMapW(0xa1, 0x01, 0x2A);\r
+       addToMapW(0xa1, 0x01, 0x2B);\r
+       addToMapW(0xa1, 0x04, 0x10);\r
+       addToMapW(0xa1, 0x04, 0x30);\r
+       addToMapW(0xa1, 0x06, 0x29);\r
+       addToMapW(0xa1, 0x0E, 0x01);\r
+       addToMapW(0xa1, 0xFE, 0x93);\r
+       addToMapW(0xa1, 0xFE, 0x94);\r
+       addToMapW(0xa1, 0xFF, 0x61);\r
+       addToMapW(0xa2, 0x00, 0xA2);\r
+       addToMapW(0xa2, 0x06, 0x2A);\r
+       addToMapW(0xa2, 0x0E, 0x02);\r
+       addToMapW(0xa2, 0xFE, 0x95);\r
+       addToMapW(0xa2, 0xFE, 0x96);\r
+       addToMapW(0xa2, 0xFE, 0x97);\r
+       addToMapW(0xa2, 0xFE, 0x98);\r
+       addToMapW(0xa2, 0xFF, 0x62);\r
+       addToMapW(0xa3, 0x00, 0xA3);\r
+       addToMapW(0xa3, 0x01, 0x7B);\r
+       addToMapW(0xa3, 0x01, 0x7C);\r
+       addToMapW(0xa3, 0x04, 0x11);\r
+       addToMapW(0xa3, 0x04, 0x31);\r
+       addToMapW(0xa3, 0x06, 0x2B);\r
+       addToMapW(0xa3, 0x0E, 0x03);\r
+       addToMapW(0xa3, 0xFE, 0x99);\r
+       addToMapW(0xa3, 0xFE, 0x9A);\r
+       addToMapW(0xa3, 0xFE, 0x9B);\r
+       addToMapW(0xa3, 0xFE, 0x9C);\r
+       addToMapW(0xa3, 0xFF, 0x63);\r
+       addToMapW(0xa4, 0x00, 0xA4);\r
+       addToMapW(0xa4, 0x01, 0x04);\r
+       addToMapW(0xa4, 0x01, 0x05);\r
+       addToMapW(0xa4, 0x06, 0x2C);\r
+       addToMapW(0xa4, 0x0E, 0x04);\r
+       addToMapW(0xa4, 0xFE, 0x9D);\r
+       addToMapW(0xa4, 0xFE, 0x9E);\r
+       addToMapW(0xa4, 0xFE, 0x9F);\r
+       addToMapW(0xa4, 0xFE, 0xA0);\r
+       addToMapW(0xa4, 0xFF, 0x64);\r
+       addToMapW(0xa5, 0x00, 0xA5);\r
+       addToMapW(0xa5, 0x00, 0xD1);\r
+       addToMapW(0xa5, 0x00, 0xF1);\r
+       addToMapW(0xa5, 0x04, 0x26);\r
+       addToMapW(0xa5, 0x04, 0x46);\r
+       addToMapW(0xa5, 0x06, 0x2D);\r
+       addToMapW(0xa5, 0x0E, 0x05);\r
+       addToMapW(0xa5, 0xFE, 0xA1);\r
+       addToMapW(0xa5, 0xFE, 0xA2);\r
+       addToMapW(0xa5, 0xFE, 0xA3);\r
+       addToMapW(0xa5, 0xFE, 0xA4);\r
+       addToMapW(0xa5, 0xFF, 0x65);\r
+       addToMapW(0xa6, 0x00, 0xA6);\r
+       addToMapW(0xa6, 0x00, 0xAA);\r
+       addToMapW(0xa6, 0x01, 0x1E);\r
+       addToMapW(0xa6, 0x01, 0x1F);\r
+       addToMapW(0xa6, 0x01, 0x7D);\r
+       addToMapW(0xa6, 0x01, 0x7E);\r
+       addToMapW(0xa6, 0x06, 0x2E);\r
+       addToMapW(0xa6, 0x0E, 0x06);\r
+       addToMapW(0xa6, 0x20, 0x1D);\r
+       addToMapW(0xa6, 0xFE, 0xA5);\r
+       addToMapW(0xa6, 0xFE, 0xA6);\r
+       addToMapW(0xa6, 0xFE, 0xA7);\r
+       addToMapW(0xa6, 0xFE, 0xA8);\r
+       addToMapW(0xa6, 0xFF, 0x66);\r
+       addToMapW(0xa7, 0x00, 0xA6);\r
+       addToMapW(0xa7, 0x00, 0xA7);\r
+       addToMapW(0xa7, 0x00, 0xBA);\r
+       addToMapW(0xa7, 0x04, 0x14);\r
+       addToMapW(0xa7, 0x04, 0x34);\r
+       addToMapW(0xa7, 0x06, 0x2F);\r
+       addToMapW(0xa7, 0x0E, 0x07);\r
+       addToMapW(0xa7, 0xFE, 0xA9);\r
+       addToMapW(0xa7, 0xFE, 0xAA);\r
+       addToMapW(0xa7, 0xFF, 0x67);\r
+       addToMapW(0xa8, 0x00, 0xA8);\r
+       addToMapW(0xa8, 0x00, 0xA9);\r
+       addToMapW(0xa8, 0x00, 0xBF);\r
+       addToMapW(0xa8, 0x01, 0x18);\r
+       addToMapW(0xa8, 0x01, 0x19);\r
+       addToMapW(0xa8, 0x06, 0x30);\r
+       addToMapW(0xa8, 0x0E, 0x08);\r
+       addToMapW(0xa8, 0xFE, 0xAB);\r
+       addToMapW(0xa8, 0xFE, 0xAC);\r
+       addToMapW(0xa8, 0xFF, 0x68);\r
+       addToMapW(0xa9, 0x00, 0xA9);\r
+       addToMapW(0xa9, 0x00, 0xAE);\r
+       addToMapW(0xa9, 0x04, 0x15);\r
+       addToMapW(0xa9, 0x04, 0x35);\r
+       addToMapW(0xa9, 0x06, 0x31);\r
+       addToMapW(0xa9, 0x0E, 0x09);\r
+       addToMapW(0xa9, 0x23, 0x10);\r
+       addToMapW(0xa9, 0xFE, 0xAD);\r
+       addToMapW(0xa9, 0xFE, 0xAE);\r
+       addToMapW(0xa9, 0xFF, 0x69);\r
+       addToMapW(0xaa, 0x00, 0xAA);\r
+       addToMapW(0xaa, 0x00, 0xAC);\r
+       addToMapW(0xaa, 0x06, 0x32);\r
+       addToMapW(0xaa, 0x0E, 0x0A);\r
+       addToMapW(0xaa, 0x23, 0x10);\r
+       addToMapW(0xaa, 0xFE, 0xAF);\r
+       addToMapW(0xaa, 0xFE, 0xB0);\r
+       addToMapW(0xaa, 0xFF, 0x6A);\r
+       addToMapW(0xab, 0x00, 0xAB);\r
+       addToMapW(0xab, 0x00, 0xBD);\r
+       addToMapW(0xab, 0x04, 0x24);\r
+       addToMapW(0xab, 0x04, 0x44);\r
+       addToMapW(0xab, 0x06, 0x33);\r
+       addToMapW(0xab, 0x0E, 0x0B);\r
+       addToMapW(0xab, 0xFE, 0xB1);\r
+       addToMapW(0xab, 0xFE, 0xB2);\r
+       addToMapW(0xab, 0xFE, 0xB3);\r
+       addToMapW(0xab, 0xFE, 0xB4);\r
+       addToMapW(0xab, 0xFF, 0x6B);\r
+       addToMapW(0xac, 0x00, 0xAC);\r
+       addToMapW(0xac, 0x00, 0xBC);\r
+       addToMapW(0xac, 0x01, 0x0C);\r
+       addToMapW(0xac, 0x01, 0x0D);\r
+       addToMapW(0xac, 0x06, 0x34);\r
+       addToMapW(0xac, 0x0E, 0x0C);\r
+       addToMapW(0xac, 0xFE, 0xB5);\r
+       addToMapW(0xac, 0xFE, 0xB6);\r
+       addToMapW(0xac, 0xFE, 0xB7);\r
+       addToMapW(0xac, 0xFE, 0xB8);\r
+       addToMapW(0xac, 0xFF, 0x6C);\r
+       addToMapW(0xad, 0x00, 0xA1);\r
+       addToMapW(0xad, 0x00, 0xAD);\r
+       addToMapW(0xad, 0x01, 0x41);\r
+       addToMapW(0xad, 0x01, 0x42);\r
+       addToMapW(0xad, 0x04, 0x13);\r
+       addToMapW(0xad, 0x04, 0x33);\r
+       addToMapW(0xad, 0x06, 0x35);\r
+       addToMapW(0xad, 0x0E, 0x0D);\r
+       addToMapW(0xad, 0xFE, 0xB9);\r
+       addToMapW(0xad, 0xFE, 0xBA);\r
+       addToMapW(0xad, 0xFE, 0xBB);\r
+       addToMapW(0xad, 0xFE, 0xBC);\r
+       addToMapW(0xad, 0xFF, 0x6D);\r
+       addToMapW(0xae, 0x00, 0xAB);\r
+       addToMapW(0xae, 0x00, 0xAE);\r
+       addToMapW(0xae, 0x0E, 0x0E);\r
+       addToMapW(0xae, 0x22, 0x6A);\r
+       addToMapW(0xae, 0x30, 0x0A);\r
+       addToMapW(0xae, 0xFF, 0x6E);\r
+       addToMapW(0xaf, 0x00, 0xAF);\r
+       addToMapW(0xaf, 0x00, 0xBB);\r
+       addToMapW(0xaf, 0x0E, 0x0F);\r
+       addToMapW(0xaf, 0x22, 0x6B);\r
+       addToMapW(0xaf, 0x30, 0x0B);\r
+       addToMapW(0xaf, 0xFF, 0x6F);\r
+       addToMapW(0xb0, 0x00, 0xB0);\r
+       addToMapW(0xb0, 0x0E, 0x10);\r
+       addToMapW(0xb0, 0x25, 0x91);\r
+       addToMapW(0xb0, 0xFF, 0x70);\r
+       addToMapW(0xb1, 0x00, 0xB1);\r
+       addToMapW(0xb1, 0x0E, 0x11);\r
+       addToMapW(0xb1, 0x25, 0x92);\r
+       addToMapW(0xb1, 0xFF, 0x71);\r
+       addToMapW(0xb2, 0x00, 0xB2);\r
+       addToMapW(0xb2, 0x0E, 0x12);\r
+       addToMapW(0xb2, 0x25, 0x93);\r
+       addToMapW(0xb2, 0xFF, 0x72);\r
+       addToMapW(0xb3, 0x00, 0xA6);\r
+       addToMapW(0xb3, 0x00, 0xB3);\r
+       addToMapW(0xb3, 0x01, 0xC0);\r
+       addToMapW(0xb3, 0x0E, 0x13);\r
+       addToMapW(0xb3, 0x22, 0x23);\r
+       addToMapW(0xb3, 0x25, 0x02);\r
+       addToMapW(0xb3, 0x27, 0x58);\r
+       addToMapW(0xb3, 0xFF, 0x73);\r
+       addToMapW(0xb4, 0x00, 0xB4);\r
+       addToMapW(0xb4, 0x0E, 0x14);\r
+       addToMapW(0xb4, 0x25, 0x24);\r
+       addToMapW(0xb4, 0xFF, 0x74);\r
+       addToMapW(0xb5, 0x00, 0xB5);\r
+       addToMapW(0xb5, 0x00, 0xC1);\r
+       addToMapW(0xb5, 0x00, 0xE1);\r
+       addToMapW(0xb5, 0x01, 0x04);\r
+       addToMapW(0xb5, 0x01, 0x05);\r
+       addToMapW(0xb5, 0x0E, 0x15);\r
+       addToMapW(0xb5, 0x25, 0x61);\r
+       addToMapW(0xb5, 0xFF, 0x75);\r
+       addToMapW(0xb6, 0x00, 0xB6);\r
+       addToMapW(0xb6, 0x00, 0xC2);\r
+       addToMapW(0xb6, 0x00, 0xE2);\r
+       addToMapW(0xb6, 0x01, 0x0C);\r
+       addToMapW(0xb6, 0x01, 0x0D);\r
+       addToMapW(0xb6, 0x04, 0x25);\r
+       addToMapW(0xb6, 0x04, 0x45);\r
+       addToMapW(0xb6, 0x0E, 0x16);\r
+       addToMapW(0xb6, 0x25, 0x62);\r
+       addToMapW(0xb6, 0xFF, 0x76);\r
+       addToMapW(0xb7, 0x00, 0xB7);\r
+       addToMapW(0xb7, 0x00, 0xC0);\r
+       addToMapW(0xb7, 0x00, 0xE0);\r
+       addToMapW(0xb7, 0x01, 0x18);\r
+       addToMapW(0xb7, 0x01, 0x19);\r
+       addToMapW(0xb7, 0x01, 0x1A);\r
+       addToMapW(0xb7, 0x01, 0x1B);\r
+       addToMapW(0xb7, 0x0E, 0x17);\r
+       addToMapW(0xb7, 0x25, 0x56);\r
+       addToMapW(0xb7, 0xFF, 0x77);\r
+       addToMapW(0xb8, 0x00, 0xA9);\r
+       addToMapW(0xb8, 0x00, 0xB8);\r
+       addToMapW(0xb8, 0x01, 0x16);\r
+       addToMapW(0xb8, 0x01, 0x17);\r
+       addToMapW(0xb8, 0x01, 0x5E);\r
+       addToMapW(0xb8, 0x01, 0x5F);\r
+       addToMapW(0xb8, 0x04, 0x18);\r
+       addToMapW(0xb8, 0x04, 0x38);\r
+       addToMapW(0xb8, 0x0E, 0x18);\r
+       addToMapW(0xb8, 0x25, 0x55);\r
+       addToMapW(0xb8, 0xFF, 0x78);\r
+       addToMapW(0xb9, 0x00, 0xB9);\r
+       addToMapW(0xb9, 0x0E, 0x19);\r
+       addToMapW(0xb9, 0x25, 0x61);\r
+       addToMapW(0xb9, 0x25, 0x62);\r
+       addToMapW(0xb9, 0x25, 0x63);\r
+       addToMapW(0xb9, 0xFF, 0x79);\r
+       addToMapW(0xba, 0x00, 0xBA);\r
+       addToMapW(0xba, 0x0E, 0x1A);\r
+       addToMapW(0xba, 0x25, 0x51);\r
+       addToMapW(0xba, 0xFF, 0x7A);\r
+       addToMapW(0xbb, 0x00, 0xBB);\r
+       addToMapW(0xbb, 0x0E, 0x1B);\r
+       addToMapW(0xbb, 0x25, 0x55);\r
+       addToMapW(0xbb, 0x25, 0x56);\r
+       addToMapW(0xbb, 0x25, 0x57);\r
+       addToMapW(0xbb, 0xFF, 0x7B);\r
+       addToMapW(0xbc, 0x00, 0xBC);\r
+       addToMapW(0xbc, 0x0E, 0x1C);\r
+       addToMapW(0xbc, 0x25, 0x5B);\r
+       addToMapW(0xbc, 0x25, 0x5C);\r
+       addToMapW(0xbc, 0x25, 0x5D);\r
+       addToMapW(0xbc, 0xFF, 0x7C);\r
+       addToMapW(0xbd, 0x00, 0xA2);\r
+       addToMapW(0xbd, 0x00, 0xBD);\r
+       addToMapW(0xbd, 0x01, 0x2E);\r
+       addToMapW(0xbd, 0x01, 0x2F);\r
+       addToMapW(0xbd, 0x01, 0x7B);\r
+       addToMapW(0xbd, 0x01, 0x7C);\r
+       addToMapW(0xbd, 0x0E, 0x1D);\r
+       addToMapW(0xbd, 0x25, 0x5C);\r
+       addToMapW(0xbd, 0xFF, 0x7D);\r
+       addToMapW(0xbe, 0x00, 0xA5);\r
+       addToMapW(0xbe, 0x00, 0xBE);\r
+       addToMapW(0xbe, 0x01, 0x60);\r
+       addToMapW(0xbe, 0x01, 0x61);\r
+       addToMapW(0xbe, 0x04, 0x19);\r
+       addToMapW(0xbe, 0x04, 0x39);\r
+       addToMapW(0xbe, 0x0E, 0x1E);\r
+       addToMapW(0xbe, 0x25, 0x5B);\r
+       addToMapW(0xbe, 0xFF, 0x7E);\r
+       addToMapW(0xbf, 0x00, 0xAC);\r
+       addToMapW(0xbf, 0x00, 0xBF);\r
+       addToMapW(0xbf, 0x0E, 0x1F);\r
+       addToMapW(0xbf, 0x25, 0x10);\r
+       addToMapW(0xbf, 0xFF, 0x7F);\r
+       addToMapW(0xc0, 0x00, 0xC0);\r
+       addToMapW(0xc0, 0x00, 0xE0);\r
+       addToMapW(0xc0, 0x0E, 0x20);\r
+       addToMapW(0xc0, 0x25, 0x14);\r
+       addToMapW(0xc0, 0xFF, 0x80);\r
+       addToMapW(0xc1, 0x00, 0xC1);\r
+       addToMapW(0xc1, 0x00, 0xE1);\r
+       addToMapW(0xc1, 0x0E, 0x21);\r
+       addToMapW(0xc1, 0x25, 0x34);\r
+       addToMapW(0xc1, 0xFF, 0x81);\r
+       addToMapW(0xc2, 0x00, 0xC2);\r
+       addToMapW(0xc2, 0x00, 0xE2);\r
+       addToMapW(0xc2, 0x0E, 0x22);\r
+       addToMapW(0xc2, 0x25, 0x2C);\r
+       addToMapW(0xc2, 0xFF, 0x82);\r
+       addToMapW(0xc3, 0x01, 0x02);\r
+       addToMapW(0xc3, 0x01, 0x03);\r
+       addToMapW(0xc3, 0x0E, 0x23);\r
+       addToMapW(0xc3, 0x25, 0x1C);\r
+       addToMapW(0xc3, 0xFF, 0x83);\r
+       addToMapW(0xc4, 0x00, 0xAF);\r
+       addToMapW(0xc4, 0x00, 0xC4);\r
+       addToMapW(0xc4, 0x00, 0xE4);\r
+       addToMapW(0xc4, 0x02, 0xC9);\r
+       addToMapW(0xc4, 0x03, 0x04);\r
+       addToMapW(0xc4, 0x03, 0x05);\r
+       addToMapW(0xc4, 0x0E, 0x24);\r
+       addToMapW(0xc4, 0x25, 0x00);\r
+       addToMapW(0xc4, 0xFF, 0x84);\r
+       addToMapW(0xc5, 0x00, 0xC5);\r
+       addToMapW(0xc5, 0x00, 0xE5);\r
+       addToMapW(0xc5, 0x0E, 0x25);\r
+       addToMapW(0xc5, 0x20, 0x20);\r
+       addToMapW(0xc5, 0x20, 0x21);\r
+       addToMapW(0xc5, 0x25, 0x3C);\r
+       addToMapW(0xc5, 0xFF, 0x85);\r
+       addToMapW(0xc6, 0x00, 0xC6);\r
+       addToMapW(0xc6, 0x00, 0xE6);\r
+       addToMapW(0xc6, 0x01, 0x02);\r
+       addToMapW(0xc6, 0x01, 0x03);\r
+       addToMapW(0xc6, 0x01, 0x72);\r
+       addToMapW(0xc6, 0x01, 0x73);\r
+       addToMapW(0xc6, 0x0E, 0x26);\r
+       addToMapW(0xc6, 0x25, 0x5E);\r
+       addToMapW(0xc6, 0xFF, 0x86);\r
+       addToMapW(0xc7, 0x00, 0xC3);\r
+       addToMapW(0xc7, 0x00, 0xC7);\r
+       addToMapW(0xc7, 0x00, 0xE3);\r
+       addToMapW(0xc7, 0x00, 0xE7);\r
+       addToMapW(0xc7, 0x01, 0x6A);\r
+       addToMapW(0xc7, 0x01, 0x6B);\r
+       addToMapW(0xc7, 0x04, 0x1A);\r
+       addToMapW(0xc7, 0x04, 0x3A);\r
+       addToMapW(0xc7, 0x0E, 0x27);\r
+       addToMapW(0xc7, 0x25, 0x5F);\r
+       addToMapW(0xc7, 0xFF, 0x87);\r
+       addToMapW(0xc8, 0x00, 0xC8);\r
+       addToMapW(0xc8, 0x00, 0xE8);\r
+       addToMapW(0xc8, 0x0E, 0x28);\r
+       addToMapW(0xc8, 0x25, 0x58);\r
+       addToMapW(0xc8, 0x25, 0x59);\r
+       addToMapW(0xc8, 0x25, 0x5A);\r
+       addToMapW(0xc8, 0xFF, 0x88);\r
+       addToMapW(0xc9, 0x00, 0xC9);\r
+       addToMapW(0xc9, 0x00, 0xE9);\r
+       addToMapW(0xc9, 0x0E, 0x29);\r
+       addToMapW(0xc9, 0x25, 0x52);\r
+       addToMapW(0xc9, 0x25, 0x53);\r
+       addToMapW(0xc9, 0x25, 0x54);\r
+       addToMapW(0xc9, 0xFF, 0x89);\r
+       addToMapW(0xca, 0x00, 0xCA);\r
+       addToMapW(0xca, 0x00, 0xEA);\r
+       addToMapW(0xca, 0x0E, 0x2A);\r
+       addToMapW(0xca, 0x25, 0x67);\r
+       addToMapW(0xca, 0x25, 0x68);\r
+       addToMapW(0xca, 0x25, 0x69);\r
+       addToMapW(0xca, 0xFF, 0x8A);\r
+       addToMapW(0xcb, 0x00, 0xCB);\r
+       addToMapW(0xcb, 0x00, 0xEB);\r
+       addToMapW(0xcb, 0x0E, 0x2B);\r
+       addToMapW(0xcb, 0x25, 0x64);\r
+       addToMapW(0xcb, 0x25, 0x65);\r
+       addToMapW(0xcb, 0x25, 0x66);\r
+       addToMapW(0xcb, 0xFF, 0x8B);\r
+       addToMapW(0xcc, 0x03, 0x00);\r
+       addToMapW(0xcc, 0x0E, 0x2C);\r
+       addToMapW(0xcc, 0x25, 0x5E);\r
+       addToMapW(0xcc, 0x25, 0x5F);\r
+       addToMapW(0xcc, 0x25, 0x60);\r
+       addToMapW(0xcc, 0xFF, 0x8C);\r
+       addToMapW(0xcd, 0x00, 0xCD);\r
+       addToMapW(0xcd, 0x00, 0xED);\r
+       addToMapW(0xcd, 0x0E, 0x2D);\r
+       addToMapW(0xcd, 0x25, 0x50);\r
+       addToMapW(0xcd, 0xFF, 0x8D);\r
+       addToMapW(0xce, 0x00, 0xCE);\r
+       addToMapW(0xce, 0x00, 0xEE);\r
+       addToMapW(0xce, 0x0E, 0x2E);\r
+       addToMapW(0xce, 0x20, 0x21);\r
+       addToMapW(0xce, 0x25, 0x6A);\r
+       addToMapW(0xce, 0x25, 0x6B);\r
+       addToMapW(0xce, 0x25, 0x6C);\r
+       addToMapW(0xce, 0xFF, 0x8E);\r
+       addToMapW(0xcf, 0x00, 0xA4);\r
+       addToMapW(0xcf, 0x00, 0xCF);\r
+       addToMapW(0xcf, 0x00, 0xEF);\r
+       addToMapW(0xcf, 0x01, 0x7D);\r
+       addToMapW(0xcf, 0x01, 0x7E);\r
+       addToMapW(0xcf, 0x0E, 0x2F);\r
+       addToMapW(0xcf, 0x25, 0x67);\r
+       addToMapW(0xcf, 0xFF, 0x8F);\r
+       addToMapW(0xd0, 0x00, 0xBA);\r
+       addToMapW(0xd0, 0x01, 0x10);\r
+       addToMapW(0xd0, 0x01, 0x11);\r
+       addToMapW(0xd0, 0x0E, 0x30);\r
+       addToMapW(0xd0, 0x25, 0x68);\r
+       addToMapW(0xd0, 0xFF, 0x90);\r
+       addToMapW(0xd1, 0x00, 0xAA);\r
+       addToMapW(0xd1, 0x00, 0xD0);\r
+       addToMapW(0xd1, 0x00, 0xD1);\r
+       addToMapW(0xd1, 0x00, 0xF0);\r
+       addToMapW(0xd1, 0x00, 0xF1);\r
+       addToMapW(0xd1, 0x01, 0x10);\r
+       addToMapW(0xd1, 0x01, 0x11);\r
+       addToMapW(0xd1, 0x01, 0x89);\r
+       addToMapW(0xd1, 0x04, 0x1B);\r
+       addToMapW(0xd1, 0x04, 0x3B);\r
+       addToMapW(0xd1, 0x0E, 0x31);\r
+       addToMapW(0xd1, 0x25, 0x64);\r
+       addToMapW(0xd1, 0xFF, 0x91);\r
+       addToMapW(0xd2, 0x00, 0xCA);\r
+       addToMapW(0xd2, 0x00, 0xEA);\r
+       addToMapW(0xd2, 0x01, 0x0E);\r
+       addToMapW(0xd2, 0x01, 0x0F);\r
+       addToMapW(0xd2, 0x03, 0x09);\r
+       addToMapW(0xd2, 0x0E, 0x32);\r
+       addToMapW(0xd2, 0x25, 0x65);\r
+       addToMapW(0xd2, 0xFF, 0x92);\r
+       addToMapW(0xd3, 0x00, 0xCB);\r
+       addToMapW(0xd3, 0x00, 0xD3);\r
+       addToMapW(0xd3, 0x00, 0xEB);\r
+       addToMapW(0xd3, 0x00, 0xF3);\r
+       addToMapW(0xd3, 0x04, 0x1C);\r
+       addToMapW(0xd3, 0x04, 0x3C);\r
+       addToMapW(0xd3, 0x0E, 0x33);\r
+       addToMapW(0xd3, 0x25, 0x59);\r
+       addToMapW(0xd3, 0xFF, 0x93);\r
+       addToMapW(0xd4, 0x00, 0xC8);\r
+       addToMapW(0xd4, 0x00, 0xD4);\r
+       addToMapW(0xd4, 0x00, 0xE8);\r
+       addToMapW(0xd4, 0x00, 0xF4);\r
+       addToMapW(0xd4, 0x0E, 0x34);\r
+       addToMapW(0xd4, 0x25, 0x58);\r
+       addToMapW(0xd4, 0xFF, 0x94);\r
+       addToMapW(0xd5, 0x01, 0x31);\r
+       addToMapW(0xd5, 0x01, 0x47);\r
+       addToMapW(0xd5, 0x01, 0x48);\r
+       addToMapW(0xd5, 0x01, 0xA0);\r
+       addToMapW(0xd5, 0x01, 0xA1);\r
+       addToMapW(0xd5, 0x04, 0x1D);\r
+       addToMapW(0xd5, 0x04, 0x3D);\r
+       addToMapW(0xd5, 0x0E, 0x35);\r
+       addToMapW(0xd5, 0x25, 0x52);\r
+       addToMapW(0xd5, 0xF8, 0xBB);\r
+       addToMapW(0xd5, 0xFF, 0x95);\r
+       addToMapW(0xd6, 0x00, 0xCD);\r
+       addToMapW(0xd6, 0x00, 0xD6);\r
+       addToMapW(0xd6, 0x00, 0xED);\r
+       addToMapW(0xd6, 0x00, 0xF6);\r
+       addToMapW(0xd6, 0x0E, 0x36);\r
+       addToMapW(0xd6, 0x25, 0x53);\r
+       addToMapW(0xd6, 0xFF, 0x96);\r
+       addToMapW(0xd7, 0x00, 0xCE);\r
+       addToMapW(0xd7, 0x00, 0xD7);\r
+       addToMapW(0xd7, 0x00, 0xEE);\r
+       addToMapW(0xd7, 0x04, 0x1E);\r
+       addToMapW(0xd7, 0x04, 0x3E);\r
+       addToMapW(0xd7, 0x0E, 0x37);\r
+       addToMapW(0xd7, 0x25, 0x6B);\r
+       addToMapW(0xd7, 0xFF, 0x97);\r
+       addToMapW(0xd8, 0x00, 0xCF);\r
+       addToMapW(0xd8, 0x00, 0xD8);\r
+       addToMapW(0xd8, 0x00, 0xEF);\r
+       addToMapW(0xd8, 0x00, 0xF8);\r
+       addToMapW(0xd8, 0x0E, 0x38);\r
+       addToMapW(0xd8, 0x20, 0x21);\r
+       addToMapW(0xd8, 0x25, 0x6A);\r
+       addToMapW(0xd8, 0xFF, 0x98);\r
+       addToMapW(0xd9, 0x00, 0xD9);\r
+       addToMapW(0xd9, 0x00, 0xF9);\r
+       addToMapW(0xd9, 0x0E, 0x39);\r
+       addToMapW(0xd9, 0x25, 0x18);\r
+       addToMapW(0xd9, 0xFF, 0x99);\r
+       addToMapW(0xda, 0x00, 0xDA);\r
+       addToMapW(0xda, 0x00, 0xFA);\r
+       addToMapW(0xda, 0x0E, 0x3A);\r
+       addToMapW(0xda, 0x25, 0x0C);\r
+       addToMapW(0xda, 0xFF, 0x9A);\r
+       addToMapW(0xdb, 0x00, 0xDB);\r
+       addToMapW(0xdb, 0x00, 0xFB);\r
+       addToMapW(0xdb, 0x25, 0x88);\r
+       addToMapW(0xdb, 0x25, 0x8C);\r
+       addToMapW(0xdb, 0x25, 0x90);\r
+       addToMapW(0xdb, 0xF8, 0xC1);\r
+       addToMapW(0xdb, 0xFF, 0x9B);\r
+       addToMapW(0xdc, 0x00, 0xDC);\r
+       addToMapW(0xdc, 0x00, 0xFC);\r
+       addToMapW(0xdc, 0x25, 0x84);\r
+       addToMapW(0xdc, 0xF8, 0xC2);\r
+       addToMapW(0xdc, 0xFF, 0x9C);\r
+       addToMapW(0xdd, 0x00, 0xA6);\r
+       addToMapW(0xdd, 0x01, 0x62);\r
+       addToMapW(0xdd, 0x01, 0x63);\r
+       addToMapW(0xdd, 0x01, 0xAF);\r
+       addToMapW(0xdd, 0x01, 0xB0);\r
+       addToMapW(0xdd, 0x04, 0x1F);\r
+       addToMapW(0xdd, 0x04, 0x3F);\r
+       addToMapW(0xdd, 0x25, 0x8C);\r
+       addToMapW(0xdd, 0xF8, 0xC3);\r
+       addToMapW(0xdd, 0xFF, 0x9D);\r
+       addToMapW(0xde, 0x00, 0xCC);\r
+       addToMapW(0xde, 0x00, 0xEC);\r
+       addToMapW(0xde, 0x01, 0x6E);\r
+       addToMapW(0xde, 0x01, 0x6F);\r
+       addToMapW(0xde, 0x03, 0x03);\r
+       addToMapW(0xde, 0x25, 0x90);\r
+       addToMapW(0xde, 0xF8, 0xC4);\r
+       addToMapW(0xde, 0xFF, 0x9E);\r
+       addToMapW(0xdf, 0x00, 0xDF);\r
+       addToMapW(0xdf, 0x0E, 0x3F);\r
+       addToMapW(0xdf, 0x25, 0x80);\r
+       addToMapW(0xdf, 0xFF, 0x9F);\r
+       addToMapW(0xe0, 0x00, 0xD3);\r
+       addToMapW(0xe0, 0x00, 0xF3);\r
+       addToMapW(0xe0, 0x03, 0x91);\r
+       addToMapW(0xe0, 0x03, 0xB1);\r
+       addToMapW(0xe0, 0x04, 0x2F);\r
+       addToMapW(0xe0, 0x04, 0x4F);\r
+       addToMapW(0xe0, 0x06, 0x36);\r
+       addToMapW(0xe0, 0x0E, 0x40);\r
+       addToMapW(0xe0, 0xFE, 0xBD);\r
+       addToMapW(0xe0, 0xFE, 0xBE);\r
+       addToMapW(0xe0, 0xFE, 0xBF);\r
+       addToMapW(0xe0, 0xFE, 0xC0);\r
+       addToMapW(0xe1, 0x00, 0xDF);\r
+       addToMapW(0xe1, 0x03, 0xB2);\r
+       addToMapW(0xe1, 0x06, 0x37);\r
+       addToMapW(0xe1, 0x0E, 0x41);\r
+       addToMapW(0xe1, 0xFE, 0xC1);\r
+       addToMapW(0xe1, 0xFE, 0xC2);\r
+       addToMapW(0xe1, 0xFE, 0xC3);\r
+       addToMapW(0xe1, 0xFE, 0xC4);\r
+       addToMapW(0xe2, 0x00, 0xD4);\r
+       addToMapW(0xe2, 0x00, 0xF4);\r
+       addToMapW(0xe2, 0x01, 0x4C);\r
+       addToMapW(0xe2, 0x01, 0x4D);\r
+       addToMapW(0xe2, 0x03, 0x93);\r
+       addToMapW(0xe2, 0x04, 0x20);\r
+       addToMapW(0xe2, 0x04, 0x40);\r
+       addToMapW(0xe2, 0x06, 0x38);\r
+       addToMapW(0xe2, 0x0E, 0x42);\r
+       addToMapW(0xe2, 0xFE, 0xC5);\r
+       addToMapW(0xe2, 0xFE, 0xC6);\r
+       addToMapW(0xe2, 0xFE, 0xC7);\r
+       addToMapW(0xe2, 0xFE, 0xC8);\r
+       addToMapW(0xe3, 0x00, 0xD2);\r
+       addToMapW(0xe3, 0x00, 0xF2);\r
+       addToMapW(0xe3, 0x01, 0x43);\r
+       addToMapW(0xe3, 0x01, 0x44);\r
+       addToMapW(0xe3, 0x03, 0xA0);\r
+       addToMapW(0xe3, 0x03, 0xC0);\r
+       addToMapW(0xe3, 0x06, 0x39);\r
+       addToMapW(0xe3, 0x0E, 0x43);\r
+       addToMapW(0xe3, 0xFE, 0xC9);\r
+       addToMapW(0xe3, 0xFE, 0xCA);\r
+       addToMapW(0xe3, 0xFE, 0xCB);\r
+       addToMapW(0xe3, 0xFE, 0xCC);\r
+       addToMapW(0xe4, 0x01, 0xA9);\r
+       addToMapW(0xe4, 0x03, 0xA3);\r
+       addToMapW(0xe4, 0x03, 0xC3);\r
+       addToMapW(0xe4, 0x04, 0x21);\r
+       addToMapW(0xe4, 0x04, 0x41);\r
+       addToMapW(0xe4, 0x06, 0x3A);\r
+       addToMapW(0xe4, 0x0E, 0x44);\r
+       addToMapW(0xe4, 0x22, 0x11);\r
+       addToMapW(0xe4, 0xFE, 0xCD);\r
+       addToMapW(0xe4, 0xFE, 0xCE);\r
+       addToMapW(0xe4, 0xFE, 0xCF);\r
+       addToMapW(0xe4, 0xFE, 0xD0);\r
+       addToMapW(0xe5, 0x00, 0xD5);\r
+       addToMapW(0xe5, 0x00, 0xF5);\r
+       addToMapW(0xe5, 0x06, 0x41);\r
+       addToMapW(0xe5, 0x0E, 0x45);\r
+       addToMapW(0xe5, 0xFE, 0xD1);\r
+       addToMapW(0xe5, 0xFE, 0xD2);\r
+       addToMapW(0xe5, 0xFE, 0xD3);\r
+       addToMapW(0xe5, 0xFE, 0xD4);\r
+       addToMapW(0xe6, 0x00, 0xB5);\r
+       addToMapW(0xe6, 0x01, 0x60);\r
+       addToMapW(0xe6, 0x01, 0x61);\r
+       addToMapW(0xe6, 0x03, 0xBC);\r
+       addToMapW(0xe6, 0x04, 0x22);\r
+       addToMapW(0xe6, 0x04, 0x42);\r
+       addToMapW(0xe6, 0x0E, 0x46);\r
+       addToMapW(0xe7, 0x03, 0xA4);\r
+       addToMapW(0xe7, 0x03, 0xC4);\r
+       addToMapW(0xe7, 0x06, 0x42);\r
+       addToMapW(0xe7, 0x0E, 0x47);\r
+       addToMapW(0xe7, 0xF8, 0xBC);\r
+       addToMapW(0xe7, 0xFE, 0xD5);\r
+       addToMapW(0xe7, 0xFE, 0xD6);\r
+       addToMapW(0xe7, 0xFE, 0xD7);\r
+       addToMapW(0xe7, 0xFE, 0xD8);\r
+       addToMapW(0xe8, 0x00, 0xD7);\r
+       addToMapW(0xe8, 0x00, 0xDE);\r
+       addToMapW(0xe8, 0x00, 0xFE);\r
+       addToMapW(0xe8, 0x01, 0x36);\r
+       addToMapW(0xe8, 0x01, 0x37);\r
+       addToMapW(0xe8, 0x01, 0x54);\r
+       addToMapW(0xe8, 0x01, 0x55);\r
+       addToMapW(0xe8, 0x02, 0x78);\r
+       addToMapW(0xe8, 0x03, 0xA6);\r
+       addToMapW(0xe8, 0x03, 0xC6);\r
+       addToMapW(0xe8, 0x04, 0x23);\r
+       addToMapW(0xe8, 0x04, 0x43);\r
+       addToMapW(0xe8, 0x06, 0x43);\r
+       addToMapW(0xe8, 0x0E, 0x48);\r
+       addToMapW(0xe8, 0x22, 0x05);\r
+       addToMapW(0xe8, 0xFE, 0xD9);\r
+       addToMapW(0xe8, 0xFE, 0xDA);\r
+       addToMapW(0xe8, 0xFE, 0xDB);\r
+       addToMapW(0xe8, 0xFE, 0xDC);\r
+       addToMapW(0xe9, 0x00, 0xDA);\r
+       addToMapW(0xe9, 0x00, 0xFA);\r
+       addToMapW(0xe9, 0x03, 0x98);\r
+       addToMapW(0xe9, 0x06, 0x44);\r
+       addToMapW(0xe9, 0x0E, 0x49);\r
+       addToMapW(0xe9, 0xFE, 0xDD);\r
+       addToMapW(0xe9, 0xFE, 0xDE);\r
+       addToMapW(0xe9, 0xFE, 0xDF);\r
+       addToMapW(0xe9, 0xFE, 0xE0);\r
+       addToMapW(0xea, 0x00, 0xDB);\r
+       addToMapW(0xea, 0x00, 0xFB);\r
+       addToMapW(0xea, 0x01, 0x3B);\r
+       addToMapW(0xea, 0x01, 0x3C);\r
+       addToMapW(0xea, 0x03, 0x86);\r
+       addToMapW(0xea, 0x03, 0xA9);\r
+       addToMapW(0xea, 0x03, 0xAC);\r
+       addToMapW(0xea, 0x04, 0x16);\r
+       addToMapW(0xea, 0x04, 0x36);\r
+       addToMapW(0xea, 0x06, 0x45);\r
+       addToMapW(0xea, 0x0E, 0x4A);\r
+       addToMapW(0xea, 0x21, 0x26);\r
+       addToMapW(0xea, 0xFE, 0xE1);\r
+       addToMapW(0xea, 0xFE, 0xE2);\r
+       addToMapW(0xea, 0xFE, 0xE3);\r
+       addToMapW(0xea, 0xFE, 0xE4);\r
+       addToMapW(0xeb, 0x00, 0xD9);\r
+       addToMapW(0xeb, 0x00, 0xF9);\r
+       addToMapW(0xeb, 0x01, 0x70);\r
+       addToMapW(0xeb, 0x01, 0x71);\r
+       addToMapW(0xeb, 0x03, 0x88);\r
+       addToMapW(0xeb, 0x03, 0x94);\r
+       addToMapW(0xeb, 0x03, 0xAD);\r
+       addToMapW(0xeb, 0x03, 0xB4);\r
+       addToMapW(0xeb, 0x06, 0x46);\r
+       addToMapW(0xeb, 0x0E, 0x4B);\r
+       addToMapW(0xeb, 0xFE, 0xE5);\r
+       addToMapW(0xeb, 0xFE, 0xE6);\r
+       addToMapW(0xeb, 0xFE, 0xE7);\r
+       addToMapW(0xeb, 0xFE, 0xE8);\r
+       addToMapW(0xec, 0x03, 0x01);\r
+       addToMapW(0xec, 0x03, 0x89);\r
+       addToMapW(0xec, 0x03, 0xAE);\r
+       addToMapW(0xec, 0x04, 0x12);\r
+       addToMapW(0xec, 0x04, 0x32);\r
+       addToMapW(0xec, 0x06, 0x47);\r
+       addToMapW(0xec, 0x0E, 0x4C);\r
+       addToMapW(0xec, 0x22, 0x1E);\r
+       addToMapW(0xec, 0xFE, 0xE9);\r
+       addToMapW(0xec, 0xFE, 0xEA);\r
+       addToMapW(0xec, 0xFE, 0xEB);\r
+       addToMapW(0xec, 0xFE, 0xEC);\r
+       addToMapW(0xed, 0x00, 0xDD);\r
+       addToMapW(0xed, 0x00, 0xFD);\r
+       addToMapW(0xed, 0x01, 0x12);\r
+       addToMapW(0xed, 0x01, 0x13);\r
+       addToMapW(0xed, 0x03, 0x8A);\r
+       addToMapW(0xed, 0x03, 0xAF);\r
+       addToMapW(0xed, 0x06, 0x48);\r
+       addToMapW(0xed, 0x0E, 0x4D);\r
+       addToMapW(0xed, 0xFE, 0xED);\r
+       addToMapW(0xed, 0xFE, 0xEE);\r
+       addToMapW(0xee, 0x00, 0xAF);\r
+       addToMapW(0xee, 0x01, 0x45);\r
+       addToMapW(0xee, 0x01, 0x46);\r
+       addToMapW(0xee, 0x03, 0x04);\r
+       addToMapW(0xee, 0x03, 0x05);\r
+       addToMapW(0xee, 0x03, 0x8C);\r
+       addToMapW(0xee, 0x03, 0x95);\r
+       addToMapW(0xee, 0x03, 0xB5);\r
+       addToMapW(0xee, 0x03, 0xCC);\r
+       addToMapW(0xee, 0x04, 0x2C);\r
+       addToMapW(0xee, 0x04, 0x4C);\r
+       addToMapW(0xee, 0x06, 0x49);\r
+       addToMapW(0xee, 0x0E, 0x4E);\r
+       addToMapW(0xee, 0xFE, 0xEF);\r
+       addToMapW(0xee, 0xFE, 0xF0);\r
+       addToMapW(0xef, 0x00, 0xB4);\r
+       addToMapW(0xef, 0x02, 0xB9);\r
+       addToMapW(0xef, 0x02, 0xCA);\r
+       addToMapW(0xef, 0x03, 0x01);\r
+       addToMapW(0xef, 0x03, 0x8E);\r
+       addToMapW(0xef, 0x03, 0xCD);\r
+       addToMapW(0xef, 0x06, 0x4A);\r
+       addToMapW(0xef, 0x0E, 0x4F);\r
+       addToMapW(0xef, 0x20, 0x19);\r
+       addToMapW(0xef, 0x20, 0x32);\r
+       addToMapW(0xef, 0x20, 0x35);\r
+       addToMapW(0xef, 0x21, 0x16);\r
+       addToMapW(0xef, 0x22, 0x29);\r
+       addToMapW(0xef, 0xFE, 0xF1);\r
+       addToMapW(0xef, 0xFE, 0xF2);\r
+       addToMapW(0xef, 0xFE, 0xF3);\r
+       addToMapW(0xef, 0xFE, 0xF4);\r
+       addToMapW(0xf0, 0x00, 0xAD);\r
+       addToMapW(0xf0, 0x03, 0x8F);\r
+       addToMapW(0xf0, 0x03, 0xCE);\r
+       addToMapW(0xf0, 0x04, 0x01);\r
+       addToMapW(0xf0, 0x04, 0x51);\r
+       addToMapW(0xf0, 0x0E, 0x50);\r
+       addToMapW(0xf0, 0x22, 0x61);\r
+       addToMapW(0xf1, 0x00, 0xB1);\r
+       addToMapW(0xf1, 0x02, 0xDD);\r
+       addToMapW(0xf1, 0x06, 0x4B);\r
+       addToMapW(0xf1, 0x0E, 0x51);\r
+       addToMapW(0xf1, 0x22, 0x13);\r
+       addToMapW(0xf1, 0xFE, 0x70);\r
+       addToMapW(0xf1, 0xFE, 0x71);\r
+       addToMapW(0xf2, 0x02, 0xDB);\r
+       addToMapW(0xf2, 0x03, 0x23);\r
+       addToMapW(0xf2, 0x04, 0x04);\r
+       addToMapW(0xf2, 0x04, 0x2B);\r
+       addToMapW(0xf2, 0x04, 0x4B);\r
+       addToMapW(0xf2, 0x04, 0x54);\r
+       addToMapW(0xf2, 0x06, 0x4C);\r
+       addToMapW(0xf2, 0x0E, 0x52);\r
+       addToMapW(0xf2, 0x20, 0x17);\r
+       addToMapW(0xf2, 0x20, 0x1C);\r
+       addToMapW(0xf2, 0x22, 0x65);\r
+       addToMapW(0xf2, 0xF8, 0xBD);\r
+       addToMapW(0xf2, 0xFE, 0x72);\r
+       addToMapW(0xf3, 0x00, 0xBE);\r
+       addToMapW(0xf3, 0x02, 0xC7);\r
+       addToMapW(0xf3, 0x03, 0x0C);\r
+       addToMapW(0xf3, 0x06, 0x4D);\r
+       addToMapW(0xf3, 0x0E, 0x53);\r
+       addToMapW(0xf3, 0x22, 0x64);\r
+       addToMapW(0xf3, 0xFE, 0x74);\r
+       addToMapW(0xf4, 0x00, 0xB6);\r
+       addToMapW(0xf4, 0x02, 0xD8);\r
+       addToMapW(0xf4, 0x03, 0x06);\r
+       addToMapW(0xf4, 0x03, 0xAA);\r
+       addToMapW(0xf4, 0x03, 0xCA);\r
+       addToMapW(0xf4, 0x04, 0x07);\r
+       addToMapW(0xf4, 0x04, 0x17);\r
+       addToMapW(0xf4, 0x04, 0x37);\r
+       addToMapW(0xf4, 0x04, 0x57);\r
+       addToMapW(0xf4, 0x06, 0x4E);\r
+       addToMapW(0xf4, 0x0E, 0x54);\r
+       addToMapW(0xf4, 0x23, 0x20);\r
+       addToMapW(0xf4, 0xFE, 0x76);\r
+       addToMapW(0xf4, 0xFE, 0x77);\r
+       addToMapW(0xf5, 0x00, 0xA7);\r
+       addToMapW(0xf5, 0x03, 0xAB);\r
+       addToMapW(0xf5, 0x03, 0xCB);\r
+       addToMapW(0xf5, 0x06, 0x4F);\r
+       addToMapW(0xf5, 0x0E, 0x55);\r
+       addToMapW(0xf5, 0x23, 0x21);\r
+       addToMapW(0xf5, 0xFE, 0x78);\r
+       addToMapW(0xf5, 0xFE, 0x79);\r
+       addToMapW(0xf6, 0x00, 0xF7);\r
+       addToMapW(0xf6, 0x04, 0x0E);\r
+       addToMapW(0xf6, 0x04, 0x28);\r
+       addToMapW(0xf6, 0x04, 0x48);\r
+       addToMapW(0xf6, 0x04, 0x5E);\r
+       addToMapW(0xf6, 0x06, 0x50);\r
+       addToMapW(0xf6, 0x0E, 0x56);\r
+       addToMapW(0xf6, 0xFE, 0x7A);\r
+       addToMapW(0xf6, 0xFE, 0x7B);\r
+       addToMapW(0xf7, 0x00, 0xB8);\r
+       addToMapW(0xf7, 0x00, 0xF7);\r
+       addToMapW(0xf7, 0x02, 0xDB);\r
+       addToMapW(0xf7, 0x03, 0x27);\r
+       addToMapW(0xf7, 0x0E, 0x57);\r
+       addToMapW(0xf7, 0x20, 0x1E);\r
+       addToMapW(0xf7, 0x22, 0x48);\r
+       addToMapW(0xf8, 0x00, 0xB0);\r
+       addToMapW(0xf8, 0x02, 0xDA);\r
+       addToMapW(0xf8, 0x03, 0x0A);\r
+       addToMapW(0xf8, 0x04, 0x2D);\r
+       addToMapW(0xf8, 0x04, 0x4D);\r
+       addToMapW(0xf8, 0x0E, 0x58);\r
+       addToMapW(0xf8, 0x20, 0x70);\r
+       addToMapW(0xf8, 0x22, 0x18);\r
+       addToMapW(0xf9, 0x00, 0xA8);\r
+       addToMapW(0xf9, 0x02, 0xDD);\r
+       addToMapW(0xf9, 0x03, 0x08);\r
+       addToMapW(0xf9, 0x0E, 0x59);\r
+       addToMapW(0xf9, 0x22, 0x19);\r
+       addToMapW(0xfa, 0x00, 0xB7);\r
+       addToMapW(0xfa, 0x02, 0xD9);\r
+       addToMapW(0xfa, 0x03, 0x07);\r
+       addToMapW(0xfa, 0x04, 0x29);\r
+       addToMapW(0xfa, 0x04, 0x49);\r
+       addToMapW(0xfa, 0x0E, 0x5A);\r
+       addToMapW(0xfa, 0x20, 0x24);\r
+       addToMapW(0xfa, 0x22, 0xC5);\r
+       addToMapW(0xfa, 0x30, 0xFB);\r
+       addToMapW(0xfb, 0x00, 0xB9);\r
+       addToMapW(0xfb, 0x0E, 0x5B);\r
+       addToMapW(0xfb, 0x20, 0x81);\r
+       addToMapW(0xfb, 0x22, 0x1A);\r
+       addToMapW(0xfb, 0x27, 0x13);\r
+       addToMapW(0xfc, 0x00, 0xB3);\r
+       addToMapW(0xfc, 0x01, 0x58);\r
+       addToMapW(0xfc, 0x01, 0x59);\r
+       addToMapW(0xfc, 0x04, 0x27);\r
+       addToMapW(0xfc, 0x04, 0x47);\r
+       addToMapW(0xfc, 0x20, 0x7F);\r
+       addToMapW(0xfc, 0x20, 0x83);\r
+       addToMapW(0xfc, 0x21, 0x16);\r
+       addToMapW(0xfc, 0xF8, 0xC5);\r
+       addToMapW(0xfd, 0x00, 0xA4);\r
+       addToMapW(0xfd, 0x00, 0xA7);\r
+       addToMapW(0xfd, 0x00, 0xB2);\r
+       addToMapW(0xfd, 0x20, 0x82);\r
+       addToMapW(0xfd, 0xF8, 0xC6);\r
+       addToMapW(0xfd, 0xF8, 0xF1);\r
+       addToMapW(0xfe, 0x20, 0xAB);\r
+       addToMapW(0xfe, 0x25, 0xA0);\r
+       addToMapW(0xfe, 0xF8, 0xC7);\r
+       addToMapW(0xfe, 0xF8, 0xF2);\r
+       addToMapW(0xff, 0x00, 0xA0);\r
+       addToMapW(0xff, 0xF8, 0xC8);\r
+       addToMapW(0xff, 0xF8, 0xF3);\r
+}\r
index cb11c7ee67d473f544b4254066659e968001b78d..34ae50e359604a8606d5d6b10729a58eae5d8629 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright Bitweasil
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- *
- * This code implements the MD4 message-digest algorithm.
- * "Just the reference implementation, single stage. Hardly "optimized." Though a good bit faster than libssl's MD4, as it isn't doing nearly the same amount of work." - Bitweasil
- * 
- * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke
- */
-
-
-//#include <cstdlib>
-//#include <cstring>
-#include "md4.h"
-
-/* MD4 Defines as per RFC reference implementation */
-#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
-#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
-#define H(x, y, z) ((x) ^ (y) ^ (z))
-#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
-#define FF(a, b, c, d, x, s) { \
-               (a) += F ((b), (c), (d)) + (x); \
-               (a) = ROTATE_LEFT ((a), (s)); \
-       }
-#define GG(a, b, c, d, x, s) { \
-               (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
-               (a) = ROTATE_LEFT ((a), (s)); \
-       }
-#define HH(a, b, c, d, x, s) { \
-               (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
-               (a) = ROTATE_LEFT ((a), (s)); \
-       }
-#define S11 3
-#define S12 7
-#define S13 11
-#define S14 19
-#define S21 3
-#define S22 5
-#define S23 9
-#define S24 13
-#define S31 3
-#define S32 9
-#define S33 11
-#define S34 15
-/* End MD4 Defines */
-
-void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
-{
-       // access data as 4-byte word
-       #define uData                           ((UINT4 *)pData)
-       #define uDigest                         ((UINT4 *)pDigest)
-
-       // pad word and append bit at appropriate location
-       #define MD4_pad_w0()            (0x00000080)
-       #define MD4_pad_w1(data)        (((data) & 0x000000FF) | 0x00008000)
-       #define MD4_pad_w2(data)        (((data) & 0x0000FFFF) | 0x00800000)
-       #define MD4_pad_w3(data)        (((data) & 0x00FFFFFF) | 0x80000000)
-
-       // For the hash working space
-       //__attribute__((aligned(16))) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-       //__declspec(align(16)) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-       UINT4 data[MD4_DIGEST_LENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
-       // For the output result
-       UINT4 a,b,c,d;
-
-       switch (length)
-       {
-               case 0:
-               {
-                       data[ 0] = MD4_pad_w0();
-
-                       data[14] = 0;
-               }
-               break;
-               case 1:
-               {
-                       data[ 0] = MD4_pad_w1(uData[0]);
-
-                       data[14] = 1 << 3;
-               }
-               break;
-               case 2:
-               {
-                       data[ 0] = MD4_pad_w2(uData[0]);
-
-                       data[14] = 2 << 3;
-               }
-               break;
-               case 3:
-               {
-                       data[ 0] = MD4_pad_w3(uData[0]);
-
-                       data[14] = 3 << 3;
-               }
-               break;
-               case 4:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = MD4_pad_w0();
-
-                       data[14] = 4 << 3;
-               }
-               break;
-               case 5:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = MD4_pad_w1(uData[1]);
-
-                       data[14] = 5 << 3;
-               }
-               break;
-               case 6:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = MD4_pad_w2(uData[1]);
-
-                       data[14] = 6 << 3;
-               }
-               break;
-               case 7:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = MD4_pad_w3(uData[1]);
-
-                       data[14] = 7 << 3;
-               }
-               break;
-               case 8:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = MD4_pad_w0();
-
-                       data[14] = 8 << 3;
-               }
-               break;
-               case 9:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = MD4_pad_w1(uData[2]);
-
-                       data[14] = 9 << 3;
-               }
-               break;
-               case 10:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = MD4_pad_w2(uData[2]);
-
-                       data[14] = 10 << 3;
-               }
-               break;
-               case 11:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = MD4_pad_w3(uData[2]);
-
-                       data[14] = 11 << 3;
-               }
-               break;
-               case 12:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = uData[2];
-                       data[ 3] = MD4_pad_w0();
-
-                       data[14] = 12 << 3;
-               }
-               break;
-               case 13:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = uData[2];
-                       data[ 3] = MD4_pad_w1(uData[3]);
-
-                       data[14] = 13 << 3;
-               }
-               break;
-               case 14:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = uData[2];
-                       data[ 3] = MD4_pad_w2(uData[3]);
-
-                       data[14] = 14 << 3;
-               }
-               break;
-               case 15:
-               {
-                       data[ 0] = uData[0];
-                       data[ 1] = uData[1];
-                       data[ 2] = uData[2];
-                       data[ 3] = MD4_pad_w3(uData[3]);
-
-                       data[14] = 15 << 3;
-               }
-               break;
-
-               default:
-               {
-                       length = length % 32; // lenght >= 32 not suported
-
-                       int word = length >> 2;
-
-                       int i = 0;
-                       while (i < word) {
-                               data[i] = uData[i];
-                               i++;
-                       }
-
-                       switch (length & 0x3) {
-                               case 0:
-                               {
-                                       data[word] = MD4_pad_w0();
-                               }
-                               break;
-                               case 1:
-                               {
-                                       data[word] = MD4_pad_w1(uData[word]);
-                               }
-                               break;
-                               case 2:
-                               {
-                                       data[word] = MD4_pad_w2(uData[word]);
-                               }
-                               break;
-                               case 3:
-                               {
-                                       data[word] = MD4_pad_w3(uData[word]);
-                               }
-                               break;
-                       }
-
-                       data[14] = length << 3;
-               }
-               break;
-       }
-
-       a = 0x67452301;
-       b = 0xefcdab89;
-       c = 0x98badcfe;
-       d = 0x10325476;
-
-       /* Round 1 */
-       FF (a, b, c, d, data[ 0], S11); /* 1 */
-       FF (d, a, b, c, data[ 1], S12); /* 2 */
-       FF (c, d, a, b, data[ 2], S13); /* 3 */
-       FF (b, c, d, a, data[ 3], S14); /* 4 */
-       FF (a, b, c, d, data[ 4], S11); /* 5 */
-       FF (d, a, b, c, data[ 5], S12); /* 6 */
-       FF (c, d, a, b, data[ 6], S13); /* 7 */
-       FF (b, c, d, a, data[ 7], S14); /* 8 */
-       FF (a, b, c, d,        0, S11); /* 9 */
-       FF (d, a, b, c,        0, S12); /* 10 */
-       FF (c, d, a, b,        0, S13); /* 11 */
-       FF (b, c, d, a,        0, S14); /* 12 */
-       FF (a, b, c, d,        0, S11); /* 13 */
-       FF (d, a, b, c,        0, S12); /* 14 */
-       FF (c, d, a, b, data[14], S13); /* 15 */
-       FF (b, c, d, a,        0, S14); /* 16 */
-
-       /* Round 2 */
-       GG (a, b, c, d, data[ 0], S21); /* 17 */
-       GG (d, a, b, c, data[ 4], S22); /* 18 */
-       GG (c, d, a, b,        0, S23); /* 19 */
-       GG (b, c, d, a,        0, S24); /* 20 */
-       GG (a, b, c, d, data[ 1], S21); /* 21 */
-       GG (d, a, b, c, data[ 5], S22); /* 22 */
-       GG (c, d, a, b,        0, S23); /* 23 */
-       GG (b, c, d, a,        0, S24); /* 24 */
-       GG (a, b, c, d, data[ 2], S21); /* 25 */
-       GG (d, a, b, c, data[ 6], S22); /* 26 */
-       GG (c, d, a, b,        0, S23); /* 27 */
-       GG (b, c, d, a, data[14], S24); /* 28 */
-       GG (a, b, c, d, data[ 3], S21); /* 29 */
-       GG (d, a, b, c, data[ 7], S22); /* 30 */
-       GG (c, d, a, b,        0, S23); /* 31 */
-       GG (b, c, d, a,        0, S24); /* 32 */
-
-       /* Round 3 */
-       HH (a, b, c, d, data[ 0], S31); /* 33 */
-       HH (d, a, b, c,        0, S32); /* 34 */
-       HH (c, d, a, b, data[ 4], S33); /* 35 */
-       HH (b, c, d, a,        0, S34); /* 36 */
-       HH (a, b, c, d, data[ 2], S31); /* 37 */
-       HH (d, a, b, c,        0, S32); /* 38 */
-       HH (c, d, a, b, data[ 6], S33); /* 39 */
-       HH (b, c, d, a, data[14], S34); /* 40 */
-       HH (a, b, c, d, data[ 1], S31); /* 41 */
-       HH (d, a, b, c,        0, S32); /* 42 */
-       HH (c, d, a, b, data[ 5], S33); /* 43 */
-       HH (b, c, d, a,        0, S34); /* 44 */
-       HH (a, b, c, d, data[ 3], S31); /* 45 */
-       HH (d, a, b, c,        0, S32); /* 46 */
-       HH (c, d, a, b, data[ 7], S33); /* 47 */
-       HH (b, c, d, a,        0, S34); /* 48 */
-
-       // Finally, add initial values, as this is the only pass we make.
-       a += 0x67452301;
-       b += 0xefcdab89;
-       c += 0x98badcfe;
-       d += 0x10325476;
-
-       uDigest[0] = a;
-       uDigest[1] = b;
-       uDigest[2] = c;
-       uDigest[3] = d;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright Bitweasil\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ *\r
+ * This code implements the MD4 message-digest algorithm.\r
+ * "Just the reference implementation, single stage. Hardly "optimized." Though a good bit faster than libssl's MD4, as it isn't doing nearly the same amount of work." - Bitweasil\r
+ * \r
+ * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke\r
+ */\r
+\r
+\r
+//#include <cstdlib>\r
+//#include <cstring>\r
+#include "md4.h"\r
+\r
+/* MD4 Defines as per RFC reference implementation */\r
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))\r
+#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))\r
+#define H(x, y, z) ((x) ^ (y) ^ (z))\r
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))\r
+#define FF(a, b, c, d, x, s) { \\r
+               (a) += F ((b), (c), (d)) + (x); \\r
+               (a) = ROTATE_LEFT ((a), (s)); \\r
+       }\r
+#define GG(a, b, c, d, x, s) { \\r
+               (a) += G ((b), (c), (d)) + (x) + (uint32)0x5a827999; \\r
+               (a) = ROTATE_LEFT ((a), (s)); \\r
+       }\r
+#define HH(a, b, c, d, x, s) { \\r
+               (a) += H ((b), (c), (d)) + (x) + (uint32)0x6ed9eba1; \\r
+               (a) = ROTATE_LEFT ((a), (s)); \\r
+       }\r
+#define S11 3\r
+#define S12 7\r
+#define S13 11\r
+#define S14 19\r
+#define S21 3\r
+#define S22 5\r
+#define S23 9\r
+#define S24 13\r
+#define S31 3\r
+#define S32 9\r
+#define S33 11\r
+#define S34 15\r
+/* End MD4 Defines */\r
+\r
+void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)\r
+{\r
+       // access data as 4-byte word\r
+       #define uData                           ((uint32 *)pData)\r
+       #define uDigest                         ((uint32 *)pDigest)\r
+\r
+       // pad word and append bit at appropriate location\r
+       #define MD4_pad_w0()            (0x00000080)\r
+       #define MD4_pad_w1(data)        (((data) & 0x000000FF) | 0x00008000)\r
+       #define MD4_pad_w2(data)        (((data) & 0x0000FFFF) | 0x00800000)\r
+       #define MD4_pad_w3(data)        (((data) & 0x00FFFFFF) | 0x80000000)\r
+\r
+       // For the hash working space\r
+       //__attribute__((aligned(16))) uint32 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
+       //__declspec(align(16)) uint32 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
+       uint32 data[MD4_DIGEST_LENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};\r
+\r
+       // For the output result\r
+       uint32 a,b,c,d;\r
+\r
+       switch (length)\r
+       {\r
+               case 0:\r
+               {\r
+                       data[ 0] = MD4_pad_w0();\r
+\r
+                       data[14] = 0;\r
+               }\r
+               break;\r
+               case 1:\r
+               {\r
+                       data[ 0] = MD4_pad_w1(uData[0]);\r
+\r
+                       data[14] = 1 << 3;\r
+               }\r
+               break;\r
+               case 2:\r
+               {\r
+                       data[ 0] = MD4_pad_w2(uData[0]);\r
+\r
+                       data[14] = 2 << 3;\r
+               }\r
+               break;\r
+               case 3:\r
+               {\r
+                       data[ 0] = MD4_pad_w3(uData[0]);\r
+\r
+                       data[14] = 3 << 3;\r
+               }\r
+               break;\r
+               case 4:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = MD4_pad_w0();\r
+\r
+                       data[14] = 4 << 3;\r
+               }\r
+               break;\r
+               case 5:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = MD4_pad_w1(uData[1]);\r
+\r
+                       data[14] = 5 << 3;\r
+               }\r
+               break;\r
+               case 6:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = MD4_pad_w2(uData[1]);\r
+\r
+                       data[14] = 6 << 3;\r
+               }\r
+               break;\r
+               case 7:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = MD4_pad_w3(uData[1]);\r
+\r
+                       data[14] = 7 << 3;\r
+               }\r
+               break;\r
+               case 8:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = MD4_pad_w0();\r
+\r
+                       data[14] = 8 << 3;\r
+               }\r
+               break;\r
+               case 9:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = MD4_pad_w1(uData[2]);\r
+\r
+                       data[14] = 9 << 3;\r
+               }\r
+               break;\r
+               case 10:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = MD4_pad_w2(uData[2]);\r
+\r
+                       data[14] = 10 << 3;\r
+               }\r
+               break;\r
+               case 11:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = MD4_pad_w3(uData[2]);\r
+\r
+                       data[14] = 11 << 3;\r
+               }\r
+               break;\r
+               case 12:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = uData[2];\r
+                       data[ 3] = MD4_pad_w0();\r
+\r
+                       data[14] = 12 << 3;\r
+               }\r
+               break;\r
+               case 13:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = uData[2];\r
+                       data[ 3] = MD4_pad_w1(uData[3]);\r
+\r
+                       data[14] = 13 << 3;\r
+               }\r
+               break;\r
+               case 14:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = uData[2];\r
+                       data[ 3] = MD4_pad_w2(uData[3]);\r
+\r
+                       data[14] = 14 << 3;\r
+               }\r
+               break;\r
+               case 15:\r
+               {\r
+                       data[ 0] = uData[0];\r
+                       data[ 1] = uData[1];\r
+                       data[ 2] = uData[2];\r
+                       data[ 3] = MD4_pad_w3(uData[3]);\r
+\r
+                       data[14] = 15 << 3;\r
+               }\r
+               break;\r
+\r
+               default:\r
+               {\r
+                       length = length % 32; // lenght >= 32 not suported\r
+\r
+                       int word = length >> 2;\r
+\r
+                       int i = 0;\r
+                       while (i < word) {\r
+                               data[i] = uData[i];\r
+                               i++;\r
+                       }\r
+\r
+                       switch (length & 0x3) {\r
+                               case 0:\r
+                               {\r
+                                       data[word] = MD4_pad_w0();\r
+                               }\r
+                               break;\r
+                               case 1:\r
+                               {\r
+                                       data[word] = MD4_pad_w1(uData[word]);\r
+                               }\r
+                               break;\r
+                               case 2:\r
+                               {\r
+                                       data[word] = MD4_pad_w2(uData[word]);\r
+                               }\r
+                               break;\r
+                               case 3:\r
+                               {\r
+                                       data[word] = MD4_pad_w3(uData[word]);\r
+                               }\r
+                               break;\r
+                       }\r
+\r
+                       data[14] = length << 3;\r
+               }\r
+               break;\r
+       }\r
+\r
+       a = 0x67452301;\r
+       b = 0xefcdab89;\r
+       c = 0x98badcfe;\r
+       d = 0x10325476;\r
+\r
+       /* Round 1 */\r
+       FF (a, b, c, d, data[ 0], S11); /* 1 */\r
+       FF (d, a, b, c, data[ 1], S12); /* 2 */\r
+       FF (c, d, a, b, data[ 2], S13); /* 3 */\r
+       FF (b, c, d, a, data[ 3], S14); /* 4 */\r
+       FF (a, b, c, d, data[ 4], S11); /* 5 */\r
+       FF (d, a, b, c, data[ 5], S12); /* 6 */\r
+       FF (c, d, a, b, data[ 6], S13); /* 7 */\r
+       FF (b, c, d, a, data[ 7], S14); /* 8 */\r
+       FF (a, b, c, d,        0, S11); /* 9 */\r
+       FF (d, a, b, c,        0, S12); /* 10 */\r
+       FF (c, d, a, b,        0, S13); /* 11 */\r
+       FF (b, c, d, a,        0, S14); /* 12 */\r
+       FF (a, b, c, d,        0, S11); /* 13 */\r
+       FF (d, a, b, c,        0, S12); /* 14 */\r
+       FF (c, d, a, b, data[14], S13); /* 15 */\r
+       FF (b, c, d, a,        0, S14); /* 16 */\r
+\r
+       /* Round 2 */\r
+       GG (a, b, c, d, data[ 0], S21); /* 17 */\r
+       GG (d, a, b, c, data[ 4], S22); /* 18 */\r
+       GG (c, d, a, b,        0, S23); /* 19 */\r
+       GG (b, c, d, a,        0, S24); /* 20 */\r
+       GG (a, b, c, d, data[ 1], S21); /* 21 */\r
+       GG (d, a, b, c, data[ 5], S22); /* 22 */\r
+       GG (c, d, a, b,        0, S23); /* 23 */\r
+       GG (b, c, d, a,        0, S24); /* 24 */\r
+       GG (a, b, c, d, data[ 2], S21); /* 25 */\r
+       GG (d, a, b, c, data[ 6], S22); /* 26 */\r
+       GG (c, d, a, b,        0, S23); /* 27 */\r
+       GG (b, c, d, a, data[14], S24); /* 28 */\r
+       GG (a, b, c, d, data[ 3], S21); /* 29 */\r
+       GG (d, a, b, c, data[ 7], S22); /* 30 */\r
+       GG (c, d, a, b,        0, S23); /* 31 */\r
+       GG (b, c, d, a,        0, S24); /* 32 */\r
+\r
+       /* Round 3 */\r
+       HH (a, b, c, d, data[ 0], S31); /* 33 */\r
+       HH (d, a, b, c,        0, S32); /* 34 */\r
+       HH (c, d, a, b, data[ 4], S33); /* 35 */\r
+       HH (b, c, d, a,        0, S34); /* 36 */\r
+       HH (a, b, c, d, data[ 2], S31); /* 37 */\r
+       HH (d, a, b, c,        0, S32); /* 38 */\r
+       HH (c, d, a, b, data[ 6], S33); /* 39 */\r
+       HH (b, c, d, a, data[14], S34); /* 40 */\r
+       HH (a, b, c, d, data[ 1], S31); /* 41 */\r
+       HH (d, a, b, c,        0, S32); /* 42 */\r
+       HH (c, d, a, b, data[ 5], S33); /* 43 */\r
+       HH (b, c, d, a,        0, S34); /* 44 */\r
+       HH (a, b, c, d, data[ 3], S31); /* 45 */\r
+       HH (d, a, b, c,        0, S32); /* 46 */\r
+       HH (c, d, a, b, data[ 7], S33); /* 47 */\r
+       HH (b, c, d, a,        0, S34); /* 48 */\r
+\r
+       // Finally, add initial values, as this is the only pass we make.\r
+       a += 0x67452301;\r
+       b += 0xefcdab89;\r
+       c += 0x98badcfe;\r
+       d += 0x10325476;\r
+\r
+       uDigest[0] = a;\r
+       uDigest[1] = b;\r
+       uDigest[2] = c;\r
+       uDigest[3] = d;\r
+}\r
index e2d6f722e6eb670d2a55e1fcb417416b42d364ae..b960bbc36f3dca4aba3b46349630d9ba6a206e19 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-#if defined(_WIN32) && !defined(__GNUC__)
-       #pragma warning(disable : 4786 4267 4018)
-#endif
-
-#include "rcrackiThread.h"
-
-// create job for pre-calculation
-rcrackiThread::rcrackiThread(unsigned char* TargetHash, int thread_id, int nRainbowChainLen, int thread_count, uint64* pStartPosIndexE)
-{
-       t_TargetHash = TargetHash;
-       t_nRainbowChainLen = nRainbowChainLen;
-       t_ID = thread_id;
-       t_count = thread_count;
-       t_pStartPosIndexE = pStartPosIndexE;
-       t_nChainWalkStep = 0;
-       falseAlarmChecker = false;
-       falseAlarmCheckerO = false;
-}
-
-// create job for false alarm checking
-rcrackiThread::rcrackiThread(unsigned char* pHash, bool oldFormat)
-{
-       falseAlarmChecker = true;
-       falseAlarmCheckerO = oldFormat;
-       t_pChainsFound.clear();
-       t_nGuessedPoss.clear();
-       t_pHash = pHash;
-       t_nChainWalkStepDueToFalseAlarm = 0;
-       t_nFalseAlarm = 0;
-       foundHash = false;
-}
-
-void rcrackiThread::AddAlarmCheck(RainbowChain* pChain, int nGuessedPos)
-{
-       t_pChainsFound.push_back(pChain);
-       t_nGuessedPoss.push_back(nGuessedPos);
-}
-
-void rcrackiThread::AddAlarmCheckO(RainbowChainO* pChain, int nGuessedPos)
-{
-       t_pChainsFoundO.push_back(pChain);
-       t_nGuessedPoss.push_back(nGuessedPos);
-}
-
-// Windows (beginthreadex) way of threads
-//unsigned __stdcall rcrackiThread::rcrackiThreadStaticEntryPoint(void * pThis)
-//{
-//     rcrackiThread* pTT = (rcrackiThread*)pThis;
-//     pTT->rcrackiThreadEntryPoint();
-//     _endthreadex( 2 );
-//     return 2;
-//}
-
-// entry point for the posix thread
-void * rcrackiThread::rcrackiThreadStaticEntryPointPthread(void * pThis)
-{
-       rcrackiThread* pTT = (rcrackiThread*)pThis;
-       pTT->rcrackiThreadEntryPoint();
-       pthread_exit(NULL);
-       return NULL;
-}
-
-// start processing of jobs
-void rcrackiThread::rcrackiThreadEntryPoint()
-{
-       if (falseAlarmChecker) {
-               if (falseAlarmCheckerO) {
-                       CheckAlarmO();
-               }
-               else {
-                       CheckAlarm();
-               }
-       }
-       else {
-               PreCalculate();
-       }
-}
-
-uint64 rcrackiThread::GetIndex(int nPos)
-{
-       uint64 t_index = t_vStartPosIndexE[nPos - t_ID];
-       return t_index;
-}
-
-int rcrackiThread::GetChainWalkStep()
-{
-       return t_nChainWalkStep;
-}
-
-int rcrackiThread::GetIndexCount()
-{
-       return t_vStartPosIndexE.size();
-}
-
-rcrackiThread::~rcrackiThread(void)
-{
-}
-
-void rcrackiThread::PreCalculate()
-{
-       for (t_nPos = t_nRainbowChainLen - 2 - t_ID; t_nPos >= 0; t_nPos -= t_count)
-       {
-               t_cwc.SetHash(t_TargetHash);
-               t_cwc.HashToIndex(t_nPos);
-               int i;
-               for (i = t_nPos + 1; i <= t_nRainbowChainLen - 2; i++)
-               {
-                       t_cwc.IndexToPlain();
-                       t_cwc.PlainToHash();
-                       t_cwc.HashToIndex(i);
-               }
-               t_pStartPosIndexE[t_nPos] = t_cwc.GetIndex();
-               t_nChainWalkStep += t_nRainbowChainLen - 2 - t_nPos;
-       }
-}
-
-void rcrackiThread::CheckAlarm()
-{
-       UINT4 i;
-       for (i = 0; i < t_pChainsFound.size(); i++)
-       {
-               RainbowChain* t_pChain = t_pChainsFound[i];
-               int t_nGuessedPos = t_nGuessedPoss[i];          
-               
-               CChainWalkContext cwc;
-               //uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFF; // for first 6 bytes
-               //uint64 nIndexS = t_pChain->nIndexS >> 16;
-               uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes
-               cwc.SetIndex(nIndexS);
-               //cwc.SetIndex(t_pChain->nIndexS);      
-               int nPos;
-               for (nPos = 0; nPos < t_nGuessedPos; nPos++)
-               {
-                       cwc.IndexToPlain();
-                       cwc.PlainToHash();
-                       cwc.HashToIndex(nPos);
-               }
-               cwc.IndexToPlain();
-               cwc.PlainToHash();
-               if (cwc.CheckHash(t_pHash))
-               {
-                       t_Hash = cwc.GetHash();
-                       t_Plain = cwc.GetPlain();
-                       t_Binary = cwc.GetBinary();
-
-                       foundHash = true;
-                       break;
-               }
-               else {
-                       foundHash = false;
-                       t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1;
-                       t_nFalseAlarm++;
-               }
-       }
-}
-
-void rcrackiThread::CheckAlarmO()
-{
-       UINT4 i;
-       for (i = 0; i < t_pChainsFoundO.size(); i++)
-       {
-               RainbowChainO* t_pChain = t_pChainsFoundO[i];
-               int t_nGuessedPos = t_nGuessedPoss[i];          
-               
-               CChainWalkContext cwc;
-
-               uint64 nIndexS = t_pChain->nIndexS;
-               cwc.SetIndex(nIndexS);
-
-               int nPos;
-               for (nPos = 0; nPos < t_nGuessedPos; nPos++)
-               {
-                       cwc.IndexToPlain();
-                       cwc.PlainToHash();
-                       cwc.HashToIndex(nPos);
-               }
-               cwc.IndexToPlain();
-               cwc.PlainToHash();
-               if (cwc.CheckHash(t_pHash))
-               {
-                       t_Hash = cwc.GetHash();
-                       t_Plain = cwc.GetPlain();
-                       t_Binary = cwc.GetBinary();
-
-                       foundHash = true;
-                       break;
-               }
-               else {
-                       foundHash = false;
-                       t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1;
-                       t_nFalseAlarm++;
-               }
-       }
-}
-
-bool rcrackiThread::FoundHash()
-{
-       return foundHash;
-}
-
-int rcrackiThread::GetChainWalkStepDueToFalseAlarm()
-{
-       return t_nChainWalkStepDueToFalseAlarm;
-}
-
-int rcrackiThread::GetnFalseAlarm()
-{
-       return t_nFalseAlarm;
-}
-
-string rcrackiThread::GetHash()
-{
-       return t_Hash;
-}
-
-string rcrackiThread::GetPlain()
-{
-       return t_Plain;
-}
-
-string rcrackiThread::GetBinary()
-{
-       return t_Binary;
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+#if defined(_WIN32) && !defined(__GNUC__)\r
+       #pragma warning(disable : 4786 4267 4018)\r
+#endif\r
+\r
+#include "rcrackiThread.h"\r
+\r
+// create job for pre-calculation\r
+rcrackiThread::rcrackiThread(unsigned char* TargetHash, int thread_id, int nRainbowChainLen, int thread_count, uint64* pStartPosIndexE)\r
+{\r
+       t_TargetHash = TargetHash;\r
+       t_nRainbowChainLen = nRainbowChainLen;\r
+       t_ID = thread_id;\r
+       t_count = thread_count;\r
+       t_pStartPosIndexE = pStartPosIndexE;\r
+       t_nChainWalkStep = 0;\r
+       falseAlarmChecker = false;\r
+       falseAlarmCheckerO = false;\r
+}\r
+\r
+// create job for false alarm checking\r
+rcrackiThread::rcrackiThread(unsigned char* pHash, bool oldFormat)\r
+{\r
+       falseAlarmChecker = true;\r
+       falseAlarmCheckerO = oldFormat;\r
+       t_pChainsFound.clear();\r
+       t_nGuessedPoss.clear();\r
+       t_pHash = pHash;\r
+       t_nChainWalkStepDueToFalseAlarm = 0;\r
+       t_nFalseAlarm = 0;\r
+       foundHash = false;\r
+}\r
+\r
+void rcrackiThread::AddAlarmCheck(RainbowChain* pChain, int nGuessedPos)\r
+{\r
+       t_pChainsFound.push_back(pChain);\r
+       t_nGuessedPoss.push_back(nGuessedPos);\r
+}\r
+\r
+void rcrackiThread::AddAlarmCheckO(RainbowChainO* pChain, int nGuessedPos)\r
+{\r
+       t_pChainsFoundO.push_back(pChain);\r
+       t_nGuessedPoss.push_back(nGuessedPos);\r
+}\r
+\r
+// Windows (beginthreadex) way of threads\r
+//unsigned __stdcall rcrackiThread::rcrackiThreadStaticEntryPoint(void * pThis)\r
+//{\r
+//     rcrackiThread* pTT = (rcrackiThread*)pThis;\r
+//     pTT->rcrackiThreadEntryPoint();\r
+//     _endthreadex( 2 );\r
+//     return 2;\r
+//}\r
+\r
+// entry point for the posix thread\r
+void * rcrackiThread::rcrackiThreadStaticEntryPointPthread(void * pThis)\r
+{\r
+       rcrackiThread* pTT = (rcrackiThread*)pThis;\r
+       pTT->rcrackiThreadEntryPoint();\r
+       pthread_exit(NULL);\r
+       return NULL;\r
+}\r
+\r
+// start processing of jobs\r
+void rcrackiThread::rcrackiThreadEntryPoint()\r
+{\r
+       if (falseAlarmChecker) {\r
+               if (falseAlarmCheckerO) {\r
+                       CheckAlarmO();\r
+               }\r
+               else {\r
+                       CheckAlarm();\r
+               }\r
+       }\r
+       else {\r
+               PreCalculate();\r
+       }\r
+}\r
+\r
+uint64 rcrackiThread::GetIndex(int nPos)\r
+{\r
+       uint64 t_index = t_vStartPosIndexE[nPos - t_ID];\r
+       return t_index;\r
+}\r
+\r
+int rcrackiThread::GetChainWalkStep()\r
+{\r
+       return t_nChainWalkStep;\r
+}\r
+\r
+int rcrackiThread::GetIndexCount()\r
+{\r
+       return t_vStartPosIndexE.size();\r
+}\r
+\r
+rcrackiThread::~rcrackiThread(void)\r
+{\r
+}\r
+\r
+void rcrackiThread::PreCalculate()\r
+{\r
+       for (t_nPos = t_nRainbowChainLen - 2 - t_ID; t_nPos >= 0; t_nPos -= t_count)\r
+       {\r
+               t_cwc.SetHash(t_TargetHash);\r
+               t_cwc.HashToIndex(t_nPos);\r
+               int i;\r
+               for (i = t_nPos + 1; i <= t_nRainbowChainLen - 2; i++)\r
+               {\r
+                       t_cwc.IndexToPlain();\r
+                       t_cwc.PlainToHash();\r
+                       t_cwc.HashToIndex(i);\r
+               }\r
+               t_pStartPosIndexE[t_nPos] = t_cwc.GetIndex();\r
+               t_nChainWalkStep += t_nRainbowChainLen - 2 - t_nPos;\r
+       }\r
+}\r
+\r
+void rcrackiThread::CheckAlarm()\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < t_pChainsFound.size(); i++)\r
+       {\r
+               RainbowChain* t_pChain = t_pChainsFound[i];\r
+               int t_nGuessedPos = t_nGuessedPoss[i];          \r
+               \r
+               CChainWalkContext cwc;\r
+               //uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFF; // for first 6 bytes\r
+               //uint64 nIndexS = t_pChain->nIndexS >> 16;\r
+               uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes\r
+               cwc.SetIndex(nIndexS);\r
+               //cwc.SetIndex(t_pChain->nIndexS);      \r
+               int nPos;\r
+               for (nPos = 0; nPos < t_nGuessedPos; nPos++)\r
+               {\r
+                       cwc.IndexToPlain();\r
+                       cwc.PlainToHash();\r
+                       cwc.HashToIndex(nPos);\r
+               }\r
+               cwc.IndexToPlain();\r
+               cwc.PlainToHash();\r
+               if (cwc.CheckHash(t_pHash))\r
+               {\r
+                       t_Hash = cwc.GetHash();\r
+                       t_Plain = cwc.GetPlain();\r
+                       t_Binary = cwc.GetBinary();\r
+\r
+                       foundHash = true;\r
+                       break;\r
+               }\r
+               else {\r
+                       foundHash = false;\r
+                       t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1;\r
+                       t_nFalseAlarm++;\r
+               }\r
+       }\r
+}\r
+\r
+void rcrackiThread::CheckAlarmO()\r
+{\r
+       uint32 i;\r
+       for (i = 0; i < t_pChainsFoundO.size(); i++)\r
+       {\r
+               RainbowChainO* t_pChain = t_pChainsFoundO[i];\r
+               int t_nGuessedPos = t_nGuessedPoss[i];          \r
+               \r
+               CChainWalkContext cwc;\r
+\r
+               uint64 nIndexS = t_pChain->nIndexS;\r
+               cwc.SetIndex(nIndexS);\r
+\r
+               int nPos;\r
+               for (nPos = 0; nPos < t_nGuessedPos; nPos++)\r
+               {\r
+                       cwc.IndexToPlain();\r
+                       cwc.PlainToHash();\r
+                       cwc.HashToIndex(nPos);\r
+               }\r
+               cwc.IndexToPlain();\r
+               cwc.PlainToHash();\r
+               if (cwc.CheckHash(t_pHash))\r
+               {\r
+                       t_Hash = cwc.GetHash();\r
+                       t_Plain = cwc.GetPlain();\r
+                       t_Binary = cwc.GetBinary();\r
+\r
+                       foundHash = true;\r
+                       break;\r
+               }\r
+               else {\r
+                       foundHash = false;\r
+                       t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1;\r
+                       t_nFalseAlarm++;\r
+               }\r
+       }\r
+}\r
+\r
+bool rcrackiThread::FoundHash()\r
+{\r
+       return foundHash;\r
+}\r
+\r
+int rcrackiThread::GetChainWalkStepDueToFalseAlarm()\r
+{\r
+       return t_nChainWalkStepDueToFalseAlarm;\r
+}\r
+\r
+int rcrackiThread::GetnFalseAlarm()\r
+{\r
+       return t_nFalseAlarm;\r
+}\r
+\r
+string rcrackiThread::GetHash()\r
+{\r
+       return t_Hash;\r
+}\r
+\r
+string rcrackiThread::GetPlain()\r
+{\r
+       return t_Plain;\r
+}\r
+\r
+string rcrackiThread::GetBinary()\r
+{\r
+       return t_Binary;\r
+}\r
index ea8ef5bf17583845f027b4f064c44900aa54fd1e..e1218544755ab2e2f1e94304728de769f924361c 100644 (file)
-/*
- * rcracki_mt is a multithreaded implementation and fork of the original 
- * RainbowCrack
- *
- * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
- * Copyright Wei Dai <weidai@eskimo.com>
- * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
- * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
- *
- * This file is part of rcracki_mt.
- *
- * rcracki_mt is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
- *
- * rcracki_mt is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.
- */
-
-//#include <stdio.h>
-#if defined(_WIN32)
-       #include <windows.h>
-#endif
-
-#include <string.h>
-
-#include "sha1.h"
-
-#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))
-
-// this rotate isn't faster with me
-#if defined(_WIN32)
-       #define ROTATE(a,n)     _lrotl(a,n)
-#else
-       #define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))
-#endif
-
-/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */
-#if defined(_WIN32)
-/* 5 instructions with rotate instruction, else 9 */
-#define Endian_Reverse32(a) \
-       { \
-       unsigned long l=(a); \
-       (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \
-       }
-#else
-/* 6 instructions with rotate instruction, else 8 */
-#define Endian_Reverse32(a) \
-       { \
-       unsigned long l=(a); \
-       l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \
-       (a)=ROTATE(l,16L); \
-       }
-#endif
-
-#define        F_00_19(b,c,d)  ((((c) ^ (d)) & (b)) ^ (d)) 
-#define        F_20_39(b,c,d)  ((b) ^ (c) ^ (d))
-#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) 
-#define        F_60_79(b,c,d)  F_20_39(b,c,d)
-
-#define K0 0x5A827999
-#define K1 0x6ED9EBA1
-#define K2 0x8F1BBCDC
-#define K3 0xCA62C1D6
-
-#define H0 0x67452301
-#define H1 0xEFCDAB89
-#define H2 0x98BADCFE
-#define H3 0x10325476
-#define H4 0xC3D2E1F0
-
-#define SHA1HashSize 20
-
-void SHA1_NEW( unsigned char * pData, int length, unsigned char * pDigest)
-{
-       if (length > 16)
-               return;
-
-       UINT4 Message_Block_Index    = 0;
-
-       union
-       {
-               unsigned char Message_Block[64];
-               UINT4 Message_Block_W[16];
-       };
-
-       Message_Block_W[0] = 0x00000000;
-       Message_Block_W[1] = 0x00000000;
-       Message_Block_W[2] = 0x00000000;
-       Message_Block_W[3] = 0x00000000;
-       Message_Block_W[4] = 0x00000000;
-
-       UINT4 Intermediate_Hash[5] = { H0, H1, H2, H3, H4 };
-       
-       memcpy(Message_Block, pData, length);
-       Message_Block_Index += length;
-
-       //padMessage
-       Message_Block[length] = 0x80;
-       
-       UINT4 W_15 = length << 3;
-
-       int           t;                 /* Loop counter                */
-       UINT4      temp;              /* Temporary word value        */
-       UINT4      W[80];             /* Word sequence               */
-       UINT4      A, B, C, D, E;     /* Word buffers                */
-
-    /*
-     *  Initialize the first 16 words in the array W
-     */
-
-       #define INIT(x) W[x] = Message_Block_W[x];
-       
-       #define INIT_NULL(x) W[x] = 0;
-
-       
-       Endian_Reverse32(Message_Block_W[0]);
-       INIT(0);
-
-       #define INIT_NULL_1_14 \
-               INIT_NULL(1);  INIT_NULL_2_14;
-
-       #define INIT_NULL_2_14 \
-               INIT_NULL(2);  INIT_NULL_3_14;
-
-       #define INIT_NULL_3_14 \
-               INIT_NULL(3);  INIT_NULL_4_14;
-
-       #define INIT_NULL_4_14 \
-               INIT_NULL(4); INIT_NULL_5_14;
-
-       #define INIT_NULL_5_14 \
-               INIT_NULL(5);  INIT_NULL(6);  INIT_NULL(7); \
-               INIT_NULL(8);  INIT_NULL(9);  INIT_NULL(10); INIT_NULL(11); \
-               INIT_NULL(12); INIT_NULL(13); INIT_NULL(14);
-
-       #define ROTATE1_NULL_5_14 \
-               ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \
-               ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \
-               ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL;
-
-
-       #define EXPAND(t) \
-               W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); \
-
-       #define EXPAND_3(t) W[t] = SHA1CircularShift(1,W[t-3]);
-       #define EXPAND_16(t) W[t] = SHA1CircularShift(1,W[t-16]);
-       #define EXPAND_3_8(t) W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8]);
-
-       if (length < 4) {
-               INIT_NULL_1_14;
-               W[15] = W_15;
-               EXPAND_16(16);
-               W[17] = 0;
-               W[18] = W_15<<1;
-       }
-       else if (length < 8) {
-               Endian_Reverse32(Message_Block_W[1]);
-               INIT(1);
-               INIT_NULL_2_14;
-               W[15] = W_15;
-               EXPAND_16(16);
-               EXPAND_16(17);
-               W[18] = W_15<<1;
-       }
-       else {
-               Endian_Reverse32(Message_Block_W[1]);
-               Endian_Reverse32(Message_Block_W[2]);
-               Endian_Reverse32(Message_Block_W[3]);
-               Endian_Reverse32(Message_Block_W[4]);
-               INIT(1); INIT(2); INIT(3); INIT(4); 
-               INIT_NULL_5_14;
-               W[15] = W_15;
-               EXPAND(16);
-               EXPAND(17);
-               EXPAND(18);
-       }
-
-       if (length < 12) {
-               EXPAND_3(19);
-       }
-       else {
-               EXPAND(19);
-       }
-
-       if (length < 16) {
-               EXPAND_3(20);
-       }
-       else {
-               EXPAND(20);
-       }
-       EXPAND_3(21); EXPAND_3(22);
-       EXPAND(23);
-
-       EXPAND(24); EXPAND(25); EXPAND_3_8(26); EXPAND_3_8(27);
-       EXPAND(28);     EXPAND(29);     EXPAND(30);     EXPAND(31);
-       EXPAND(32);     EXPAND(33);     EXPAND(34);     EXPAND(35);
-       EXPAND(36);     EXPAND(37);     EXPAND(38);     EXPAND(39);
-       EXPAND(40);     EXPAND(41);     EXPAND(42);     EXPAND(43);
-       EXPAND(44);     EXPAND(45);     EXPAND(46);     EXPAND(47);
-       EXPAND(48);     EXPAND(49);     EXPAND(50);     EXPAND(51);
-       EXPAND(52);     EXPAND(53);     EXPAND(54);     EXPAND(55);
-       EXPAND(56);     EXPAND(57);     EXPAND(58);     EXPAND(59);
-       EXPAND(60);     EXPAND(61);     EXPAND(62);     EXPAND(63);
-       EXPAND(64);     EXPAND(65);     EXPAND(66);     EXPAND(67);
-       EXPAND(68);     EXPAND(69);     EXPAND(70);     EXPAND(71);
-       EXPAND(72);     EXPAND(73);     EXPAND(74);     EXPAND(75);
-       EXPAND(76);     EXPAND(77);     EXPAND(78);     EXPAND(79);
-
-
-       #define ROTATE1_NEW(a, b, c, d, e, x) \
-                       e += SHA1CircularShift(5,a) + F_00_19(b,c,d) + x + K0; \
-                       b = SHA1CircularShift(30,b);
-
-       #define ROTATE1_NULL \
-                       temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + E + K0; \
-                       E = D; D = C; \
-                       C = SHA1CircularShift(30,B); \
-                       B = A; A = temp; \
-                       
-       #define ROTATE2_NEW(a, b, c, d, e, x) \
-                       e += SHA1CircularShift(5,a) + F_20_39(b,c,d) + x + K1; \
-                       b = SHA1CircularShift(30,b);
-       
-       #define ROTATE2(t) \
-               temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + W[t] + K1; \
-               E = D; D = C; \
-               C = SHA1CircularShift(30,B); \
-               B = A; A = temp;
-
-       #define ROTATE2_W(w) \
-               temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + w + K1; \
-               E = D; D = C; \
-               C = SHA1CircularShift(30,B); \
-               B = A; A = temp;
-
-       #define ROTATE3(t) \
-               temp = SHA1CircularShift(5,A) + F_40_59(B,C,D) + E + W[t] + K2; \
-               E = D; D = C; \
-               C = SHA1CircularShift(30,B); \
-               B = A; A = temp;
-
-       #define ROTATE4(t) \
-               temp = SHA1CircularShift(5,A) + F_60_79(B,C,D) + E + W[t] + K3; \
-               E = D; D = C; \
-               C = SHA1CircularShift(30,B); \
-               B = A; A = temp;
-
-       A = H0;
-       B = H1;
-       C = H2;
-       D = H3;
-       E = H4;
-
-
-       E = H2;
-       //D = 2079550178;
-       //C = 1506887872;
-       B = 2679412915u + W[0];
-       if (length < 4) {
-               A = SHA1CircularShift(5,B) + 1722862861;
-       }
-       else {
-               A = SHA1CircularShift(5,B) + 1722862861 + W[1];
-       }
-
-       if (length < 8) {
-               temp = SHA1CircularShift(5,A) + ((((1506887872) ^ (2079550178)) & (B)) ^ (2079550178)) + H2 + K0;
-       }
-       else {
-               temp = SHA1CircularShift(5,A) + (((572662306) & (B)) ^ (2079550178)) + H2 + K0 + W[2];
-       }
-       C = SHA1CircularShift(30,B);  //SHA1CircularShift(30,(2679412915 + W[0]));
-       B = A;
-       A = temp;
-       
-       if (length < 12) {
-               temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0;
-       }
-       else {
-               temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0 + W[3];
-       }
-       E = 1506887872;
-       D = C;
-       C = SHA1CircularShift(30,B);
-       B = A;
-       A = temp;
-
-       if (length < 16) {
-               temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0;
-       }
-       else {
-               temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0 + W[4];
-       }
-       E = D;
-       D = C;
-       C = SHA1CircularShift(30,B);
-       B = A;
-       A = temp;
-
-       ROTATE1_NULL_5_14;
-
-       ROTATE1_NEW( A, B, C, D, E, W_15 );
-       ROTATE1_NEW( E, A, B, C, D, W[16] );
-       ROTATE1_NEW( D, E, A, B, C, W[17] );
-       ROTATE1_NEW( C, D, E, A, B, W[18] );
-       ROTATE1_NEW( B, C, D, E, A, W[19] );
-               
-       for(t = 20; t < 40; t++)
-       {
-               if (t == 21 && length < 8) {
-                       ROTATE2_W((length<<5)); // *32
-               }
-               else {
-                       ROTATE2(t);
-               }
-       }
-
-       for(t = 40; t < 60; t++)
-       {
-               ROTATE3(t);
-       }
-       
-       for(t = 60; t < 80; t++)
-       {
-               ROTATE4(t);
-       }
-       
-       Intermediate_Hash[0] += A;
-       Intermediate_Hash[1] += B;
-       Intermediate_Hash[2] += C;
-       Intermediate_Hash[3] += D;
-       Intermediate_Hash[4] += E;
-
-       Endian_Reverse32(Intermediate_Hash[0]);
-       Endian_Reverse32(Intermediate_Hash[1]);
-       Endian_Reverse32(Intermediate_Hash[2]);
-       Endian_Reverse32(Intermediate_Hash[3]);
-       Endian_Reverse32(Intermediate_Hash[4]);
-
-       memcpy(pDigest, Intermediate_Hash, 20);
-}
+/*\r
+ * rcracki_mt is a multithreaded implementation and fork of the original \r
+ * RainbowCrack\r
+ *\r
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>\r
+ * Copyright Wei Dai <weidai@eskimo.com>\r
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>\r
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>\r
+ *\r
+ * This file is part of rcracki_mt.\r
+ *\r
+ * rcracki_mt is free software: you can redistribute it and/or modify\r
+ * it under the terms of the GNU General Public License as published by\r
+ * the Free Software Foundation, either version 2 of the License, or\r
+ * (at your option) any later version.\r
+ *\r
+ * rcracki_mt is distributed in the hope that it will be useful,\r
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of\r
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
+ * GNU General Public License for more details.\r
+ *\r
+ * You should have received a copy of the GNU General Public License\r
+ * along with rcracki_mt.  If not, see <http://www.gnu.org/licenses/>.\r
+ */\r
+\r
+//#include <stdio.h>\r
+#if defined(_WIN32)\r
+       #include <windows.h>\r
+#endif\r
+\r
+#include <string.h>\r
+\r
+#include "sha1.h"\r
+\r
+#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits))))\r
+\r
+// this rotate isn't faster with me\r
+#if defined(_WIN32)\r
+       #define ROTATE(a,n)     _lrotl(a,n)\r
+#else\r
+       #define ROTATE(a,n)     (((a)<<(n))|(((a)&0xffffffff)>>(32-(n))))\r
+#endif\r
+\r
+/* A nice byte order reversal from Wei Dai <weidai@eskimo.com> */\r
+#if defined(_WIN32)\r
+/* 5 instructions with rotate instruction, else 9 */\r
+#define Endian_Reverse32(a) \\r
+       { \\r
+       unsigned long l=(a); \\r
+       (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \\r
+       }\r
+#else\r
+/* 6 instructions with rotate instruction, else 8 */\r
+#define Endian_Reverse32(a) \\r
+       { \\r
+       unsigned long l=(a); \\r
+       l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \\r
+       (a)=ROTATE(l,16L); \\r
+       }\r
+#endif\r
+\r
+#define        F_00_19(b,c,d)  ((((c) ^ (d)) & (b)) ^ (d)) \r
+#define        F_20_39(b,c,d)  ((b) ^ (c) ^ (d))\r
+#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) \r
+#define        F_60_79(b,c,d)  F_20_39(b,c,d)\r
+\r
+#define K0 0x5A827999\r
+#define K1 0x6ED9EBA1\r
+#define K2 0x8F1BBCDC\r
+#define K3 0xCA62C1D6\r
+\r
+#define H0 0x67452301\r
+#define H1 0xEFCDAB89\r
+#define H2 0x98BADCFE\r
+#define H3 0x10325476\r
+#define H4 0xC3D2E1F0\r
+\r
+#define SHA1HashSize 20\r
+\r
+void SHA1_NEW( unsigned char * pData, int length, unsigned char * pDigest)\r
+{\r
+       if (length > 16)\r
+               return;\r
+\r
+       uint32 Message_Block_Index    = 0;\r
+\r
+       union\r
+       {\r
+               unsigned char Message_Block[64];\r
+               uint32 Message_Block_W[16];\r
+       };\r
+\r
+       Message_Block_W[0] = 0x00000000;\r
+       Message_Block_W[1] = 0x00000000;\r
+       Message_Block_W[2] = 0x00000000;\r
+       Message_Block_W[3] = 0x00000000;\r
+       Message_Block_W[4] = 0x00000000;\r
+\r
+       uint32 Intermediate_Hash[5] = { H0, H1, H2, H3, H4 };\r
+       \r
+       memcpy(Message_Block, pData, length);\r
+       Message_Block_Index += length;\r
+\r
+       //padMessage\r
+       Message_Block[length] = 0x80;\r
+       \r
+       uint32 W_15 = length << 3;\r
+\r
+       int           t;                 /* Loop counter                */\r
+       uint32      temp;              /* Temporary word value        */\r
+       uint32      W[80];             /* Word sequence               */\r
+       uint32      A, B, C, D, E;     /* Word buffers                */\r
+\r
+    /*\r
+     *  Initialize the first 16 words in the array W\r
+     */\r
+\r
+       #define INIT(x) W[x] = Message_Block_W[x];\r
+       \r
+       #define INIT_NULL(x) W[x] = 0;\r
+\r
+       \r
+       Endian_Reverse32(Message_Block_W[0]);\r
+       INIT(0);\r
+\r
+       #define INIT_NULL_1_14 \\r
+               INIT_NULL(1);  INIT_NULL_2_14;\r
+\r
+       #define INIT_NULL_2_14 \\r
+               INIT_NULL(2);  INIT_NULL_3_14;\r
+\r
+       #define INIT_NULL_3_14 \\r
+               INIT_NULL(3);  INIT_NULL_4_14;\r
+\r
+       #define INIT_NULL_4_14 \\r
+               INIT_NULL(4); INIT_NULL_5_14;\r
+\r
+       #define INIT_NULL_5_14 \\r
+               INIT_NULL(5);  INIT_NULL(6);  INIT_NULL(7); \\r
+               INIT_NULL(8);  INIT_NULL(9);  INIT_NULL(10); INIT_NULL(11); \\r
+               INIT_NULL(12); INIT_NULL(13); INIT_NULL(14);\r
+\r
+       #define ROTATE1_NULL_5_14 \\r
+               ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \\r
+               ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \\r
+               ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL;\r
+\r
+\r
+       #define EXPAND(t) \\r
+               W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); \\r
+\r
+       #define EXPAND_3(t) W[t] = SHA1CircularShift(1,W[t-3]);\r
+       #define EXPAND_16(t) W[t] = SHA1CircularShift(1,W[t-16]);\r
+       #define EXPAND_3_8(t) W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8]);\r
+\r
+       if (length < 4) {\r
+               INIT_NULL_1_14;\r
+               W[15] = W_15;\r
+               EXPAND_16(16);\r
+               W[17] = 0;\r
+               W[18] = W_15<<1;\r
+       }\r
+       else if (length < 8) {\r
+               Endian_Reverse32(Message_Block_W[1]);\r
+               INIT(1);\r
+               INIT_NULL_2_14;\r
+               W[15] = W_15;\r
+               EXPAND_16(16);\r
+               EXPAND_16(17);\r
+               W[18] = W_15<<1;\r
+       }\r
+       else {\r
+               Endian_Reverse32(Message_Block_W[1]);\r
+               Endian_Reverse32(Message_Block_W[2]);\r
+               Endian_Reverse32(Message_Block_W[3]);\r
+               Endian_Reverse32(Message_Block_W[4]);\r
+               INIT(1); INIT(2); INIT(3); INIT(4); \r
+               INIT_NULL_5_14;\r
+               W[15] = W_15;\r
+               EXPAND(16);\r
+               EXPAND(17);\r
+               EXPAND(18);\r
+       }\r
+\r
+       if (length < 12) {\r
+               EXPAND_3(19);\r
+       }\r
+       else {\r
+               EXPAND(19);\r
+       }\r
+\r
+       if (length < 16) {\r
+               EXPAND_3(20);\r
+       }\r
+       else {\r
+               EXPAND(20);\r
+       }\r
+       EXPAND_3(21); EXPAND_3(22);\r
+       EXPAND(23);\r
+\r
+       EXPAND(24); EXPAND(25); EXPAND_3_8(26); EXPAND_3_8(27);\r
+       EXPAND(28);     EXPAND(29);     EXPAND(30);     EXPAND(31);\r
+       EXPAND(32);     EXPAND(33);     EXPAND(34);     EXPAND(35);\r
+       EXPAND(36);     EXPAND(37);     EXPAND(38);     EXPAND(39);\r
+       EXPAND(40);     EXPAND(41);     EXPAND(42);     EXPAND(43);\r
+       EXPAND(44);     EXPAND(45);     EXPAND(46);     EXPAND(47);\r
+       EXPAND(48);     EXPAND(49);     EXPAND(50);     EXPAND(51);\r
+       EXPAND(52);     EXPAND(53);     EXPAND(54);     EXPAND(55);\r
+       EXPAND(56);     EXPAND(57);     EXPAND(58);     EXPAND(59);\r
+       EXPAND(60);     EXPAND(61);     EXPAND(62);     EXPAND(63);\r
+       EXPAND(64);     EXPAND(65);     EXPAND(66);     EXPAND(67);\r
+       EXPAND(68);     EXPAND(69);     EXPAND(70);     EXPAND(71);\r
+       EXPAND(72);     EXPAND(73);     EXPAND(74);     EXPAND(75);\r
+       EXPAND(76);     EXPAND(77);     EXPAND(78);     EXPAND(79);\r
+\r
+\r
+       #define ROTATE1_NEW(a, b, c, d, e, x) \\r
+                       e += SHA1CircularShift(5,a) + F_00_19(b,c,d) + x + K0; \\r
+                       b = SHA1CircularShift(30,b);\r
+\r
+       #define ROTATE1_NULL \\r
+                       temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + E + K0; \\r
+                       E = D; D = C; \\r
+                       C = SHA1CircularShift(30,B); \\r
+                       B = A; A = temp; \\r
+                       \r
+       #define ROTATE2_NEW(a, b, c, d, e, x) \\r
+                       e += SHA1CircularShift(5,a) + F_20_39(b,c,d) + x + K1; \\r
+                       b = SHA1CircularShift(30,b);\r
+       \r
+       #define ROTATE2(t) \\r
+               temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + W[t] + K1; \\r
+               E = D; D = C; \\r
+               C = SHA1CircularShift(30,B); \\r
+               B = A; A = temp;\r
+\r
+       #define ROTATE2_W(w) \\r
+               temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + w + K1; \\r
+               E = D; D = C; \\r
+               C = SHA1CircularShift(30,B); \\r
+               B = A; A = temp;\r
+\r
+       #define ROTATE3(t) \\r
+               temp = SHA1CircularShift(5,A) + F_40_59(B,C,D) + E + W[t] + K2; \\r
+               E = D; D = C; \\r
+               C = SHA1CircularShift(30,B); \\r
+               B = A; A = temp;\r
+\r
+       #define ROTATE4(t) \\r
+               temp = SHA1CircularShift(5,A) + F_60_79(B,C,D) + E + W[t] + K3; \\r
+               E = D; D = C; \\r
+               C = SHA1CircularShift(30,B); \\r
+               B = A; A = temp;\r
+\r
+       A = H0;\r
+       B = H1;\r
+       C = H2;\r
+       D = H3;\r
+       E = H4;\r
+\r
+\r
+       E = H2;\r
+       //D = 2079550178;\r
+       //C = 1506887872;\r
+       B = 2679412915u + W[0];\r
+       if (length < 4) {\r
+               A = SHA1CircularShift(5,B) + 1722862861;\r
+       }\r
+       else {\r
+               A = SHA1CircularShift(5,B) + 1722862861 + W[1];\r
+       }\r
+\r
+       if (length < 8) {\r
+               temp = SHA1CircularShift(5,A) + ((((1506887872) ^ (2079550178)) & (B)) ^ (2079550178)) + H2 + K0;\r
+       }\r
+       else {\r
+               temp = SHA1CircularShift(5,A) + (((572662306) & (B)) ^ (2079550178)) + H2 + K0 + W[2];\r
+       }\r
+       C = SHA1CircularShift(30,B);  //SHA1CircularShift(30,(2679412915 + W[0]));\r
+       B = A;\r
+       A = temp;\r
+       \r
+       if (length < 12) {\r
+               temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0;\r
+       }\r
+       else {\r
+               temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0 + W[3];\r
+       }\r
+       E = 1506887872;\r
+       D = C;\r
+       C = SHA1CircularShift(30,B);\r
+       B = A;\r
+       A = temp;\r
+\r
+       if (length < 16) {\r
+               temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0;\r
+       }\r
+       else {\r
+               temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0 + W[4];\r
+       }\r
+       E = D;\r
+       D = C;\r
+       C = SHA1CircularShift(30,B);\r
+       B = A;\r
+       A = temp;\r
+\r
+       ROTATE1_NULL_5_14;\r
+\r
+       ROTATE1_NEW( A, B, C, D, E, W_15 );\r
+       ROTATE1_NEW( E, A, B, C, D, W[16] );\r
+       ROTATE1_NEW( D, E, A, B, C, W[17] );\r
+       ROTATE1_NEW( C, D, E, A, B, W[18] );\r
+       ROTATE1_NEW( B, C, D, E, A, W[19] );\r
+               \r
+       for(t = 20; t < 40; t++)\r
+       {\r
+               if (t == 21 && length < 8) {\r
+                       ROTATE2_W((length<<5)); // *32\r
+               }\r
+               else {\r
+                       ROTATE2(t);\r
+               }\r
+       }\r
+\r
+       for(t = 40; t < 60; t++)\r
+       {\r
+               ROTATE3(t);\r
+       }\r
+       \r
+       for(t = 60; t < 80; t++)\r
+       {\r
+               ROTATE4(t);\r
+       }\r
+       \r
+       Intermediate_Hash[0] += A;\r
+       Intermediate_Hash[1] += B;\r
+       Intermediate_Hash[2] += C;\r
+       Intermediate_Hash[3] += D;\r
+       Intermediate_Hash[4] += E;\r
+\r
+       Endian_Reverse32(Intermediate_Hash[0]);\r
+       Endian_Reverse32(Intermediate_Hash[1]);\r
+       Endian_Reverse32(Intermediate_Hash[2]);\r
+       Endian_Reverse32(Intermediate_Hash[3]);\r
+       Endian_Reverse32(Intermediate_Hash[4]);\r
+\r
+       memcpy(pDigest, Intermediate_Hash, 20);\r
+}\r
index 3eadfbf8275cbb4e87bad9bfa29f12f2913242e6..2494a8447b778ad791ba8174a3f14eccbfd150eb 100644 (file)
@@ -1,7 +1,7 @@
 SHELL = /bin/sh
 CC = g++
 OPTIMIZATION = -O3
-INCLUDES = -I../../Common/rt\ api -I../../Server\ Applications/rsearchi
+INCLUDES = -I../../Common/rt\ api
 CFLAGS = -Wall -ansi $(INCLUDES) $(OPTIMIZATION) -c $(DEBUG)
 LFLAGS = -Wall -ansi $(INCLUDES) $(OPTIMIZATION) $(DEBUG)
 LIBS = 
@@ -19,6 +19,9 @@ clean:
 debug: DEBUG += -DDEBUG -g
 debug: all
 
+m32: DEBUG += -m32
+m32: rti2rto
+
 rebuild: clean all
 
 MemoryPool.o: $(COMMON_API_PATH)/MemoryPool.h $(COMMON_API_PATH)/MemoryPool.cpp $(COMMON_API_PATH)/Public.h
index 086c333f27172373569429ad44868798b3b02b58..ba7f16315e6f4f7531b33082087db2e14b27db0e 100644 (file)
@@ -129,7 +129,7 @@ void ConvertRainbowTable(string sPathName, string sResultFileName, string sType)
 #ifdef _MEMORYDEBUG
                        printf("Recieved %i chains from file\n", nChains);
 #endif
-                       for(UINT4 i = 0; i < nChains; i++)
+                       for(uint32 i = 0; i < nChains; i++)
                        {
                                fwrite(&pChain[i], 1, 16, fResult);
                        }
@@ -170,7 +170,7 @@ int main(int argc, char* argv[])
                printf("no rainbow table found\n");
                return 0;
        }
-       for (UINT4 i = 0; i < vPathName.size(); i++)
+       for (uint32 i = 0; i < vPathName.size(); i++)
        {
                string sResultFile, sType;
                        
@@ -193,4 +193,4 @@ int main(int argc, char* argv[])
                printf("\n");
        }
        return 0;
-}
\ No newline at end of file
+}
index d762e2690ed1d8dae80adca0656005f9e0e65009..5e08a97bcb34775b8dc4eb458668e7450ccad14e 100644 (file)
@@ -1,2 +1,25 @@
-#include "BaseRTReader.h"
+/*
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
+#include "BaseRTReader.h"
index 5054d8fb2088d19957fbf17c2d9ac1232eb98ef0..a9923cf325683b768da4bf056a3e8f63fbce57aa 100644 (file)
@@ -1,11 +1,37 @@
+/*
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #ifndef __BASERTREADER_H__
 #define __BASERTREADER_H__
 
 #include "Public.h"
 #include <string>
-#ifdef WIN32
+
+#if defined(_WIN32) && !defined(__GNUC__)
        #include <io.h>
 #endif
+
 using namespace std;
 
 class BaseRTReader
index 52c9091e8c5b280f8b39082fbf6de02b65ad9044..f551d639b5fc6fd397efe3b34bee9937719a62f3 100644 (file)
@@ -8,7 +8,7 @@
  * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
  * Copyright 2010 Yngve AAdlandsvik
  *
- * This file is part of rcracki_mt.
+ * This file is part of freerainbowtables.
  *
  * freerainbowtables is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -40,6 +40,8 @@ int CChainWalkContext::m_nHashLen;
 int CChainWalkContext::m_nPlainLenMinTotal = 0;
 int CChainWalkContext::m_nPlainLenMaxTotal = 0;
 int CChainWalkContext::m_nHybridCharset = 0;
+bool CChainWalkContext::isOldRtFormat = false;
+bool CChainWalkContext::isRti2RtFormat = false;
 vector<stCharset> CChainWalkContext::m_vCharset;
 uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];
 uint64 CChainWalkContext::m_nPlainSpaceTotal;
@@ -280,13 +282,24 @@ bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLe
                printf("%s is not a rainbow table\n", sPathName.c_str());
                return false;
        }
-       /*
-       if (sPathName.substr(sPathName.size() - 4) != ".rti")
+       if (sPathName.substr(sPathName.size() - 5) == ".rti2")
+       {
+               isRti2RtFormat = true;
+       }
+       else if (sPathName.substr(sPathName.size() - 4) == ".rti")
+       {
+               isOldRtFormat = false;
+       }
+       else if (sPathName.substr(sPathName.size() - 3) == ".rt")
+       {
+               isOldRtFormat = true;
+       }
+       else
        {
                printf("%s is not a rainbow table\n", sPathName.c_str());
                return false;
        }
-*/
+
        // Parse
        vector<string> vPart;
        if (!SeperateString(sPathName, "___x_", vPart))
@@ -475,6 +488,7 @@ void CChainWalkContext::IndexToPlain()
                        }
                }
        }
+
 #elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__)
 
        // Fast ia32 version
@@ -488,6 +502,7 @@ void CChainWalkContext::IndexToPlain()
                if (nIndexOfX < 0x100000000llu)
                        break;
 #endif
+
                int nCharsetLen = 0;
                for(uint32 j = 0; j < m_vCharset.size(); j++)
                {
@@ -620,3 +635,13 @@ bool CChainWalkContext::CheckHash(unsigned char* pHash)
 
        return false;
 }
+
+bool CChainWalkContext::isOldFormat()
+{
+       return isOldRtFormat;
+}
+
+bool CChainWalkContext::isRti2Format()
+{
+       return isRti2RtFormat;
+}
index de7e2fb430373b0fe9260cb226bd0400f9d641da..9854c59e0f2ef9f2f678723f6bed40ccfd437c1c 100644 (file)
@@ -1,8 +1,26 @@
 /*
-   RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
-
-   Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-*/
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifndef _CHAINWALKCONTEXT_H
 #define _CHAINWALKCONTEXT_H
@@ -13,7 +31,7 @@
 typedef struct 
 {
        unsigned char m_PlainCharset[255];
-       int m_nPlainCharsetLen;
+       unsigned int m_nPlainCharsetLen;
        int m_nPlainLenMin;
        int m_nPlainLenMax;
        string m_sPlainCharsetName;
@@ -25,17 +43,16 @@ public:
        CChainWalkContext();
        virtual ~CChainWalkContext();
 
-private:
+//private:
        static string m_sHashRoutineName;       
        static HASHROUTINE m_pHashRoutine;                                                      // Configuration
        static int m_nHashLen;                                                                          // Configuration
-
-//     static unsigned char m_PlainCharset[256];                                       // Configuration
-//     static unsigned char m_PlainCharset2[256];                                      // Configuration
+       static bool isOldRtFormat;
+       static bool isRti2RtFormat;
        static vector<stCharset> m_vCharset;
        static int m_nPlainLenMinTotal, m_nPlainLenMaxTotal;
-       static uint64 m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];            // Performance consideration
        static uint64 m_nPlainSpaceTotal;                                                       // Performance consideration
+       static uint64 m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1];            // Performance consideration
        static int m_nHybridCharset;
        static int m_nRainbowTableIndex;                                                        // Configuration
        static uint64 m_nReduceOffset;                                                          // Performance consideration
@@ -65,8 +82,9 @@ public:
        static uint64 GetPlainSpaceTotal();
        static int GetRainbowTableIndex();
        static void Dump();
+       static bool isOldFormat();
+       static bool isRti2Format();
 
-//     void GenerateRandomIndex();
        void SetIndex(uint64 nIndex);
        void SetHash(unsigned char* pHash);             // The length should be m_nHashLen
 
index a081eb8279c4d386f28008974a1a6feec3d208ea..e2d71c9f6328de2e91c0dfdfef6c969d718f5fa2 100644 (file)
@@ -1,10 +1,29 @@
 /*
-   RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
-   Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-*/
-
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__GNUC__)
        #pragma warning(disable : 4786)
 #endif
 
@@ -18,6 +37,9 @@ CChainWalkSet::CChainWalkSet()
        m_nPlainLenMax       = 0;
        m_nRainbowTableIndex = 0;
        m_nRainbowChainLen   = 0;
+       debug = false;
+       sPrecalcPathName     = "";
+       preCalcPart          = 0;
 }
 
 CChainWalkSet::~CChainWalkSet()
@@ -31,17 +53,207 @@ void CChainWalkSet::DiscardAll()
 
        list<ChainWalk>::iterator it;
        for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
-               delete it->pIndexE;
+               delete [] it->pIndexE;
        m_lChainWalk.clear();
 }
 
+string CChainWalkSet::CheckOrRotatePreCalcFile()
+{
+       char sPreCalcFileName[255];
+
+       // 255 files limit to be sure
+       for (; preCalcPart < 255; preCalcPart++)
+       {
+               sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);
+               string sReturnPreCalcPath(sPreCalcFileName);
+
+               unsigned int fileLen = 0;
+
+               FILE* file = fopen(sReturnPreCalcPath.c_str(), "ab");
+               if(file!=NULL)
+               {
+                       fileLen = GetFileLen(file);
+                       long unsigned int nextFileLen = fileLen + (sizeof(uint64) * (m_nRainbowChainLen-1));
+                       // Rotate to next file if we are going to pass 2GB filesize
+                       if (nextFileLen < ((unsigned)2 * 1024 * 1024 * 1024))
+                       {
+                               // We might want to vPrecalcFiles.push_back(sReturnPreCalcPath) if we just created this file
+                               // We don't as only newly generated chainwalksets will be stored to this new file, so we don't have to look there
+                               if (debug) printf("Debug: Using for precalc: %s\n", sReturnPreCalcPath.c_str());
+                               fclose(file);
+                               return sReturnPreCalcPath;
+                       }
+                       fclose(file);
+               }
+       }
+
+       return string("");
+}
+
+void CChainWalkSet::updateUsedPrecalcFiles()
+{
+       // we might also use this function to search a wildcard path of precalc files
+       vPrecalcFiles.clear();
+       char sPreCalcFileName[255];
+
+       int i;
+       // 255 files max
+       for (i = 0; i < 255; i++)
+       {
+               sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), i);
+               string sTryPreCalcPath(sPreCalcFileName);
+               FILE* file = fopen(sTryPreCalcPath.c_str(), "rb");
+               if(file!=NULL) {
+                       vPrecalcFiles.push_back(sTryPreCalcPath);
+                       fclose(file);
+               }
+               else {
+                       break;
+               }
+       }
+}
+
+void CChainWalkSet::removePrecalcFiles()
+{
+       if (debug) printf("Debug: Removing precalc files.\n");
+       updateUsedPrecalcFiles();
+       string sCurrentPrecalcPathName = "";
+       string sCurrentPrecalcIndexPathName = "";
+       
+       int i;
+       for (i = 0; i < (int)vPrecalcFiles.size(); i++)
+       {
+               sCurrentPrecalcPathName = vPrecalcFiles[i];
+               sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
+
+               if (debug) printf("Debug: Removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
+
+               if (remove(sCurrentPrecalcPathName.c_str()) != 0)
+                       if (debug) printf("Debug: Failed removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());
+
+               if (debug) printf("Debug: Removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
+
+               if (remove(sCurrentPrecalcIndexPathName.c_str()) != 0)
+                       if (debug) printf("Debug: Failed removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());
+
+       }
+}
+
+bool CChainWalkSet::FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
+{
+       int gotPrecalcOnLine = -1;
+       char precalculationLine[255];
+       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() );
+       string precalcString(precalculationLine);
+
+       string sCurrentPrecalcPathName = "";
+       string sCurrentPrecalcIndexPathName = "";
+       long unsigned int offset;
+
+       int i;
+       for (i = 0; i < (int)vPrecalcFiles.size() && gotPrecalcOnLine == -1; i++)
+       {
+               sCurrentPrecalcPathName = vPrecalcFiles[i];
+               sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
+
+               offset = 0;
+
+               vector<string> precalcLines;
+               if (ReadLinesFromFile(sCurrentPrecalcIndexPathName.c_str(), precalcLines))
+               {
+                       int j;
+                       for (j = 0; j < (int)precalcLines.size(); j++)
+                       {
+                               if (precalcString.compare(0, precalcString.size()-1, precalcLines[j]) == 0)
+                               {
+                                       gotPrecalcOnLine = j;
+                                       break;
+                               }
+
+                               // Parse
+                               vector<string> vPart;
+                               if (SeperateString(precalcLines[j], "___:", vPart))
+                               {
+                                       // add to offset
+                                       offset += ((atoi(vPart[3].c_str())-1) * sizeof(uint64));
+                               }
+                               else {
+                                       // corrupt file
+                                       printf("Corrupted precalculation file!\n");
+                                       gotPrecalcOnLine = -1;
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       if (gotPrecalcOnLine > -1)
+       {
+               if (debug) printf("Debug: Reading pre calculations from file, line %d offset %lu\n", gotPrecalcOnLine, offset);
+               
+               FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "rb");
+
+               if (fp!=NULL) {
+                       fseek(fp, offset, SEEK_SET);
+
+                       // We should do some verification here, for example by recalculating the middle chain, to catch corrupted files
+                       if(fread(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1)
+                               printf("File read error.");
+                       fclose(fp);
+               }
+               else
+                       printf("Cannot open precalculation file %s.\n", sCurrentPrecalcPathName.c_str());
+
+               //printf("\npIndexE[0]: %s\n", uint64tostr(pIndexE[0]).c_str());
+               //printf("\npIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pIndexE[m_nRainbowChainLen-2]).c_str());
+
+               return true;
+       }
+
+       return false;
+}
+
+void CChainWalkSet::StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)
+{
+       if (debug) printf("\nDebug: Storing precalc\n");
+       
+       string sCurrentPrecalcPathName = CheckOrRotatePreCalcFile();
+       string sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";
+
+       FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "ab");
+       if(fp!=NULL)
+       {
+               if(fwrite(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1)
+                       printf("File write error.");
+               else
+               {
+                       FILE* file = fopen(sCurrentPrecalcIndexPathName.c_str(), "a");
+                       if (file!=NULL)
+                       {
+                               char precalculationLine[255];
+                               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() );
+                               fputs (precalculationLine, file);
+                               fclose (file);
+                       }
+               }
+               fclose(fp);
+               }
+       else
+               printf("Cannot open precalculation file %s\n", sCurrentPrecalcPathName.c_str());
+}
+
 uint64* CChainWalkSet::RequestWalk(unsigned char* pHash, int nHashLen,
                                                                   string sHashRoutineName,
                                                                   string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax, 
                                                                   int nRainbowTableIndex, 
                                                                   int nRainbowChainLen,
-                                                                  bool& fNewlyGenerated)
+                                                                  bool& fNewlyGenerated,
+                                                                  bool setDebug,
+                                                                  string sPrecalc)
 {
+       debug = setDebug;
+       sPrecalcPathName = sPrecalc;
+
        if (   m_sHashRoutineName   != sHashRoutineName
                || m_sPlainCharsetName  != sPlainCharsetName
                || m_nPlainLenMin       != nPlainLenMin
@@ -63,7 +275,13 @@ uint64* CChainWalkSet::RequestWalk(unsigned char* pHash, int nHashLen,
                cw.pIndexE = new uint64[nRainbowChainLen - 1];
                m_lChainWalk.push_back(cw);
 
-               fNewlyGenerated = true;
+               // Only update this list when we search through another rainbow table
+               updateUsedPrecalcFiles();
+
+               if (!FindInFile(cw.pIndexE, pHash, nHashLen))
+                       fNewlyGenerated = true;
+               else
+                       fNewlyGenerated = false;
                return cw.pIndexE;
        }
 
@@ -82,7 +300,10 @@ uint64* CChainWalkSet::RequestWalk(unsigned char* pHash, int nHashLen,
        cw.pIndexE = new uint64[nRainbowChainLen - 1];
        m_lChainWalk.push_back(cw);
 
-       fNewlyGenerated = true;
+       if (!FindInFile(cw.pIndexE, pHash, nHashLen))
+                       fNewlyGenerated = true;
+               else
+                       fNewlyGenerated = false;
        return cw.pIndexE;
 }
 
index 427689454c9df7b71ae927c9ecb6162225feaecc..6d991fe81fb3bfa6f421800e0e974c646feb0362 100644 (file)
@@ -1,8 +1,27 @@
 /*
-   RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
-
-   Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-*/
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifndef _CHAINWALKSET_H
 #define _CHAINWALKSET_H
@@ -30,9 +49,16 @@ private:
        int    m_nRainbowTableIndex;    // Discard all if not match
        int    m_nRainbowChainLen;              // Discard all if not match
        list<ChainWalk> m_lChainWalk;
+       bool   debug;
+       string sPrecalcPathName;
+       int    preCalcPart;
+       vector<string> vPrecalcFiles;
 
 private:
        void DiscardAll();
+       bool FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen);
+       string CheckOrRotatePreCalcFile();
+       void updateUsedPrecalcFiles();
 
 public:
        uint64* RequestWalk(unsigned char* pHash, int nHashLen,
@@ -40,8 +66,12 @@ public:
                                                string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax, 
                                                int nRainbowTableIndex, 
                                                int nRainbowChainLen,
-                                               bool& fNewlyGenerated);
+                                               bool& fNewlyGenerated,
+                                               bool setDebug,
+                                               string sPrecalc);
        void DiscardWalk(uint64* pIndexE);
+       void StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen);
+       void removePrecalcFiles();
 };
 
 #endif
index e6f92c0c17a586e969c7380fee5bfc9b71ff031d..4815fc6ac83d650de88e160c5fec597682516187 100644 (file)
@@ -175,13 +175,13 @@ void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
        DES_key_schedule ks1,ks2;
        unsigned char deskey_fixed[]={ 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef};
        int i,j;
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__GNUC__)
        strcpy_s(username, sizeof(username), "SYS");
 #else
        strcpy(username, "SYS");
 #endif
        int userlen = 3;
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__GNUC__)
        _strupr((char*) pPlain);
 #else
        strupr((char*) pPlain);
@@ -210,6 +210,7 @@ void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
        memcpy (pHash,iv2,8);
 }
 */
+
 void HashNTLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
 {
        unsigned char UnicodePlain[MAX_PLAIN_LEN * 2];
@@ -392,10 +393,6 @@ void HashPIX(unsigned char* pPlain, int nPlainLen, unsigned char* pHash)
 
        memcpy (pass,pPlain,nPlainLen);
 
-       MD5_CTX ctx;
-       MD5_Init(&ctx);
-       MD5_Update(&ctx, (unsigned char *) pass, MD5_DIGEST_LENGTH);
-       MD5_Final(final, &ctx);
        MD5_NEW((unsigned char *) pass, MD5_DIGEST_LENGTH, final);
 
        char* p = (char*) temp;
index 6d72c4b3813163b281a4d852a2bc83fa67a6484d..72f7f67331798b0ade1620440121df061a46ccfa 100644 (file)
@@ -1,10 +1,29 @@
 /*
-   RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
-   Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-*/
-
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__GNUC__)
        #pragma warning(disable : 4786)
 #endif
 
index 4b53c1474139fe48af90c79cbdbd55f23585ea56..cc0dcdc563e28986215f498b1930f1e952a4f91a 100644 (file)
@@ -1,8 +1,27 @@
 /*
-   RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
-
-   Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-*/
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifndef _HASHROUTINE_H
 #define _HASHROUTINE_H
index 4c8d5c98eeb810e7d06ac81ad017bf8ef12d5e61..a6745073f0e97e9953c510280ac32b405106de2f 100644 (file)
@@ -1,8 +1,28 @@
 /*
-   RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
-
-   Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-*/
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ * Copyright 2010 uroskn
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #include "MemoryPool.h"
 #include "Public.h"
@@ -29,7 +49,7 @@ CMemoryPool::~CMemoryPool()
 #ifdef _MEMORYDEBUG
                printf("Freeing %i bytes of memory\n", m_nMemSize);
 #endif 
-               delete m_pMem;
+               delete [] m_pMem;
                m_pMem = NULL;
                m_nMemSize = 0;
        }
@@ -54,7 +74,7 @@ unsigned char* CMemoryPool::Allocate(unsigned int nFileLen, unsigned int& nAlloc
 #ifdef _MEMORYDEBUG
                printf("Freeing %i bytes of memory\n", m_nMemSize);
 #endif 
-               delete m_pMem;
+               delete [] m_pMem;
                m_pMem = NULL;
                m_nMemSize = 0;
        }
index 9f2ea4ed21f3c0e9532536a903544e161fbad176..d40d5a7d6bcf7fa8f7d927f2396704a01c082c2b 100644 (file)
@@ -1,12 +1,34 @@
 /*
-   RainbowCrack - a general propose implementation of Philippe Oechslin's faster time-memory trade-off technique.
-
-   Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
-*/
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright (C) Zhu Shuanglei <shuanglei@hotmail.com>
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2009, 2010 Daniël Niggebrugge <niggebrugge@fox-it.com>
+ * Copyright 2009, 2010 James Nobis <frt@quelrod.net>
+ * Copyright 2010 uroskn
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
 
 #ifndef _MEMORYPOOL_H
 #define _MEMORYPOOL_H
 
+#include "global.h"
+
 class CMemoryPool  
 {
 public:
@@ -14,6 +36,7 @@ public:
        virtual ~CMemoryPool();
 
 private:
+       bool debug;
        unsigned char* m_pMem;
        unsigned int m_nMemSize;
 
index 834dea77019e5d7aa822df66ed2b02f2909962d5..b42c954918123518222083caa999476cf45c2118 100644 (file)
@@ -11,8 +11,7 @@
  *
  * freerainbowtables is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, either version 2 of the License.
  *
  * freerainbowtables is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -23,7 +22,7 @@
  * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-#ifdef _WIN32
+#if defined(_WIN32) && !defined(__GNUC__)
        #pragma warning(disable : 4786)
 #endif
 
@@ -32,7 +31,7 @@
                #include "boinc_win.h"
        #endif
 #else
-#include "config.h"
+//#include "config.h"
 #include <cstdio>
 #include <cctype>
 #include <ctime>
 
 #ifdef _WIN32
        #include <windows.h>
+#endif
+
+#if defined(_WIN32) && !defined(__GNUC__)
+       #include <windows.h>
+       #include <time.h>
+
+       #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
+               #define DELTA_EPOCH_IN_MICROSECS  11644473600000000Ui64
+       #else
+               #define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL
+       #endif
+       struct timezone
+       {
+               int  tz_minuteswest; /* minutes W of Greenwich */
+               int  tz_dsttime;     /* type of dst correction */
+       };
+       int gettimeofday(struct timeval *tv, struct timezone *tz)
+       {
+               // Define a structure to receive the current Windows filetime
+               FILETIME ft;
+               // Initialize the present time to 0 and the timezone to UTC
+               unsigned __int64 tmpres = 0;
+               static int tzflag = 0;
+               if (NULL != tv)
+               {
+                       GetSystemTimeAsFileTime(&ft);
+                       // The GetSystemTimeAsFileTime returns the number of 100 nanosecond 
+                       // intervals since Jan 1, 1601 in a structure. Copy the high bits to 
+                       // the 64 bit tmpres, shift it left by 32 then or in the low 32 bits.
+                       tmpres |= ft.dwHighDateTime;
+                       tmpres <<= 32;
+                       tmpres |= ft.dwLowDateTime;
+                       // Convert to microseconds by dividing by 10
+                       tmpres /= 10;
+                       // The Unix epoch starts on Jan 1 1970.  Need to subtract the difference 
+                       // in seconds from Jan 1 1601.
+                       tmpres -= DELTA_EPOCH_IN_MICROSECS;
+        
+                       // Finally change microseconds to seconds and place in the seconds value. 
+                       // The modulus picks up the microseconds.
+                       tv->tv_sec = (long)(tmpres / 1000000UL);
+                       tv->tv_usec = (long)(tmpres % 1000000UL);
+               }
+        
+               if (NULL != tz)
+               {
+                       if (!tzflag)
+                       {
+                               _tzset();
+                               tzflag++;
+                       }
+         
+                       // Adjust for the timezone west of Greenwich
+                       tz->tz_minuteswest = _timezone / 60;
+                       tz->tz_dsttime = _daylight;
+               }
+        
+               return 0;
+       }
+
 #elif defined(__APPLE__) || \
        ((defined(__unix__) || defined(unix)) && !defined(USG))
 
        #elif defined(__linux__)
                #include <sys/sysinfo.h>
        #else
-               #error Unsupported Operating system
+               #error Unsupported Operating System
        #endif
 #endif
 
 //////////////////////////////////////////////////////////////////////
 
-unsigned int GetFileLen(FILE* file)
+timeval sub_timeofday( timeval tv2, timeval tv )
 {
-       unsigned int pos = ftell(file);
+       timeval final;
+
+       final.tv_usec = tv2.tv_usec - tv.tv_usec;
+       final.tv_sec = tv2.tv_sec - tv.tv_sec;
+
+       if ( final.tv_usec < 0 )
+       {
+               final.tv_usec += 1000000;
+               --final.tv_sec;
+       }
+
+       return final;
+}
+
+long GetFileLen(FILE* file)
+{
+       // XXX on x86/x86_64 linux returns long
+       // 32-bit this is a problem if the file is > (2^31-1) bytes
+       long pos = ftell(file);
        fseek(file, 0, SEEK_END);
-       unsigned int len = ftell(file);
+       long len = ftell(file);
        fseek(file, pos, SEEK_SET);
 
        return len;
@@ -102,12 +186,12 @@ bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset)
        if(sCharset.substr(0, 6) != "hybrid") // Not hybrid charset
                return false;
 
-       UINT4 nEnd = (int) sCharset.rfind(')');
-       UINT4 nStart = (int) sCharset.rfind('(');
+       string::size_type nEnd = sCharset.rfind(')');
+       string::size_type nStart = (int) sCharset.rfind('(');
        string sChar = sCharset.substr(nStart + 1, nEnd - nStart - 1);
        vector<string> vParts;
        SeperateString(sChar, ",", vParts);
-       for(UINT4 i = 0; i < vParts.size(); i++)
+       for(uint32 i = 0; i < vParts.size(); i++)
        {
                tCharset stCharset;
                vector<string> vParts2;
@@ -125,6 +209,7 @@ bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset)
 bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine)
 {
        vLine.clear();
+#ifdef 0
        vLine.push_back("byte                        = []");
        vLine.push_back("alpha                       = [ABCDEFGHIJKLMNOPQRSTUVWXYZ]");
        vLine.push_back("alpha-space                 = [ABCDEFGHIJKLMNOPQRSTUVWXYZ ]");
@@ -155,8 +240,9 @@ bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine)
        vLine.push_back("mixalpha-numeric-all        = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x2D\x5F\x2B\x3D\x7E\x60\x5B\x5D\x7B\x7D\x7C\x5C\x3A\x3B\x22\x27\x3C\x3E\x2C\x2E\x3F\x2F]");
        vLine.push_back("mixalpha-numeric-symbol32-space  = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x2D\x5F\x2B\x3D\x7E\x60\x5B\x5D\x7B\x7D\x7C\x5C\x3A\x3B\x22\x27\x3C\x3E\x2C\x2E\x3F\x2F\x20]");
        vLine.push_back("mixalpha-numeric-all-space  = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x2D\x5F\x2B\x3D\x7E\x60\x5B\x5D\x7B\x7D\x7C\x5C\x3A\x3B\x22\x27\x3C\x3E\x2C\x2E\x3F\x2F\x20]");
+#endif
 
-/*     char input_path[512];
+       char input_path[512];
        boinc_resolve_filename(sPathName.c_str(), input_path, sizeof(input_path));
        FILE *file = boinc_fopen(input_path, "rb");
        if (!file) {
@@ -183,8 +269,8 @@ bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine)
                                content[i] = '\n';
                }
 
-               int n;
-               while ((n = content.find("\n", 0)) != -1)
+               string::size_type n;
+               while ((n = content.find("\n", 0)) != string::npos)
                {
                        string line = content.substr(0, n);
                        line = TrimString(line);
@@ -197,14 +283,15 @@ bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine)
        }
        else
                return false;
-               */
+
        return true;
 }
-#endif 
+#endif
 bool ReadLinesFromFile(string sPathName, vector<string>& vLine)
 {
        vLine.clear();
-    FILE *file = fopen(sPathName.c_str(), "rb");
+
+       FILE* file = fopen(sPathName.c_str(), "rb");
        if (file != NULL)
        {
                unsigned int len = GetFileLen(file);
@@ -213,7 +300,7 @@ bool ReadLinesFromFile(string sPathName, vector<string>& vLine)
                data[len] = '\0';
                string content = data;
                content += "\n";
-               delete data;
+               delete [] data;
 
                unsigned int i;
                for (i = 0; i < content.size(); i++)
@@ -222,8 +309,8 @@ bool ReadLinesFromFile(string sPathName, vector<string>& vLine)
                                content[i] = '\n';
                }
 
-               int n;
-               while ((n = content.find("\n", 0)) != -1)
+               string::size_type n;
+               while ((n = content.find("\n", 0)) != string::npos)
                {
                        string line = content.substr(0, n);
                        line = TrimString(line);
@@ -240,6 +327,19 @@ bool ReadLinesFromFile(string sPathName, vector<string>& vLine)
        return true;
 }
 
+bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary)
+{
+       FILE* file = fopen(sOutputFile.c_str(), "a");
+       if (file!=NULL)
+       {
+               string buffer = sHash + ":" + sPlain + ":" + sBinary + "\n";
+               fputs (buffer.c_str(), file);
+               fclose (file);
+               return true;
+       }
+       else
+               return false;
+}
 
 bool SeperateString(string s, string sSeperator, vector<string>& vPart)
 {
@@ -248,14 +348,18 @@ bool SeperateString(string s, string sSeperator, vector<string>& vPart)
        unsigned int i;
        for (i = 0; i < sSeperator.size(); i++)
        {
-               int n = s.find(sSeperator[i]);
-               if (n != -1)
+               string::size_type n;
+               if ( (n = s.find(sSeperator[i])) != string::npos)
                {
                        vPart.push_back(s.substr(0, n));
                        s = s.substr(n + 1);
                }
                else
+               {
+                       printf("not found: %c\n", sSeperator[i]);
+                       printf("s: %s\n", s.c_str());
                        return false;
+               }
        }
        vPart.push_back(s);
 
@@ -302,16 +406,27 @@ string HexToStr(const unsigned char* pData, int nLen)
        return sRet;
 }
 
-unsigned int GetAvailPhysMemorySize()
+unsigned long GetAvailPhysMemorySize()
 {
 #ifdef _WIN32
-               MEMORYSTATUS ms;
-               GlobalMemoryStatus(&ms);
-               return ms.dwAvailPhys;
-#else
+       MEMORYSTATUS ms;
+       GlobalMemoryStatus(&ms);
+       return ms.dwAvailPhys;
+#elif defined(BSD)
+       int mib[2] = { CTL_HW, HW_PHYSMEM };
+       uint64 physMem;
+       //XXX warning size_t isn't portable
+       size_t len;
+       len = sizeof(physMem);
+       sysctl(mib, 2, &physMem, &len, NULL, 0);
+       return physMem;
+#elif defined(__linux__)
        struct sysinfo info;
-       sysinfo(&info);                 // This function is Linux-specific
-       return info.freeram;
+       sysinfo(&info);
+       return ( info.freeram + info.bufferram ) * (unsigned long) info.mem_unit;
+#else
+       return 0;
+       #error Unsupported Operating System
 #endif
 }
 
@@ -333,12 +448,12 @@ string GetApplicationPath()
 
        string sApplicationPath = fullPath;
 #ifdef _WIN32
-       int nIndex = sApplicationPath.find_last_of('\\');
+       string::size_type nIndex = sApplicationPath.find_last_of('\\');
 #else
-       int nIndex = sApplicationPath.find_last_of('/');
+       string::size_type nIndex = sApplicationPath.find_last_of('/');
 #endif
 
-       if ( nIndex != -1 )
+       if ( nIndex != string::npos )
                sApplicationPath = sApplicationPath.substr(0, nIndex+1);
 
        return sApplicationPath;
@@ -355,7 +470,7 @@ void ParseHash(string sHash, unsigned char* pHash, int& nHashLen)
                pHash[i] = (unsigned char)nValue;
        }
 
-       nHashLen = sHash.size() / 2;
+       nHashLen = (int) sHash.size() / 2;
 }
 
 void Logo()
@@ -366,3 +481,59 @@ void Logo()
        printf("original code by Zhu Shuanglei <shuanglei@hotmail.com>\n");
        printf("http://www.antsight.com/zsl/rainbowcrack/\n\n");
 }
+
+// XXX nmap is GPL2, will check newer releases regarding license
+// Code comes from nmap, used for the linux implementation of kbhit()
+#ifndef _WIN32
+
+static int tty_fd = 0;
+struct termios saved_ti;
+
+int tty_getchar()
+{
+       int c, numChars;
+
+       if (tty_fd && tcgetpgrp(tty_fd) == getpid()) {
+               c = 0;
+               numChars = read(tty_fd, &c, 1);
+               if (numChars > 0) return c;
+       }
+
+       return -1;
+}
+
+void tty_done()
+{
+       if (!tty_fd) return;
+
+       tcsetattr(tty_fd, TCSANOW, &saved_ti);
+
+       close(tty_fd);
+       tty_fd = 0;
+}
+
+void tty_init()
+{
+       struct termios ti;
+
+       if (tty_fd)
+               return;
+
+       if ((tty_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return;
+
+       tcgetattr(tty_fd, &ti);
+       saved_ti = ti;
+       ti.c_lflag &= ~(ICANON | ECHO);
+       ti.c_cc[VMIN] = 1;
+       ti.c_cc[VTIME] = 0;
+       tcsetattr(tty_fd, TCSANOW, &ti);
+
+       atexit(tty_done);
+}
+
+void tty_flush(void)
+{
+       tcflush(tty_fd, TCIFLUSH);
+}
+// end nmap code
+#endif
index b3103f7d3dda3cedba6f0f9037081448af467967..6708d3ad70815b33745fc2b6e31657b7f3e9f918 100644 (file)
@@ -10,8 +10,7 @@
  *
  * freerainbowtables is free software: you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 2 of the License, or
- * (at your option) any later version.
+ * the Free Software Foundation, either version 2 of the License.
  *
  * freerainbowtables is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -52,8 +51,8 @@ struct RainbowChainCP
 struct IndexChain
 {
        uint64 nPrefix;
-       UINT4 nFirstChain;
-       UINT4 nChainCount;
+       uint32 nFirstChain;
+       uint32 nChainCount;
 };
 struct FoundRainbowChain
 {
@@ -85,7 +84,32 @@ typedef struct
 #define MAX_HASH_LEN  256
 #define MAX_SALT_LEN  256
 
-unsigned int GetFileLen(FILE* file);
+// XXX nmap is GPL2, will check newer releases regarding license
+// Code comes from nmap, used for the linux implementation of kbhit()
+#ifndef _WIN32
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+
+int tty_getchar();
+void tty_done();
+void tty_init();
+void tty_flush(void);
+// end nmap code
+
+#endif
+
+#if defined(_WIN32) && !defined(__GNUC__)
+       int gettimeofday( struct timeval *tv, struct timezone *tz );
+#endif
+
+#if !defined(_WIN32) || defined(__GNUC__)
+       #include <sys/time.h>
+#endif
+
+timeval sub_timeofday( timeval tv2, timeval tv );
+
+long GetFileLen(FILE* file);
 string TrimString(string s);
 bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine);
 bool ReadLinesFromFile(string sPathName, vector<string>& vLine);
@@ -93,10 +117,11 @@ bool SeperateString(string s, string sSeperator, vector<string>& vPart);
 string uint64tostr(uint64 n);
 string uint64tohexstr(uint64 n);
 string HexToStr(const unsigned char* pData, int nLen);
-unsigned int GetAvailPhysMemorySize();
+unsigned long GetAvailPhysMemorySize();
 string GetApplicationPath();
 void ParseHash(string sHash, unsigned char* pHash, int& nHashLen);
 bool GetHybridCharsets(string sCharset, vector<tCharset>& vCharset);
 void Logo();
+bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary);
 
 #endif
index 004159ceba7b65506461157d43844233f13cc008..ad7db3dd12e31621d0abea5faa4dda2227efa90e 100644 (file)
@@ -1,6 +1,30 @@
+/*
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #include "RTI2Reader.h"
 
 #include <math.h>
+
 RTI2Header *RTI2Reader::m_pHeader = NULL;
 RTI2Reader::RTI2Reader(string Filename)
 {
@@ -20,15 +44,15 @@ RTI2Reader::RTI2Reader(string Filename)
        }
        m_chainPosition = 0;
 
-       unsigned int len = GetFileLen(pFileIndex);
+       long len = GetFileLen(pFileIndex);
        fseek(pFileIndex, 0, SEEK_SET);
 
        m_pIndex = new (nothrow) unsigned char[len];
        if(m_pIndex == NULL) {
-               printf("Error allocating %u MB memory for index in RTI2Reader::RTI2Reader()", len / (1024 * 1024));
+               printf("Error allocating %ld MB memory for index in RTI2Reader::RTI2Reader()", len / (1024 * 1024));
                exit(-2);
        }
-       if(fread(m_pIndex, 1, len, pFileIndex) != len)
+       if(fread(m_pIndex, 1, len, pFileIndex) != (unsigned long)len)
        {
                printf("Error while reading index file");
                exit(1);
@@ -38,15 +62,15 @@ RTI2Reader::RTI2Reader(string Filename)
        memcpy(m_pHeader, m_pIndex, sizeof(RTI2Header));
        m_pHeader->m_cppos = (unsigned int*)(m_pIndex + 8);
        m_pHeader->prefixstart = *(uint64*)(m_pIndex + 8 + (m_pHeader->rti_cplength * 4));
-       m_chainsizebytes = ceil((float)(m_pHeader->rti_startptlength + m_pHeader->rti_endptlength + m_pHeader->rti_cplength) / 8); // Get the size of each chain in bytes
-       m_indexrowsizebytes = ceil((float)m_pHeader->rti_index_numchainslength / 8);
+       m_chainsizebytes = (uint32)ceil((float)(m_pHeader->rti_startptlength + m_pHeader->rti_endptlength + m_pHeader->rti_cplength) / 8); // Get the size of each chain in bytes
+       m_indexrowsizebytes = (uint32)ceil((float)m_pHeader->rti_index_numchainslength / 8);
        // Check the filesize
        fseek(m_pFile, 0, SEEK_END);
        len = ftell(m_pFile);
        fseek(m_pFile, 0, SEEK_SET);
        if(len % m_chainsizebytes > 0)
        {
-               printf("Invalid filesize %u\n", len);
+               printf("Invalid filesize %lu\n", len);
                return;
        }
        
@@ -62,7 +86,7 @@ RTI2Reader::~RTI2Reader(void)
 
 unsigned int RTI2Reader::GetChainsLeft()
 {
-       int len = GetFileLen(m_pFile);
+       long len = GetFileLen(m_pFile);
        return len / m_chainsizebytes - m_chainPosition;
 }
 
@@ -82,7 +106,12 @@ int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChain *pData)
        {
                // ALERT: Possible problem here if m_indexrowsizebytes > 1 as pNumChains is a unsigned char.
                unsigned int NumChainsInRow = (unsigned int)*(pNumChains + indexRow * m_indexrowsizebytes);
-               if(m_indexrowsizebytes > 1)     { printf("Have to find a solution to this problem"); exit(2);}
+               if(m_indexrowsizebytes > 1)
+               {
+                       //XXX Have to find a solution to this problem
+                       printf( "FATAL: m_indexrowsizebytes > 1: %d\n", m_indexrowsizebytes ); 
+                       exit(2);
+               }
                if(i + NumChainsInRow > m_chainPosition)
                {
                        curRowPosition = m_chainPosition - i;
@@ -95,7 +124,7 @@ int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChain *pData)
        uint64 chainrow = 0; // Buffer to store a single read chain
        unsigned int chainsProcessed = 0; // Number of chains processed
 
-       // ALERT: same problem with unsigned char here.
+       // XXX: same problem with unsigned char here.
        unsigned int NumChainsInRow = *(pNumChains + indexRow);
        while(chainsProcessed < numChains && fread(&chainrow, 1, m_chainsizebytes, m_pFile) == m_chainsizebytes)
        {
@@ -112,13 +141,17 @@ int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChain *pData)
                        curRowPosition = 0;
                }
                // Load the starting point from the data
-               pData[chainsProcessed].nIndexS = chainrow << 64 - m_pHeader->rti_startptlength;
-               pData[chainsProcessed].nIndexS = pData[chainsProcessed].nIndexS >> 64 - m_pHeader->rti_startptlength;
+               pData[chainsProcessed].nIndexS = chainrow << ( 64 - m_pHeader->rti_startptlength );
+               pData[chainsProcessed].nIndexS = pData[chainsProcessed].nIndexS >> ( 64 - m_pHeader->rti_startptlength );
 
                // Load the ending point prefix 
-               pData[chainsProcessed].nIndexE = m_pHeader->prefixstart + indexRow << m_pHeader->rti_endptlength;
+               pData[chainsProcessed].nIndexE = ( m_pHeader->prefixstart + indexRow ) << m_pHeader->rti_endptlength;
                // Append the ending point suffix
-               pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFF >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
+#if defined(_WIN32) && !defined(__GNUC__)
+               pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFI64 >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
+#else
+               pData[chainsProcessed].nIndexE |= (chainrow & (0xFFFFFFFFFFFFFFFFllu >> m_pHeader->rti_cplength)) >> m_pHeader->rti_startptlength;
+#endif
                //pData[chainsProcessed].nCheckPoint = (chainrow >> m_pHeader->rti_startptlength + m_pHeader->rti_endptlength);
                curRowPosition++;
                chainsProcessed++;
index 0b1f127471e2c7886f6c5742f1bc6844da1a12ea..db3d446a126ad8fd7ed222ed5e91ae781eadccbd 100644 (file)
@@ -1,13 +1,39 @@
+/*
+ * freerainbowtables is a project for generating, distributing, and using
+ * perfect rainbow tables
+ *
+ * Copyright 2010 Martin Westergaard Jørgensen <martinwj2005@gmail.com>
+ * Copyright 2010 James Nobis <frt@quelrod.net>
+ *
+ * This file is part of freerainbowtables.
+ *
+ * freerainbowtables is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * freerainbowtables is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with freerainbowtables.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
 #ifndef __RTI2READER_H__
 #define __RTI2READER_H__
 
 #include "Public.h"
 #include <string>
-#ifdef WIN32
-#include <io.h>
+
+#if defined(_WIN32) && !defined(__GNUC__)
+       #include <io.h>
 #endif
+
 #include <vector>
 #include "BaseRTReader.h"
+
 using namespace std;
 
 typedef struct 
@@ -22,18 +48,18 @@ class RTI2Reader : BaseRTReader
 {
 private:
        FILE *m_pFile;
-       unsigned int m_chainPosition;
+       uint32 m_chainPosition;
        unsigned char *m_pPos, *m_pChainPos;
        static RTI2Header *m_pHeader;
        unsigned char *m_pIndex;
-       unsigned int m_chainsizebytes;
-       unsigned int m_indexrowsizebytes;
+       uint32 m_chainsizebytes;
+       uint32 m_indexrowsizebytes;
        
 
 public:
        RTI2Reader(string Filename);
        ~RTI2Reader(void);
-       int ReadChains(UINT4 &numChains, RainbowChain *pData);
+       int ReadChains(uint32 &numChains, RainbowChain *pData);
        unsigned int GetChainsLeft();
        static RTI2Header *GetHeader() { return m_pHeader; }
 };
index 3134e918cde56d464746f00a9315ff5443ecb6c7..374b062b5696ea6fa54144fff99cfd8eb7b87838 100644 (file)
@@ -17,16 +17,16 @@ RTIReader::RTIReader(string Filename)
        m_chainPosition = 0;
 
        // Load the index file
-       unsigned int nIndexFileLen = GetFileLen(pFileIndex);
-       unsigned int nFileLen = GetFileLen(m_pFile);
+       long nIndexFileLen = GetFileLen(pFileIndex);
+       long nFileLen = GetFileLen(m_pFile);
        unsigned int nTotalChainCount = nFileLen / 8;
        if (nFileLen % 8 != 0)
-               printf("file length mismatch (%u bytes)\n", nFileLen);
+               printf("file length mismatch (%lu bytes)\n", nFileLen);
        else
        {
                // File length check
                if (nIndexFileLen % 11 != 0)
-                       printf("index file length mismatch (%u bytes)\n", nIndexFileLen);
+                       printf("index file length mismatch (%lu bytes)\n", nIndexFileLen);
                else
                {
                        if(m_pIndex != NULL) {
@@ -38,7 +38,7 @@ RTIReader::RTIReader(string Filename)
 #endif
                        m_pIndex = new (nothrow) IndexChain[nIndexFileLen / 11];
                        if(m_pIndex == NULL) {
-                               printf("\nFailed allocating %i MB memory.\n", nIndexFileLen / 11 / (1024 * 1024));
+                               printf("\nFailed allocating %ld MB memory.\n", nIndexFileLen / 11 / (1024 * 1024));
                                exit(-2);
                        }
 #ifdef _MEMORYDEBUG
@@ -46,9 +46,9 @@ RTIReader::RTIReader(string Filename)
 #endif                 
                        memset(m_pIndex, 0x00, sizeof(IndexChain) * (nIndexFileLen / 11));
                        fseek(pFileIndex, 0, SEEK_SET);
-                       int nRead = 0;
-                       UINT4 nRows;
-                       for(nRows = 0; (nRows * 11) < nIndexFileLen; nRows++)
+                       //int nRead = 0;
+                       uint32 nRows;
+                       for(nRows = 0; (nRows * 11) < (uint32)nIndexFileLen; nRows++)
                        {
                                if(fread(&m_pIndex[nRows].nPrefix, 5, 1, pFileIndex) != 1) break;                                                       
                                if(fread(&m_pIndex[nRows].nFirstChain, 4, 1, pFileIndex) != 1) break;                                                   
index 7a6f91a1bde0a98d578269e0c7e2d7c3f7f86b42..c4d6c38c5e04355e8087966b472895d5c66461d2 100644 (file)
     (a) = ROTATE_LEFT ((a), (s)); \
   }
 #define GG(a, b, c, d, x, s) { \
-    (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \
+    (a) += G ((b), (c), (d)) + (x) + (uint32)0x5a827999; \
     (a) = ROTATE_LEFT ((a), (s)); \
   }
 #define HH(a, b, c, d, x, s) { \
-    (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \
+    (a) += H ((b), (c), (d)) + (x) + (uint32)0x6ed9eba1; \
     (a) = ROTATE_LEFT ((a), (s)); \
   }
 #define S11 3
 void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
 {
        // For the hash working space
-       UINT4 b0,b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
+       uint32 b0,b1, b2, b3, b4, b5, b6, b7, b8, b9, b10, b11, b12, b13, b14, b15;
 
        // For the output result
-       UINT4 a,b,c,d;
+       uint32 a,b,c,d;
 
        b0 = 0x00000000;
        b1 = 0x00000000;
@@ -76,7 +76,7 @@ void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
                        memcpy(in, pData, length);
                        in[2] = 0x80;
                        in[3] = 0x00;
-                       UINT4 * pUiIn = (UINT4 *) in;
+                       uint32 * pUiIn = (uint32 *) in;
                        b0 = pUiIn[0];
                }
                break;
@@ -84,7 +84,7 @@ void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
                {
                        unsigned char in[4];
                        memcpy(in, pData, length);
-                       UINT4 * pUiIn = (UINT4 *) in;
+                       uint32 * pUiIn = (uint32 *) in;
                        b0 = pUiIn[0];
                        b1 = 0x00000080;
                }
@@ -95,7 +95,7 @@ void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
                        memcpy(in, pData, length);
                        in[6] = 0x80;
                        in[7] = 0x00;
-                       UINT4 * pUiIn = (UINT4 *) in;
+                       uint32 * pUiIn = (uint32 *) in;
                        b0 = pUiIn[0];
                        b1 = pUiIn[1];
                }
@@ -104,7 +104,7 @@ void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
                {
                        unsigned char in[8];
                        memcpy(in, pData, length);
-                       UINT4 * pUiIn = (UINT4 *) in;
+                       uint32 * pUiIn = (uint32 *) in;
                        b0 = pUiIn[0];
                        b1 = pUiIn[1];
                        b2 = 0x00000080;
@@ -116,7 +116,7 @@ void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
                        memcpy(in, pData, length);
                        in[10] = 0x80;
                        in[11] = 0x00;
-                       UINT4 * pUiIn = (UINT4 *) in;
+                       uint32 * pUiIn = (uint32 *) in;
                        b0 = pUiIn[0];
                        b1 = pUiIn[1];
                        b2 = pUiIn[2];
@@ -128,7 +128,7 @@ void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
                        memcpy(in, pData, length);
                        in[length] = 0x80;
                        memset(in + length + 1, 0, 32 - length - 1);
-                       UINT4 * pUiIn = (UINT4 *) in;
+                       uint32 * pUiIn = (uint32 *) in;
                        b0 = pUiIn[0];
                        b1 = pUiIn[1];
                        b2 = pUiIn[2];
@@ -209,7 +209,7 @@ void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest)
        c += 0x98badcfe;
        d += 0x10325476;
 
-       UINT4 buf[4] = { a, b, c, d};
+       uint32 buf[4] = { a, b, c, d};
        memcpy(pDigest, buf, 16);
 
        return;