]> 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

21 files changed:
1  2 
Client Applications/converti2/Makefile
Client Applications/converti2/Public.cpp
Client Applications/converti2/Public.h
Client Applications/converti2/converti2.cpp
Client Applications/converti2/converti2.suo
Client Applications/rcracki_mt/BaseRTReader.h
Client Applications/rcracki_mt/ChainWalkSet.cpp
Client Applications/rcracki_mt/CrackEngine.cpp
Client Applications/rcracki_mt/HashAlgorithm.cpp
Client Applications/rcracki_mt/MemoryPool.cpp
Client Applications/rcracki_mt/Public.cpp
Client Applications/rcracki_mt/RTI2Reader.cpp
Client Applications/rcracki_mt/RTI2Reader.h
Client Applications/rti2rto/Makefile
Client Applications/rti2rto/rti2rto.cpp
Common/rt api/BaseRTReader.h
Common/rt api/MemoryPool.cpp
Common/rt api/Public.cpp
Common/rt api/RTI2Reader.cpp
Common/rt api/RTI2Reader.h
Common/rt api/RTIReader.cpp

index 632326701d7ac2ae287116a9d37bae0f5fae458f,d3715df887e3b7ffc361adb2f59babe1375454ee..4886c1a12d5011194f4dd31f9265eb51d1a34189
@@@ -3,10 -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,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 --combined Client Applications/converti2/Public.cpp
index 7e5420366852e2dd76ecabfd63496eaffacd3b09,7e5420366852e2dd76ecabfd63496eaffacd3b09..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,319 -1,319 +1,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 --combined Client Applications/converti2/Public.h
index 6c15430388ee3fa4c8f2e9ee0cf956463c663011,6c15430388ee3fa4c8f2e9ee0cf956463c663011..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,113 -1,113 +1,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
index db703e92d243a16dd46cbd0fa6475758f49fc0c9,1d8d5e79619444325b3bea2cda1c423df42190a3..da728c319c8d762f44d9b02834729ad6c7158375
mode 100644,100644..100755
@@@ -1,8 -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>
  #include <time.h>
  #include <math.h>
  #include <vector>
 -#include <conio.h>
+ #include <sstream>
  #include "Public.h"
  #include "MemoryPool.h"
+ #include "RTIReader.h"
+ #include "RTReader.h"
  
  using namespace std;
  
@@@ -246,13 -248,10 +248,10 @@@ void GetTableList(string sWildCharPathN
  
        _finddata_t fd;
        long handle = _findfirst(sWildCharPathName.c_str(), &fd);
-       if (handle != -1)
-       {
-               do
-               {
+       if (handle != -1) {
+               do      {
                        string sName = fd.name;
-                       if (sName != "." && sName != ".." && !(fd.attrib & _A_SUBDIR))
-                       {
+                       if (sName != "." && sName != ".." && !(fd.attrib & _A_SUBDIR))  {
                                string sPathName = sPath + sName;
                                vPathName.push_back(sPathName);
                        }
@@@ -290,108 -289,93 +289,93 @@@ void ConvertRainbowTable(string sPathNa
        int nIndex = sPathName.find_last_of('/');
  #endif
        string sFileName;
-       if (nIndex != -1)
+       if (nIndex != -1) {
                sFileName = sPathName.substr(nIndex + 1);
-       else
+       }
+       else {
                sFileName = sPathName;
-       // Info
-       printf("%s:\n", sFileName.c_str());
-       FILE* file = fopen(sPathName.c_str(), "rb");
-       FILE* fileR = fopen(sResultFileName.c_str(), "wb");
+       }
        unsigned int distribution[64] = {0};
        unsigned int numProcessedChains = 0;
-       
-       if (file != NULL && fileR != NULL)
-       {
+       FILE* fileR;
+       BaseRTReader *reader = NULL;
+       if(sPathName.substr(sPathName.length() - 2, sPathName.length()) == "rt")
+               reader = (BaseRTReader*)new RTReader(sPathName);
+       else if(sPathName.substr(sPathName.length() - 3, sPathName.length()) == "rti")
+               reader = (BaseRTReader*)new RTIReader(sPathName);
+       if(reader == NULL) {
+               printf("%s is not a supported file (Only RT and RTI is supported)\n", sPathName.c_str());
+               return;
+       }
+       // Info
+       printf("%s:\n", sFileName.c_str());
+       if(showDistribution == 0) {
+               fileR = fopen(sResultFileName.c_str(), "wb");
+       }
+       if (fileR != NULL || showDistribution == 1) {
                // File length check
-               UINT4 nFileLen = GetFileLen(file);
-               UINT4 nTotalChainCount = 0;
-               if(hascp == 0) nTotalChainCount = nFileLen / 16;
-               else nTotalChainCount = nFileLen / 18;
-               if ((hascp == 0 && nFileLen % 16 != 0) || (hascp == 1 && nFileLen % 18 != 0))
-               {
-                       printf("file length mismatch\n");
-               }
-               else
-               {
+               int size = reader->GetChainsLeft() * sizeof(RainbowChain);
                        static CMemoryPool mp;
                        unsigned int nAllocatedSize;
-                       RainbowChainCP* pChain = (RainbowChainCP*)mp.Allocate(nFileLen, nAllocatedSize);
-                       
-                       unsigned int chainrowsize = ceil((float)(rti_startptlength + rti_endptlength + rti_cplength) / 8) * 8 ; // The size in bits (in whole bytes)
+                       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)
-                       {
-                               nAllocatedSize = nAllocatedSize / sizeof(RainbowChainCP) * sizeof(RainbowChainCP);
-                               fseek(file, 0, SEEK_SET);
+                       if (pChain != NULL)     {
+                               nAllocatedSize = nAllocatedSize / sizeof(RainbowChain) * sizeof(RainbowChain);
+                               unsigned int nChains = nAllocatedSize / sizeof(RainbowChain);
                                uint64 curPrefix = 0, prefixStart = 0;
                                vector<IndexRow> indexes;
-                               UINT4 nRainbowChainCountRead = 0;
-                               while (true)    // Chunk read loop
-                               {
+                               unsigned int chainsLeft;
+                               while((chainsLeft = reader->GetChainsLeft()) > 0) {
+                                       
  /*                                    if (ftell(file) == nFileLen)
                                                break;*/
-                                       UINT4 nReadThisRound;
-                                       memset(pChain, 0x00, nAllocatedSize);
-                                       printf("reading...\n");
+                                       printf("%u chains left to read\n", chainsLeft);
 -                                      int nReadThisRound;
++                                      //int nReadThisRound;
                                        clock_t t1 = clock();
-                                       for(nReadThisRound = 0; nReadThisRound < nAllocatedSize / sizeof(RainbowChainCP) && nRainbowChainCountRead < nTotalChainCount; nReadThisRound++)
-                                       {                                               
-                                               if(fread(&pChain[nReadThisRound], 16, 1, file) != 1) 
-                                               { 
-                                                       printf("Error reading file\n"); exit(1);
-                                               }
-                                               if(hascp == 1)
-                                               {
-                                                       if(fread(&pChain[nReadThisRound].nCheckPoint, 2, 1, file) != 1) 
-                                                       { 
-                                                               printf("Error reading file\n"); exit(2);
-                                                       }
-                                               }
-                                               nRainbowChainCountRead++;
-                                       }
+                                       printf("reading...\n");
+ #ifdef _MEMORYDEBUG
+                       printf("Grabbing %i chains from file\n", nChains);
+ #endif
+                                       reader->ReadChains(nChains, pChain);
+ #ifdef _MEMORYDEBUG
+                       printf("Recieved %i chains from file\n", nChains);
+ #endif
                                        clock_t t2 = clock();
                                        float fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
-                                       int nDataRead = nRainbowChainCountRead * 16;
-                                       if(hascp == 1) nDataRead += nRainbowChainCountRead * 2; // Add the index readings too
-                                       printf("%u bytes read, disk access time: %.2f s\n", nDataRead , fTime);
+                                       printf("reading time: %.2f s\n", fTime);                
+                                       printf("converting %i chains...\n", nChains);
                                        t1 = clock();
-                                       for(UINT4 i = 0; i < nReadThisRound; i++)
-                                       {
-                                               if(showDistribution == 1)
-                                               {
 -                                      for(int i = 0; i < nChains; i++)        {
++                                      for(unsigned int i = 0; i < nChains; i++)       {
+                                               if(showDistribution == 1) {
                                                        distribution[GetMaxBits(pChain[i].nIndexS)-1]++;
                                                }
                                                else
                                                {
                                                        uint64 chainrow = pChain[i].nIndexS; // Insert the complete start point                                                          
                                                        chainrow |= ((uint64)pChain[i].nIndexE & (0xffffffff >> (32 - rti_endptlength))) << rti_startptlength; // 
-                                                       if(hascp == 1 && rti_cplength > 0) 
-                                                       {
+ /*                                                    if(hascp == 1 && rti_cplength > 0) {
                                                                chainrow |= (uint64)pChain[i].nCheckPoint << rti_startptlength + rti_endptlength;
-                                                       }
+                                                       }*/
                                                        fwrite(&chainrow, 1, chainrowsizebytes, fileR);                 
                                                        uint64 prefix = pChain[i].nIndexE >> rti_endptlength;
                                                        if(i == 0) curPrefix = prefix;
-                                                       if(prefix != curPrefix && numProcessedChains - prefixStart > 0)
-                                                       {
-                                                                       if(prefix < curPrefix)
-                                                                       {
-                                                                               printf("**** Error writeChain(): Prefix is smaller than previous prefix. %llu < %llu****\n", prefix, curPrefix);
-                                                                               exit(1);                                                                        
-                                                                       }
-                                                                       //unsigned char index[11] = {0}; // [0 - 10]
-                                                                       unsigned int numchains = numProcessedChains - prefixStart;
-                                                                       IndexRow index;
-                                                                       index.prefix = curPrefix;
+                                                       if(prefix != curPrefix && numProcessedChains - prefixStart > 0) {
+                                                               if(prefix < curPrefix) {
+                                                                       printf("**** Error writeChain(): Prefix is smaller than previous prefix. %llu < %llu****\n", prefix, curPrefix);
+                                                                       exit(1);                                                                        
+                                                               }
+                                                               //unsigned char index[11] = {0}; // [0 - 10]
+                                                               unsigned int numchains = numProcessedChains - prefixStart;
+                                                               IndexRow index;
+                                                               index.prefix = curPrefix;
  //                                                                            index.prefixstart = prefixStart;
-                                                                       index.numchains = numchains;
-                                                                       indexes.push_back(index);
-                                                                       prefixStart = numProcessedChains;
-                                                                       curPrefix = prefix; 
+                                                               index.numchains = numchains;
+                                                               indexes.push_back(index);
+                                                               prefixStart = numProcessedChains;
+                                                               curPrefix = prefix; 
                                                        }
                                                }
                                                numProcessedChains++;
                                        t2 = clock();
                                        fTime = 1.0f * (t2 - t1) / CLOCKS_PER_SEC;
                                        printf("conversion time: %.2f s\n", fTime);             
-                                       if(nRainbowChainCountRead == nTotalChainCount)
-                                               break;
-                                       if(showDistribution == 1)
-                                       {
-                                               for(int i = 0; i < 64; i++)
-                                               {
+                                       if(showDistribution == 1) {
+                                               for(int i = 0; i < 64; i++)     {
                                                        printf("%u - %u\n", (i+1), distribution[i]);
                                                }
+                                               delete reader;
                                                return;
                                        }
  
  //                                    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);
                                fwrite(&rti_endptlength, 1, 1, pFileIndex);
                                fwrite(&rti_cplength, 1, 1, pFileIndex);
  //                                    fwrite(&m_rti_index_indexlength , 1, 1, pFileIndex);
                                fwrite(&m_rti_index_numchainslength, 1, 1, pFileIndex);
-                               for(UINT4 i = 0; i < rti_cppos.size(); i++)
-                               {
+                               for(UINT4 i = 0; i < rti_cppos.size(); i++)     {
                                        fwrite(&rti_cppos[i], 1, 4, pFileIndex); // The position of the checkpoints
                                }
  //                                    fwrite(&m_rti_index_prefixlength, 1, 1, pFileIndex);
                                int zero = 0;
                                fwrite(&indexes[0].prefix, 1, 8, pFileIndex); // Write the first prefix
                                unsigned int lastPrefix = 0;
-                               for(UINT4 i = 0; i < indexes.size(); i++)
-                               {
-                                       if(i == 0)
+                               for(UINT4 i = 0; i < indexes.size(); i++)       {
+                                       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)
-                                       {
+                                       if(i > 0 && diffSize > 1) {
                                                //indexrow |= indexes[i].prefixstart;
                                                //printf("Diffsize is %u\n", diffSize);
  
                                                // then write the distance amount of 00's
                                                if(diffSize > 1000) {
-                                                       printf("WARNING! The distance to the next prefix is %i. Do you want to continue writing %i bytes of 0x00? Press y to continue", diffSize, diffSize);
+                                                       printf("WARNING! The distance to the next prefix is %i. Do you want to continue writing %i bytes of 0x00? Press y to continue", diffSize, (diffSize*m_indexrowsizebytes));
                                                        #ifdef _WIN32
                                                        if ( _getch() != 'y' ) {
                                                        #else
                                }
                                fclose(pFileIndex);
                        }
-                       else printf("memory allocation fail\n");
-                       
-                                       // Already finished?
-               }
-               fclose(file);
+                       else {
+                               printf("memory allocation fail\n");
+                       }                       
+                       // Already finished?
        }
-       else
+       else {
                printf("can't open file\n");
+       }
+       if(reader != NULL)
+               delete reader;
+       if(fileR != NULL) {
+               fclose(fileR);
+       }
+               
  }
  
  int main(int argc, char* argv[])
        int usecp = 0;// How many bits to use from the index
        int hascp = 0; 
        vector<unsigned int> cppositions;
-       if (argc == 1)
-       {
+       if (argc == 1) {
                Usage();                
                return 0;
        }
-       else if(argc > 2)
-       {
+       else if(argc > 2) {
                for (; argi < argc; argi++)
                {
-                       if (strcmp(argv[argi], "-d") == 0 && (argsUsed & 0x8) == 0)
-                       {
+                       if(strcmp(argv[argi], "-d") == 0 && (argsUsed & 0x8) == 0) {
                                // Enable verbose mode
                                argsUsed |= 0x8;                                
                                showDistribution = 1;
                        }                       
-                       else if (strncmp(argv[argi], "-sptl=", 6) == 0 && (argsUsed & 0x1) == 0)
-                       {
+                       else if (strncmp(argv[argi], "-sptl=", 6) == 0 && (argsUsed & 0x1) == 0) {
                                // Maximum index for starting point
                                argsUsed |= 0x1;
                                sptl = 0;
-                               for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
-                               {
+                               for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++) {
                                        sptl *= 10;
                                        sptl += ((int) argv[argi][i]) - 0x30;
                                }
-                               if (argv[argi][i] != '\0')
-                               {
+                               if (argv[argi][i] != '\0') {
                                        printf("Error: Invalid number.\n\n");
                                        Usage();
                                        return 1;
                                }
-                               if (i > 23) // i - 3 > 20
-                               {
+                               if (i > 23) { // i - 3 > 20                             
                                        printf("Error: Number is too large.\n\n");
                                        Usage();
                                        return 1;
                                }                       
                        }
  
-                       else if (strncmp(argv[argi], "-eptl=", 6) == 0 && (argsUsed & 0x2) == 0)
-                       {
+                       else if (strncmp(argv[argi], "-eptl=", 6) == 0 && (argsUsed & 0x2) == 0) {
                                // Maximum index for ending points
                                argsUsed |= 0x2;
                                eptl = 0;
-                               for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
-                               {
+                               for (i = 6; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++) {
                                        eptl *= 10;
                                        eptl += ((int) argv[argi][i]) - 0x30;
                                }
-                               if (argv[argi][i] != '\0')
-                               {
+                               if (argv[argi][i] != '\0') {
                                        printf("Error: Invalid number.\n\n");
                                        Usage();
                                        return 1;
                                }
-                               if (i > 23) // i - 3 > 20
-                               {
+                               if (i > 23) { // i - 3 > 20                             
                                        printf("Error: Number is too large.\n\n");
                                        Usage();
                                        return 1;
                                }                       
                        }
-                       else if(strncmp(argv[argi], "-usecp=", 7) == 0 && (argsUsed & 0x4) == 0)
-                       {
+                       else if(strncmp(argv[argi], "-usecp=", 7) == 0 && (argsUsed & 0x4) == 0) {
                                argsUsed |= 0x4;
                                hascp = 1;
                                usecp = 0;
                                unsigned int cppos = 0;
-                               for(i = 7; argv[argi][i] != ' ' && argv[argi][i] != '\n' && argv[argi][i] != 0;)
-                               {
+                               for(i = 7; argv[argi][i] != ' ' && argv[argi][i] != '\n' && argv[argi][i] != 0;) {
                                        if(cppositions.size() > 0) i++;
                                        for (; argv[argi][i] >= '0' && argv[argi][i] <= '9'; i++)
                                        {
                                                cppos = 0;
                                        //}
                                }
-                               if (argv[argi][i] != '\0')
-                               {
+                               if (argv[argi][i] != '\0') {
                                        printf("Error: Invalid number.\n\n");
                                        Usage();
                                        return 1;
                                }
-                               if (usecp > 16) // i - 3 > 20
-                               {
+                               if (usecp > 16) { // i - 3 > 20
                                        printf("Error: Number is too large.\n\n");
                                        Usage();
                                        return 1;
                                }                               
-                               else printf("Using %i bits of the checkpoints\n", usecp);
+                               else {
+                                       printf("Using %i bits of the checkpoints\n", usecp);
+                               }
                        }
  
                }               
  #else
        GetTableList(argc, argv, vPathName);
  #endif
-       if (vPathName.size() == 0)
-       {
+       if (vPathName.size() == 0) {
                printf("no rainbow table found\n");
                return 0;
        }
-       for (UINT4 i = 0; i < vPathName.size(); i++)
-       {
+       for (UINT4 i = 0; i < vPathName.size(); i++) {
                string sResultFile;
                int n = vPathName[i].find_last_of('\\');
-               if (n != -1)
-                       sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "i2";
-               else 
-                       sResultFile = vPathName[i] + "i2"; // Resulting file is .rt, not .rti
-               printf("Using %i of 64 bits. sptl: %i, eptl: %i, cp: %i. Chains will be %i bytes in size\n", (sptl + eptl + usecp), sptl, eptl, usecp, ((sptl + eptl + usecp) / 8));
-               if(sptl + eptl + usecp > 64)
-               {
+               if (n != -1) {
+                       if(vPathName[i].substr(vPathName[i].length() - 3, vPathName[i].length()) == "rti")      {
+                               sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "2";                            
+                       }
+                       else {
+                               sResultFile = vPathName[i].substr(n+1, vPathName[i].length()) + "i2";
+                       }
+               }
+               else {
+                       if(vPathName[i].substr(vPathName[i].length() - 3, vPathName[i].length()) == "rti")      {
+                               sResultFile = vPathName[i] + "2";                               
+                       } else {
+                               sResultFile = vPathName[i] + "i2"; // Resulting file is .rt, not .rti
+                       }
+               }
+               if(usecp == 0 && showDistribution == 0) {
+                       printf("Using %i of 64 bits. sptl: %i, eptl: %i, cp: %i. Chains will be %i bytes in size\n", (sptl + eptl + usecp), sptl, eptl, usecp, ((sptl + eptl + usecp) / 8));
+               }
+               if(sptl + eptl + usecp > 64) {
                        exit(1);
                }
                ConvertRainbowTable(vPathName[i], sResultFile, sptl, eptl, showDistribution, hascp, usecp, cppositions);
                printf("\n");
        }
        return 0;
 -}
 +}
index d24f654f1b2fc9a7db14eb69e0ba308469741148,969775df93c826044223479c653332e27dce4f7c..8a63fa9b5159a55fccea14cc1d43d090451ee27d
mode 100644,100644..100755
Binary files differ
index 17a93ac51de7171aeaba31e9fd593125d0eebd33,0000000000000000000000000000000000000000..a662ff459fc1104c8f86874692e25144077ffc3d
mode 100644,000000..100644
--- /dev/null
@@@ -1,45 -1,0 +1,46 @@@
-       virtual int ReadChains(unsigned int &numChains, RainbowChainO *pData) = 0;
-       virtual unsigned int GetChainsLeft() = 0;
 +/*
 + * 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 84db65f028d00d4292c1cb276be83def82a0ef7a,cab23a12dad70ba13c0c8b2d779e0615364d2c82..b80b4ab60a3e0eacac6ecb431e0e37f5af93c2a2
- /*\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)\r
- #endif\r
\r
- #include "ChainWalkSet.h"\r
\r
- CChainWalkSet::CChainWalkSet()\r
- {\r
-       m_sHashRoutineName   = "";\r
-       m_sPlainCharsetName  = "";\r
-       m_nPlainLenMin       = 0;\r
-       m_nPlainLenMax       = 0;\r
-       m_nRainbowTableIndex = 0;\r
-       m_nRainbowChainLen   = 0;\r
-       debug = false;\r
-       sPrecalcPathName     = "";\r
-       preCalcPart          = 0;\r
- }\r
\r
- CChainWalkSet::~CChainWalkSet()\r
- {\r
-       DiscardAll();\r
- }\r
\r
- void CChainWalkSet::DiscardAll()\r
- {\r
-       //printf("debug: discarding all walk...\n");\r
\r
-       list<ChainWalk>::iterator it;\r
-       for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)\r
-               delete [] it->pIndexE;\r
-       m_lChainWalk.clear();\r
- }\r
\r
- string CChainWalkSet::CheckOrRotatePreCalcFile()\r
- {\r
-       char sPreCalcFileName[255];\r
\r
-       // 255 files limit to be sure\r
-       for (; preCalcPart < 255; preCalcPart++)\r
-       {\r
-               sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), preCalcPart);\r
-               string sReturnPreCalcPath(sPreCalcFileName);\r
\r
-               unsigned int fileLen = 0;\r
\r
-               FILE* file = fopen(sReturnPreCalcPath.c_str(), "ab");\r
-               if(file!=NULL)\r
-               {\r
-                       fileLen = GetFileLen(file);\r
-                       long unsigned int nextFileLen = fileLen + (sizeof(uint64) * (m_nRainbowChainLen-1));\r
-                       // Rotate to next file if we are going to pass 2GB filesize\r
-                       if (nextFileLen < ((unsigned)2 * 1024 * 1024 * 1024))\r
-                       {\r
-                               // We might want to vPrecalcFiles.push_back(sReturnPreCalcPath) if we just created this file\r
-                               // We don't as only newly generated chainwalksets will be stored to this new file, so we don't have to look there\r
-                               if (debug) printf("Debug: Using for precalc: %s\n", sReturnPreCalcPath.c_str());\r
-                               fclose(file);\r
-                               return sReturnPreCalcPath;\r
-                       }\r
-                       fclose(file);\r
-               }\r
-       }\r
\r
-       return string("");\r
- }\r
\r
- void CChainWalkSet::updateUsedPrecalcFiles()\r
- {\r
-       // we might also use this function to search a wildcard path of precalc files\r
-       vPrecalcFiles.clear();\r
-       char sPreCalcFileName[255];\r
\r
-       int i;\r
-       // 255 files max\r
-       for (i = 0; i < 255; i++)\r
-       {\r
-               sprintf(sPreCalcFileName, "%s.%d", sPrecalcPathName.c_str(), i);\r
-               string sTryPreCalcPath(sPreCalcFileName);\r
-               FILE* file = fopen(sTryPreCalcPath.c_str(), "rb");\r
-               if(file!=NULL) {\r
-                       vPrecalcFiles.push_back(sTryPreCalcPath);\r
-                       fclose(file);\r
-               }\r
-               else {\r
-                       break;\r
-               }\r
-       }\r
- }\r
\r
- void CChainWalkSet::removePrecalcFiles()\r
- {\r
-       if (debug) printf("Debug: Removing precalc files.\n");\r
-       updateUsedPrecalcFiles();\r
-       string sCurrentPrecalcPathName = "";\r
-       string sCurrentPrecalcIndexPathName = "";\r
-       \r
-       int i;\r
-       for (i = 0; i < (int)vPrecalcFiles.size(); i++)\r
-       {\r
-               sCurrentPrecalcPathName = vPrecalcFiles[i];\r
-               sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";\r
\r
-               if (debug) printf("Debug: Removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());\r
\r
-               if (remove(sCurrentPrecalcPathName.c_str()) != 0)\r
-                       if (debug) printf("Debug: Failed removing precalc file: %s\n", sCurrentPrecalcPathName.c_str());\r
\r
-               if (debug) printf("Debug: Removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());\r
\r
-               if (remove(sCurrentPrecalcIndexPathName.c_str()) != 0)\r
-                       if (debug) printf("Debug: Failed removing precalc index file: %s\n", sCurrentPrecalcIndexPathName.c_str());\r
\r
-       }\r
- }\r
\r
- bool CChainWalkSet::FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)\r
- {\r
-       int gotPrecalcOnLine = -1;\r
-       char precalculationLine[255];\r
-       sprintf(precalculationLine, "%s_%s#%d-%d_%d_%d:%s\n", m_sHashRoutineName.c_str(), m_sPlainCharsetName.c_str(), m_nPlainLenMin, m_nPlainLenMax, m_nRainbowTableIndex, m_nRainbowChainLen, HexToStr(pHash, nHashLen).c_str() );\r
-       string precalcString(precalculationLine);\r
\r
-       string sCurrentPrecalcPathName = "";\r
-       string sCurrentPrecalcIndexPathName = "";\r
-       long unsigned int offset;\r
\r
-       int i;\r
-       for (i = 0; i < (int)vPrecalcFiles.size() && gotPrecalcOnLine == -1; i++)\r
-       {\r
-               sCurrentPrecalcPathName = vPrecalcFiles[i];\r
-               sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";\r
\r
-               offset = 0;\r
\r
-               vector<string> precalcLines;\r
-               if (ReadLinesFromFile(sCurrentPrecalcIndexPathName.c_str(), precalcLines))\r
-               {\r
-                       int j;\r
-                       for (j = 0; j < (int)precalcLines.size(); j++)\r
-                       {\r
-                               if (precalcString.compare(0, precalcString.size()-1, precalcLines[j]) == 0)\r
-                               {\r
-                                       gotPrecalcOnLine = j;\r
-                                       break;\r
-                               }\r
\r
-                               // Parse\r
-                               vector<string> vPart;\r
-                               if (SeperateString(precalcLines[j], "___:", vPart))\r
-                               {\r
-                                       // add to offset\r
-                                       offset += ((atoi(vPart[3].c_str())-1) * sizeof(uint64));\r
-                               }\r
-                               else {\r
-                                       // corrupt file\r
-                                       printf("Corrupted precalculation file!\n");\r
-                                       gotPrecalcOnLine = -1;\r
-                                       break;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
\r
-       if (gotPrecalcOnLine > -1)\r
-       {\r
-               if (debug) printf("Debug: Reading pre calculations from file, line %d offset %lu\n", gotPrecalcOnLine, offset);\r
-               \r
-               FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "rb");\r
\r
-               if (fp!=NULL) {\r
-                       fseek(fp, offset, SEEK_SET);\r
\r
-                       // We should do some verification here, for example by recalculating the middle chain, to catch corrupted files\r
-                       if(fread(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1)\r
-                               printf("File read error.");\r
-                       fclose(fp);\r
-               }\r
-               else\r
-                       printf("Cannot open precalculation file %s.\n", sCurrentPrecalcPathName.c_str());\r
\r
-               //printf("\npIndexE[0]: %s\n", uint64tostr(pIndexE[0]).c_str());\r
-               //printf("\npIndexE[nRainbowChainLen-2]: %s\n", uint64tostr(pIndexE[m_nRainbowChainLen-2]).c_str());\r
\r
-               return true;\r
-       }\r
\r
-       return false;\r
- }\r
\r
- void CChainWalkSet::StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen)\r
- {\r
-       if (debug) printf("\nDebug: Storing precalc\n");\r
-       \r
-       string sCurrentPrecalcPathName = CheckOrRotatePreCalcFile();\r
-       string sCurrentPrecalcIndexPathName = sCurrentPrecalcPathName + ".index";\r
\r
-       FILE* fp = fopen(sCurrentPrecalcPathName.c_str(), "ab");\r
-       if(fp!=NULL)\r
-       {\r
-               if(fwrite(pIndexE, sizeof(uint64), (unsigned long)m_nRainbowChainLen-1, fp) != (unsigned long)m_nRainbowChainLen-1)\r
-                       printf("File write error.");\r
-               else\r
-               {\r
-                       FILE* file = fopen(sCurrentPrecalcIndexPathName.c_str(), "a");\r
-                       if (file!=NULL)\r
-                       {\r
-                               char precalculationLine[255];\r
-                               sprintf(precalculationLine, "%s_%s#%d-%d_%d_%d:%s\n", m_sHashRoutineName.c_str(), m_sPlainCharsetName.c_str(), m_nPlainLenMin, m_nPlainLenMax, m_nRainbowTableIndex, m_nRainbowChainLen, HexToStr(pHash, nHashLen).c_str() );\r
-                               fputs (precalculationLine, file);\r
-                               fclose (file);\r
-                       }\r
-               }\r
-               fclose(fp);\r
-               }\r
-       else\r
-               printf("Cannot open precalculation file %s\n", sCurrentPrecalcPathName.c_str());\r
- }\r
\r
- uint64* CChainWalkSet::RequestWalk(unsigned char* pHash, int nHashLen,\r
-                                                                  string sHashRoutineName,\r
-                                                                  string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax, \r
-                                                                  int nRainbowTableIndex, \r
-                                                                  int nRainbowChainLen,\r
-                                                                  bool& fNewlyGenerated,\r
-                                                                  bool setDebug,\r
-                                                                  string sPrecalc)\r
- {\r
-       debug = setDebug;\r
-       sPrecalcPathName = sPrecalc;\r
\r
-       if (   m_sHashRoutineName   != sHashRoutineName\r
-               || m_sPlainCharsetName  != sPlainCharsetName\r
-               || m_nPlainLenMin       != nPlainLenMin\r
-               || m_nPlainLenMax       != nPlainLenMax\r
-               || m_nRainbowTableIndex != nRainbowTableIndex\r
-               || m_nRainbowChainLen   != nRainbowChainLen)\r
-       {\r
-               DiscardAll();\r
\r
-               m_sHashRoutineName   = sHashRoutineName;\r
-               m_sPlainCharsetName  = sPlainCharsetName;\r
-               m_nPlainLenMin       = nPlainLenMin;\r
-               m_nPlainLenMax       = nPlainLenMax;\r
-               m_nRainbowTableIndex = nRainbowTableIndex;\r
-               m_nRainbowChainLen   = nRainbowChainLen;\r
\r
-               ChainWalk cw;\r
-               memcpy(cw.Hash, pHash, nHashLen);\r
-               cw.pIndexE = new uint64[nRainbowChainLen - 1];\r
-               m_lChainWalk.push_back(cw);\r
\r
-               // Only update this list when we search through another rainbow table\r
-               updateUsedPrecalcFiles();\r
\r
-               if (!FindInFile(cw.pIndexE, pHash, nHashLen))\r
-                       fNewlyGenerated = true;\r
-               else\r
-                       fNewlyGenerated = false;\r
-               return cw.pIndexE;\r
-       }\r
\r
-       list<ChainWalk>::iterator it;\r
-       for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)\r
-       {\r
-               if (memcmp(it->Hash, pHash, nHashLen) == 0)\r
-               {\r
-                       fNewlyGenerated = false;\r
-                       return it->pIndexE;\r
-               }\r
-       }\r
\r
-       ChainWalk cw;\r
-       memcpy(cw.Hash, pHash, nHashLen);\r
-       cw.pIndexE = new uint64[nRainbowChainLen - 1];\r
-       m_lChainWalk.push_back(cw);\r
\r
-       if (!FindInFile(cw.pIndexE, pHash, nHashLen))\r
-                       fNewlyGenerated = true;\r
-               else\r
-                       fNewlyGenerated = false;\r
-       return cw.pIndexE;\r
- }\r
\r
- void CChainWalkSet::DiscardWalk(uint64* pIndexE)\r
- {\r
-       list<ChainWalk>::iterator it;\r
-       for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)\r
-       {\r
-               if (it->pIndexE == pIndexE)\r
-               {\r
-                       delete it->pIndexE;\r
-                       m_lChainWalk.erase(it);\r
-                       return;\r
-               }\r
-       }\r
\r
-       printf("debug: pIndexE not found\n");\r
- }\r
+ /*
+  * 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)
+ #endif
+ #include "ChainWalkSet.h"
+ CChainWalkSet::CChainWalkSet()
+ {
+       m_sHashRoutineName   = "";
+       m_sPlainCharsetName  = "";
+       m_nPlainLenMin       = 0;
+       m_nPlainLenMax       = 0;
+       m_nRainbowTableIndex = 0;
+       m_nRainbowChainLen   = 0;
+       debug = false;
+       sPrecalcPathName     = "";
+       preCalcPart          = 0;
+ }
+ CChainWalkSet::~CChainWalkSet()
+ {
+       DiscardAll();
+ }
+ void CChainWalkSet::DiscardAll()
+ {
+       //printf("debug: discarding all walk...\n");
+       list<ChainWalk>::iterator it;
+       for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
+               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;
++              long 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 setDebug,
+                                                                  string sPrecalc)
+ {
+       debug = setDebug;
+       sPrecalcPathName = sPrecalc;
+       if (   m_sHashRoutineName   != sHashRoutineName
+               || m_sPlainCharsetName  != sPlainCharsetName
+               || m_nPlainLenMin       != nPlainLenMin
+               || m_nPlainLenMax       != nPlainLenMax
+               || m_nRainbowTableIndex != nRainbowTableIndex
+               || m_nRainbowChainLen   != nRainbowChainLen)
+       {
+               DiscardAll();
+               m_sHashRoutineName   = sHashRoutineName;
+               m_sPlainCharsetName  = sPlainCharsetName;
+               m_nPlainLenMin       = nPlainLenMin;
+               m_nPlainLenMax       = nPlainLenMax;
+               m_nRainbowTableIndex = nRainbowTableIndex;
+               m_nRainbowChainLen   = nRainbowChainLen;
+               ChainWalk cw;
+               memcpy(cw.Hash, pHash, nHashLen);
+               cw.pIndexE = new uint64[nRainbowChainLen - 1];
+               m_lChainWalk.push_back(cw);
+               // 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;
+       }
+       list<ChainWalk>::iterator it;
+       for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
+       {
+               if (memcmp(it->Hash, pHash, nHashLen) == 0)
+               {
+                       fNewlyGenerated = false;
+                       return it->pIndexE;
+               }
+       }
+       ChainWalk cw;
+       memcpy(cw.Hash, pHash, nHashLen);
+       cw.pIndexE = new uint64[nRainbowChainLen - 1];
+       m_lChainWalk.push_back(cw);
+       if (!FindInFile(cw.pIndexE, pHash, nHashLen))
+                       fNewlyGenerated = true;
+               else
+                       fNewlyGenerated = false;
+       return cw.pIndexE;
+ }
+ void CChainWalkSet::DiscardWalk(uint64* pIndexE)
+ {
+       list<ChainWalk>::iterator it;
+       for (it = m_lChainWalk.begin(); it != m_lChainWalk.end(); it++)
+       {
+               if (it->pIndexE == pIndexE)
+               {
+                       delete it->pIndexE;
+                       m_lChainWalk.erase(it);
+                       return;
+               }
+       }
+       printf("debug: pIndexE not found\n");
+ }
index d36ebbc74556e4717eb8ca53cf73992d4e22ccd0,0a4b1818bb9eb889771e94017cc28fb0ee9302c2..0343588f38015dcead7af0a10818659b97a01cc4
 -/*
 - * 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 Martin Westergaard Jørgensen <martinwj2005@gmail.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 = (RainbowChainO*)mp.Allocate(nFileLen, nAllocatedSize);\r
-                               #ifdef _WIN32\r
-                                       if (debug) printf("Allocated %I64u bytes, filelen %lu\n", nAllocatedSize, (unsigned long)nFileLen);\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 %lu\n", nAllocatedSize, (unsigned long)nFileLen);\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, nDataToRead = 0;\r
++                                              unsigned int nDataRead = 0;\r
 +                                              gettimeofday( &tv, NULL );\r
 +                                              if ( doRti2Format )\r
 +                                              {\r
-                                                       nDataToRead = nAllocatedSize / 16;\r
-                                                       nDataRead = nDataToRead;\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
-                                       unsigned int nFileLenIndex = GetFileLen(fIndex);\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 (%u bytes)\n", nFileLenIndex);\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 %u\n", nAllocatedSizeIndex, nFileLenIndex);\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 %u\n", nAllocatedSizeIndex, nFileLenIndex);\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 ( (unsigned long)ftell(fIndex) != nFileLenIndex ) // Index chunk read loop\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
++                                                                      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 4206340e73b8c3f74168640441d984af6fec58a4,db22aeba8386fbcc48af69287ebb31bf441ec25e..4a4cbbb674856b0fd8bc5978984e6726d1f6e482
 -/*
 - * 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 Martin Westergaard Jørgensen <martinwj2005@gmail.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 5c634c02df4c8cfa5515706731f76422b9c29805,10e235c4b8485e4b4883d3571fd13c9c0358c4ad..77a4eabbd5aacca9bdd22776718c896ad7952084
 -/*
 - * 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
-       uint64 nAvailPhys = GetAvailPhysMemorySize();\r
++      unsigned long nAvailPhys = GetAvailPhysMemorySize();\r
 +\r
 +      if ( debug )\r
 +      {\r
-               #ifdef _WIN32\r
++              #if defined(_WIN32) && !defined(__GNUC__)\r
 +                      printf( "Debug: nAvailPhys: %I64u\n", nAvailPhys );\r
 +              #else\r
-                       printf( "Debug: nAvailPhys: %llu\n", nAvailPhys );\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 946c79d8931c7b5681735991533a73e194e45136,53249245de7f4741516205d19682507a7069f1bc..941331ba7443b0393e3c87d24e0ffdd5e60a5b49
 -/*
 - * 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
-               unsigned int len = GetFileLen(file);\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
-               unsigned int len = GetFileLen(file);\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
- #if defined(_WIN32)\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 abd855076517797a322f22c81be219e749963112,0000000000000000000000000000000000000000..b1d5f968a4c0f27c227620cf5befe606fdafd984
mode 100644,000000..100644
--- /dev/null
@@@ -1,159 -1,0 +1,163 @@@
-       m_pIndex = new unsigned char[len];
 +/*
 + * 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;
 +}
index 35450359f5f4bf1ae197de6e4d0b53df7a330974,0000000000000000000000000000000000000000..e0f5ed4854465c473838525aeb1d4ab54edecfe2
mode 100644,000000..100644
--- /dev/null
@@@ -1,68 -1,0 +1,68 @@@
-       int ReadChains(unsigned int &numChains, RainbowChainO *pData);
 +/*
 + * 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 f9ca133d81ec0e365c42a7c0d17d440f5b4ece12,3eadfbf8275cbb4e87bad9bfa29f12f2913242e6..2494a8447b778ad791ba8174a3f14eccbfd150eb
@@@ -1,7 -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,9 -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 e69ed184cfdc3d4c4b775969ae538dcb55531a91,086c333f27172373569429ad44868798b3b02b58..ba7f16315e6f4f7531b33082087db2e14b27db0e
@@@ -87,6 -87,7 +87,7 @@@ void ConvertRainbowTable(string sPathNa
                sFileName = sPathName.substr(nIndex + 1);
        else
                sFileName = sPathName;
        // Info
        printf("%s:\n", sFileName.c_str());
        FILE *fResult = fopen(sResultFileName.c_str(), "wb");
@@@ -98,7 -99,6 +99,6 @@@
        static CMemoryPool mp;
        unsigned int nAllocatedSize;
        BaseRTReader *reader = NULL;
        if(sType == "RTI2")
                reader = (BaseRTReader*)new RTI2Reader(sFileName);
        else if(sType == "RTI")
                printf("Invalid table type '%s'", sType.c_str());
                return ;
        }
-       RainbowChainCP* pChain = (RainbowChainCP*)mp.Allocate(reader->GetChainsLeft() * sizeof(RainbowChainCP), nAllocatedSize);
+       int size = reader->GetChainsLeft() * sizeof(RainbowChain);
+ #ifdef _MEMORYDEBUG
+       printf("Starting allocation of %i bytes\n", size);
+ #endif
+       RainbowChain* pChain = (RainbowChain*)mp.Allocate(size, nAllocatedSize);
+ #ifdef _MEMORYDEBUG
+       printf("Finished. Got %i bytes\n", nAllocatedSize);
+ #endif
        if (pChain != NULL)
        {
-               nAllocatedSize = nAllocatedSize / sizeof(RainbowChainCP) * sizeof(RainbowChainCP);              // Round to boundary
-               unsigned int nChains = nAllocatedSize / sizeof(RainbowChainCP);
+               nAllocatedSize = nAllocatedSize / sizeof(RainbowChain) * sizeof(RainbowChain);          // Round to boundary
+               unsigned int nChains = nAllocatedSize / sizeof(RainbowChain);
                while(reader->GetChainsLeft() > 0)
                {
+ #ifdef _MEMORYDEBUG
+                       printf("Grabbing %i chains from file\n", nChains);
+ #endif
                        reader->ReadChains(nChains, pChain);
 -                      for(UINT4 i = 0; i < nChains; i++)
+ #ifdef _MEMORYDEBUG
+                       printf("Recieved %i chains from file\n", nChains);
+ #endif
 +                      for(uint32 i = 0; i < nChains; i++)
                        {
                                fwrite(&pChain[i], 1, 16, fResult);
                        }
@@@ -158,7 -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;
                        
                printf("\n");
        }
        return 0;
 -}
 +}
index 66f2f10f7fe593431ba51c782aa0486e3e272cca,5054d8fb2088d19957fbf17c2d9ac1232eb98ef0..a9923cf325683b768da4bf056a3e8f63fbce57aa
@@@ -1,45 -1,20 +1,46 @@@
 +/*
 + * 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
  {
  public:
-       virtual int ReadChains(unsigned int &numChains, RainbowChainCP *pData) = 0;
-       virtual unsigned int GetChainsLeft() = 0;
+       virtual int ReadChains(UINT4 &numChains, RainbowChain *pData) = 0;
+       virtual UINT4 GetChainsLeft() = 0;
        
+       virtual ~BaseRTReader()  { };
  };
  
  #endif
index 053db7a04b5fff229fe08a321768693291e7f9b9,4c8d5c98eeb810e7d06ac81ad017bf8ef12d5e61..a6745073f0e97e9953c510280ac32b405106de2f
@@@ -1,28 -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"
@@@ -45,9 -25,11 +45,11 @@@ CMemoryPool::CMemoryPool(
  
  CMemoryPool::~CMemoryPool()
  {
-       if (m_pMem != NULL)
-       {
+       if (m_pMem != NULL)     {
+ #ifdef _MEMORYDEBUG
+               printf("Freeing %i bytes of memory\n", m_nMemSize);
+ #endif 
 -              delete m_pMem;
 +              delete [] m_pMem;
                m_pMem = NULL;
                m_nMemSize = 0;
        }
  
  unsigned char* CMemoryPool::Allocate(unsigned int nFileLen, unsigned int& nAllocatedSize)
  {
-       if (nFileLen <= m_nMemSize)
-       {
+       if (nFileLen <= m_nMemSize)     {
                nAllocatedSize = nFileLen;
                return m_pMem;
        }
  
        unsigned int nTargetSize;
-       if (nFileLen < m_nMemMax)
+       if (nFileLen < m_nMemMax) {
                nTargetSize = nFileLen;
-       else
+       }
+       else {
                nTargetSize = m_nMemMax;
+       }
        // Free existing memory
-       if (m_pMem != NULL)
-       {
+       if (m_pMem != NULL)     {
+ #ifdef _MEMORYDEBUG
+               printf("Freeing %i bytes of memory\n", m_nMemSize);
+ #endif 
 -              delete m_pMem;
 +              delete [] m_pMem;
                m_pMem = NULL;
                m_nMemSize = 0;
        }
  
        // Allocate new memory
        //printf("allocating %u bytes memory\n", nTargetSize);
+       //      m_pMem = new unsigned char[nTargetSize];
+ #ifdef _MEMORYDEBUG
+               printf("Allocating %i bytes of memory - ", nTargetSize);
+ #endif 
        m_pMem = new (nothrow) unsigned char[nTargetSize];
-       while (m_pMem == NULL && nTargetSize >= 512 * 1024 * 1024 )
-       {
-               nTargetSize -= 16 * 1024 * 1024;
-               m_pMem = new (nothrow) unsigned char[nTargetSize];
+       while (m_pMem == NULL && nTargetSize >= 512 * 1024 * 1024 )     {
+ #ifdef _MEMORYDEBUG
+               printf("failed!\n");
+               printf("Allocating %i bytes of memory (backup) - ", nTargetSize);
+ #endif 
+          nTargetSize -= 16 * 1024 * 1024;
+          m_pMem = new (nothrow) unsigned char[nTargetSize];
        }
-       if (m_pMem != NULL)
-       {
+       if (m_pMem != NULL)     {
+ #ifdef _MEMORYDEBUG
+               printf("success!\n");
+ #endif
                m_nMemSize = nTargetSize;
                nAllocatedSize = nTargetSize;
                return m_pMem;
        }
-       else
-       {
-               m_nMemSize = 0;
+       else {
                nAllocatedSize = 0;
                return NULL;
        }
diff --combined Common/rt api/Public.cpp
index 6cd04822eff639376ddd191ad9b6fba60cac3428,834dea77019e5d7aa822df66ed2b02f2909962d5..b42c954918123518222083caa999476cf45c2118
@@@ -11,7 -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
@@@ -22,7 -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
  
@@@ -31,7 -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;
@@@ -186,12 -102,12 +186,12 @@@ bool GetHybridCharsets(string sCharset
        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;
  bool boinc_ReadLinesFromFile(string sPathName, vector<string>& vLine)
  {
        vLine.clear();
 -/*    char input_path[512];
++#ifdef 0
+       vLine.push_back("byte                        = []");
+       vLine.push_back("alpha                       = [ABCDEFGHIJKLMNOPQRSTUVWXYZ]");
+       vLine.push_back("alpha-space                 = [ABCDEFGHIJKLMNOPQRSTUVWXYZ ]");
+       vLine.push_back("alpha-numeric               = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]");
+       vLine.push_back("alpha-numeric-space         = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ]");
+       vLine.push_back("alpha-numeric-symbol14      = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x2D\x5F\x2B\x3D]");
+       vLine.push_back("alpha-numeric-symbol14-space= [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x2D\x5F\x2B\x3D\x20]");
+       vLine.push_back("all                         = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\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("all-space                   = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\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("alpha-numeric-symbol32-space = [ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\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("lm-frt-cp437                = [\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x7B\x7C\x7D\x7E\x80\x8E\x8F\x90\x92\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA5\xE0\xE1\xE2\xE3\xE4\xE6\xE7\xE8\xE9\xEA\xEB\xEE]");
+       vLine.push_back("lm-frt-cp850                = [\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x7B\x7C\x7D\x7E\x80\x8E\x8F\x90\x92\x99\x9A\x9C\x9D\x9F\xA5\xB5\xB6\xB7\xBD\xBE\xC7\xCF\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xDE\xE0\xE1\xE2\xE3\xE5\xE6\xE8\xE9\xEA\xEB\xED\xEF]");
+       vLine.push_back("lm-frt-cp437-850            = [\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F\x60\x7B\x7C\x7D\x7E\x80\x8E\x8F\x90\x92\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA5\xB5\xB6\xB7\xBD\xBE\xC7\xCF\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xDE\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xED\xEE\xEF]");
+       vLine.push_back("numeric                     = [0123456789]");
+       vLine.push_back("numeric-space               = [0123456789 ]");
+       vLine.push_back("loweralpha                  = [abcdefghijklmnopqrstuvwxyz]");
+       vLine.push_back("loweralpha-space            = [abcdefghijklmnopqrstuvwxyz ]");
+       vLine.push_back("loweralpha-numeric          = [abcdefghijklmnopqrstuvwxyz0123456789]");
+       vLine.push_back("loweralpha-numeric-space    = [abcdefghijklmnopqrstuvwxyz0123456789 ]");
+       vLine.push_back("loweralpha-numeric-symbol14 = [abcdefghijklmnopqrstuvwxyz0123456789\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x2D\x5F\x2B\x3D]");
+       vLine.push_back("loweralpha-numeric-all      = [abcdefghijklmnopqrstuvwxyz0123456789\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("loweralpha-numeric-symbol32-space= [abcdefghijklmnopqrstuvwxyz0123456789\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                    = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]");
+       vLine.push_back("mixalpha-space              = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ ]");
+       vLine.push_back("mixalpha-numeric            = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]");
+       vLine.push_back("mixalpha-numeric-space      = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ]");
+       vLine.push_back("mixalpha-numeric-symbol14   = [abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\x21\x40\x23\x24\x25\x5E\x26\x2A\x28\x29\x2D\x5F\x2B\x3D]");
+       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];
        boinc_resolve_filename(sPathName.c_str(), input_path, sizeof(input_path));
        FILE *file = boinc_fopen(input_path, "rb");
        if (!file) {
                                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);
        }
        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);
                data[len] = '\0';
                string content = data;
                content += "\n";
 -              delete data;
 +              delete [] data;
  
                unsigned int i;
                for (i = 0; i < content.size(); i++)
                                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);
        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)
  {
        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);
  
@@@ -373,27 -302,16 +406,27 @@@ string HexToStr(const unsigned char* pD
        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
  }
  
@@@ -415,12 -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;
@@@ -437,7 -355,7 +470,7 @@@ void ParseHash(string sHash, unsigned c
                pHash[i] = (unsigned char)nValue;
        }
  
 -      nHashLen = sHash.size() / 2;
 +      nHashLen = (int) sHash.size() / 2;
  }
  
  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 6fb0cb914507ef011bd4a07cb0c58d0e9aa3df1b,004159ceba7b65506461157d43844233f13cc008..ad7db3dd12e31621d0abea5faa4dda2227efa90e
@@@ -1,30 -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)
  {
        }
        m_chainPosition = 0;
  
 -      unsigned int len = GetFileLen(pFileIndex);
 +      long len = GetFileLen(pFileIndex);
        fseek(pFileIndex, 0, SEEK_SET);
  
-       m_pIndex = new unsigned char[len];
+       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);
        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 %ld\n", len);
 -              printf("Invalid filesize %u\n", len);
++              printf("Invalid filesize %lu\n", len);
                return;
        }
        
@@@ -82,11 -62,11 +86,11 @@@ RTI2Reader::~RTI2Reader(void
  
  unsigned int RTI2Reader::GetChainsLeft()
  {
 -      int len = GetFileLen(m_pFile);
 +      long len = GetFileLen(m_pFile);
        return len / m_chainsizebytes - m_chainPosition;
  }
  
- int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChainCP *pData)
+ int RTI2Reader::ReadChains(unsigned int &numChains, RainbowChain *pData)
  {
        if(strncmp(m_pHeader->header, "RTI2", 4) != 0)
        {
        {
                // 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;
        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)
        {
                        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 902344aae3dfea17cd3af83653d0473c7b98b8dd,0b1f127471e2c7886f6c5742f1bc6844da1a12ea..db3d446a126ad8fd7ed222ed5e91ae781eadccbd
@@@ -1,39 -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 
@@@ -48,18 -22,18 +48,18 @@@ class RTI2Reader : BaseRTReade
  {
  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(unsigned int &numChains, RainbowChainCP *pData);
 -      int ReadChains(UINT4 &numChains, RainbowChain *pData);
++      int ReadChains(uint32 &numChains, RainbowChain *pData);
        unsigned int GetChainsLeft();
        static RTI2Header *GetHeader() { return m_pHeader; }
  };
index 1a977861d80bc43b7a585c9f88f9c9e744758339,3134e918cde56d464746f00a9315ff5443ecb6c7..374b062b5696ea6fa54144fff99cfd8eb7b87838
@@@ -17,23 -17,38 +17,38 @@@ 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 (%ld bytes)\n", nFileLen);
 -              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 (%ld bytes)\n", nIndexFileLen);
 -                      printf("index file length mismatch (%u bytes)\n", nIndexFileLen);
++                      printf("index file length mismatch (%lu bytes)\n", nIndexFileLen);
                else
                {
-                       m_pIndex = new IndexChain[nIndexFileLen / 11];
+                       if(m_pIndex != NULL) {
+                               delete m_pIndex;
+                               m_pIndex = NULL;
+                       }
+ #ifdef _MEMORYDEBUG
+                       printf("Allocating %u MB memory for RTIReader::m_pIndex", nIndexFileLen / 11 / (1024 * 1024));
+ #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
+                       printf(" - success!\n");
+ #endif                        
                        memset(m_pIndex, 0x00, sizeof(IndexChain) * (nIndexFileLen / 11));
                        fseek(pFileIndex, 0, SEEK_SET);
-                       int nRows;
 -                      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;                                                   
@@@ -59,7 -74,7 +74,7 @@@
                        }
                        if(m_pIndex[m_nIndexSize - 1].nFirstChain + m_pIndex[m_nIndexSize - 1].nChainCount > nTotalChainCount) // +1 is not needed here
                        {
-                               printf("Corrupted index detected: The index is covering more than the file\n");
+                               printf("Corrupted index detected: The index is covering more than the file (%i chains of %i chains)\n", m_pIndex[m_nIndexSize - 1].nFirstChain + m_pIndex[m_nIndexSize - 1].nChainCount, nTotalChainCount);
                                exit(-1);
                        }
  
  
  }
  
- int RTIReader::ReadChains(unsigned int &numChains, RainbowChainCP *pData)
+ int RTIReader::ReadChains(unsigned int &numChains, RainbowChain *pData)
  {     
        // We HAVE to reset the data to 0x00's or we will get in trouble
-       memset(pData, 0x00, sizeof(RainbowChainCP) * numChains);
+       memset(pData, 0x00, sizeof(RainbowChain) * numChains);
        unsigned int readChains = 0;
        unsigned int chainsleft = GetChainsLeft();
-       for(unsigned int i = 0; i < m_nIndexSize; i++)
+       for(UINT4 i = 0; i < m_nIndexSize; i++)
        {
                if(m_chainPosition + readChains > m_pIndex[i].nFirstChain + m_pIndex[i].nChainCount) // We found the matching index
                        continue;
                }
                if(readChains == numChains) break;              
        }
-       if(readChains != numChains) numChains = readChains; // Update how many chains we read
+       if(readChains != numChains) { 
+               numChains = readChains; // Update how many chains we read
+       }
        m_chainPosition += readChains;
+       printf("Chain position is now %u\n", m_chainPosition);
        return 0;
  }
  
- unsigned int RTIReader::GetChainsLeft()
- {
-       int len = GetFileLen(m_pFile) / 8 - m_chainPosition;
-       return len;
+ UINT4 RTIReader::GetChainsLeft()
+ {     
+       return (GetFileLen(m_pFile) / 8) - m_chainPosition;
  }
  
  RTIReader::~RTIReader(void)