From 57b0f6696d60ccfbc6e2da76c3fa71e6d1da9db5 Mon Sep 17 00:00:00 2001 From: Martin Westergaard Date: Wed, 27 Oct 2010 21:50:28 +0200 Subject: [PATCH] test --- .../rcracki_mt/ChainWalkContext.cpp | 1256 ++--- .../rcracki_mt/ChainWalkContext.h | 208 +- .../rcracki_mt/ChainWalkSet.cpp | 648 +-- Client Applications/rcracki_mt/ChainWalkSet.h | 154 +- Client Applications/rcracki_mt/ChangeLog.txt | 164 +- .../rcracki_mt/CrackEngine.cpp | 2874 +++++------ Client Applications/rcracki_mt/CrackEngine.h | 196 +- .../rcracki_mt/HashAlgorithm.cpp | 856 ++-- .../rcracki_mt/HashAlgorithm.h | 128 +- .../rcracki_mt/HashRoutine.cpp | 192 +- Client Applications/rcracki_mt/HashRoutine.h | 110 +- Client Applications/rcracki_mt/HashSet.cpp | 366 +- Client Applications/rcracki_mt/HashSet.h | 118 +- Client Applications/rcracki_mt/MemoryPool.cpp | 220 +- Client Applications/rcracki_mt/MemoryPool.h | 98 +- Client Applications/rcracki_mt/Public.cpp | 874 ++-- Client Applications/rcracki_mt/Public.h | 276 +- Client Applications/rcracki_mt/README.txt | 342 +- .../rcracki_mt/RainbowCrack.cpp | 1738 +++---- Client Applications/rcracki_mt/lm2ntlm.cpp | 4538 ++++++++--------- Client Applications/rcracki_mt/lm2ntlm.h | 160 +- Client Applications/rcracki_mt/md4.cpp | 668 +-- Client Applications/rcracki_mt/md4.h | 70 +- .../rcracki_mt/rcrackiThread.cpp | 494 +- .../rcracki_mt/rcrackiThread.h | 170 +- Client Applications/rcracki_mt/rcracki_mt.ini | 64 +- Client Applications/rcracki_mt/sha1.cpp | 696 +-- Client Applications/rcracki_mt/sha1.h | 66 +- 28 files changed, 8872 insertions(+), 8872 deletions(-) diff --git a/Client Applications/rcracki_mt/ChainWalkContext.cpp b/Client Applications/rcracki_mt/ChainWalkContext.cpp index ae58f77..01a46e0 100644 --- a/Client Applications/rcracki_mt/ChainWalkContext.cpp +++ b/Client Applications/rcracki_mt/ChainWalkContext.cpp @@ -1,628 +1,628 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * Copyright 2010 Yngve AAdlandsvik - * - * This file is part of rcracki_mt. - * - * rcracki_mt is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * rcracki_mt is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rcracki_mt. If not, see . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "ChainWalkContext.h" - -#include - -////////////////////////////////////////////////////////////////////// - -string CChainWalkContext::m_sHashRoutineName; -HASHROUTINE CChainWalkContext::m_pHashRoutine; -int CChainWalkContext::m_nHashLen; -int CChainWalkContext::m_nPlainLenMinTotal = 0; -int CChainWalkContext::m_nPlainLenMaxTotal = 0; -int CChainWalkContext::m_nHybridCharset = 0; -bool CChainWalkContext::isOldRtFormat = false; -bool CChainWalkContext::isRti2RtFormat = false; -vector CChainWalkContext::m_vCharset; -uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1]; -uint64 CChainWalkContext::m_nPlainSpaceTotal; -unsigned char CChainWalkContext::m_Salt[MAX_SALT_LEN]; -int CChainWalkContext::m_nSaltLen = 0; -int CChainWalkContext::m_nRainbowTableIndex; -uint64 CChainWalkContext::m_nReduceOffset; - -////////////////////////////////////////////////////////////////////// - -CChainWalkContext::CChainWalkContext() -{ -} - -CChainWalkContext::~CChainWalkContext() -{ -} - -bool CChainWalkContext::LoadCharset(string sName) -{ - m_vCharset.clear(); - if (sName == "byte") - { - stCharset tCharset; - int i; - for (i = 0x00; i <= 0xff; i++) - tCharset.m_PlainCharset[i] = (unsigned char) i; - tCharset.m_nPlainCharsetLen = 256; - tCharset.m_sPlainCharsetName = sName; - tCharset.m_sPlainCharsetContent = "0x00, 0x01, ... 0xff"; - m_vCharset.push_back(tCharset); - return true; - } - if(sName.substr(0, 6) == "hybrid") // Hybrid charset consisting of 2 charsets - m_nHybridCharset = 1; - else - m_nHybridCharset = 0; - - bool readCharset = false; - vector vLine; - - if ( ReadLinesFromFile("charset.txt", vLine) ) - readCharset = true; - else if ( ReadLinesFromFile(GetApplicationPath() + "charset.txt", vLine) ) - readCharset = true; - - if (readCharset) - { - UINT4 i; - for (i = 0; i < vLine.size(); i++) - { - // Filter comment - if (vLine[i][0] == '#') - continue; - - vector vPart; - if (SeperateString(vLine[i], "=", vPart)) - { - // sCharsetName - string sCharsetName = TrimString(vPart[0]); - if (sCharsetName == "") - continue; - - // sCharsetName charset check - bool fCharsetNameCheckPass = true; - UINT4 j; - for (j = 0; j < sCharsetName.size(); j++) - { - if ( !isalpha(sCharsetName[j]) - && !isdigit(sCharsetName[j]) - && (sCharsetName[j] != '-')) - { - fCharsetNameCheckPass = false; - break; - } - } - if (!fCharsetNameCheckPass) - { - printf("invalid charset name %s in charset configuration file\n", sCharsetName.c_str()); - continue; - } - - // sCharsetContent - string sCharsetContent = TrimString(vPart[1]); - if (sCharsetContent == "" || sCharsetContent == "[]") - continue; - if (sCharsetContent[0] != '[' || sCharsetContent[sCharsetContent.size() - 1] != ']') - { - printf("invalid charset content %s in charset configuration file\n", sCharsetContent.c_str()); - continue; - } - sCharsetContent = sCharsetContent.substr(1, sCharsetContent.size() - 2); - if (sCharsetContent.size() > 256) - { - printf("charset content %s too long\n", sCharsetContent.c_str()); - continue; - } - - //printf("%s = [%s]\n", sCharsetName.c_str(), sCharsetContent.c_str()); - - // Is it the wanted charset? - if(m_nHybridCharset == 1) - { - vector vCharsets; - GetHybridCharsets(sName, vCharsets); - if(sCharsetName == vCharsets[m_vCharset.size()].sName) - { - stCharset tCharset; - tCharset.m_nPlainCharsetLen = sCharsetContent.size(); - memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen); - tCharset.m_sPlainCharsetName = sCharsetName; - tCharset.m_sPlainCharsetContent = sCharsetContent; - tCharset.m_nPlainLenMin = vCharsets[m_vCharset.size()].nPlainLenMin; - tCharset.m_nPlainLenMax = vCharsets[m_vCharset.size()].nPlainLenMax; - m_vCharset.push_back(tCharset); - if(vCharsets.size() == m_vCharset.size()) - return true; - i = 0; // Start the lookup over again for the next charset - } - } - else if (sCharsetName == sName) - { - stCharset tCharset; - tCharset.m_nPlainCharsetLen = sCharsetContent.size(); - memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen); - tCharset.m_sPlainCharsetName = sCharsetName; - tCharset.m_sPlainCharsetContent = sCharsetContent; - m_vCharset.push_back(tCharset); - return true; - } - } - } - printf("charset %s not found in charset.txt\n", sName.c_str()); - } - else - printf("can't open charset configuration file\n"); - return false; -} - -////////////////////////////////////////////////////////////////////// - -bool CChainWalkContext::SetHashRoutine(string sHashRoutineName) -{ - CHashRoutine hr; - hr.GetHashRoutine(sHashRoutineName, m_pHashRoutine, m_nHashLen); - if (m_pHashRoutine != NULL) - { - m_sHashRoutineName = sHashRoutineName; - return true; - } - else - return false; -} - -bool CChainWalkContext::SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax) -{ - // m_PlainCharset, m_nPlainCharsetLen, m_sPlainCharsetName, m_sPlainCharsetContent - if (!LoadCharset(sCharsetName)) - return false; - - if(m_vCharset.size() == 1) // Not hybrid charset - { - // m_nPlainLenMin, m_nPlainLenMax - if (nPlainLenMin < 1 || nPlainLenMax > MAX_PLAIN_LEN || nPlainLenMin > nPlainLenMax) - { - printf("invalid plaintext length range: %d - %d\n", nPlainLenMin, nPlainLenMax); - return false; - } - m_vCharset[0].m_nPlainLenMin = nPlainLenMin; - m_vCharset[0].m_nPlainLenMax = nPlainLenMax; - } - // m_nPlainSpaceUpToX - m_nPlainSpaceUpToX[0] = 0; - m_nPlainLenMaxTotal = 0; - m_nPlainLenMinTotal = 0; - uint64 nTemp = 1; - UINT4 j, k = 1; - for(j = 0; j < m_vCharset.size(); j++) - { - int i; - m_nPlainLenMaxTotal += m_vCharset[j].m_nPlainLenMax; - m_nPlainLenMinTotal += m_vCharset[j].m_nPlainLenMin; - for (i = 1; i <= m_vCharset[j].m_nPlainLenMax; i++) - { - nTemp *= m_vCharset[j].m_nPlainCharsetLen; - if (i < m_vCharset[j].m_nPlainLenMin) - m_nPlainSpaceUpToX[k] = 0; - else - m_nPlainSpaceUpToX[k] = m_nPlainSpaceUpToX[k - 1] + nTemp; - k++; - } - } - // m_nPlainSpaceTotal - m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal]; - - return true; -} - -bool CChainWalkContext::SetRainbowTableIndex(int nRainbowTableIndex) -{ - if (nRainbowTableIndex < 0) - return false; - m_nRainbowTableIndex = nRainbowTableIndex; - m_nReduceOffset = 65536 * nRainbowTableIndex; - - return true; -} - -bool CChainWalkContext::SetSalt(unsigned char *Salt, int nSaltLength) -{ - memcpy(&m_Salt[0], Salt, nSaltLength); - - m_nSaltLen = nSaltLength; -// m_sSalt = sSalt; - return true; -} - -bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount) -{ - // something like lm_alpha#1-7_0_100x16_test.rt - -#ifdef _WIN32 - string::size_type nIndex = sPathName.find_last_of('\\'); -#else - string::size_type nIndex = sPathName.find_last_of('/'); -#endif - if (nIndex != string::npos) - sPathName = sPathName.substr(nIndex + 1); - - if (sPathName.size() < 3) - { - printf("%s is not a rainbow table\n", sPathName.c_str()); - return false; - } - if (sPathName.substr(sPathName.size() - 5) == ".rti2") - { - isRti2RtFormat = true; - } - else if (sPathName.substr(sPathName.size() - 4) == ".rti") - { - isOldRtFormat = false; - } - else if (sPathName.substr(sPathName.size() - 3) == ".rt") - { - isOldRtFormat = true; - } - else - { - printf("%s is not a rainbow table\n", sPathName.c_str()); - return false; - } - - // Parse - vector vPart; - if (!SeperateString(sPathName, "___x_", vPart)) - { - printf("filename %s not identified\n", sPathName.c_str()); - return false; - } - - string sHashRoutineName = vPart[0]; - int nRainbowTableIndex = atoi(vPart[2].c_str()); - nRainbowChainLen = atoi(vPart[3].c_str()); - nRainbowChainCount = atoi(vPart[4].c_str()); - - // Parse charset definition - string sCharsetDefinition = vPart[1]; - string sCharsetName; - int nPlainLenMin = 0, nPlainLenMax = 0; - -// printf("Charset: %s", sCharsetDefinition.c_str()); - - if(sCharsetDefinition.substr(0, 6) == "hybrid") // Hybrid table - { - sCharsetName = sCharsetDefinition; - } - else - { - if ( sCharsetDefinition.find('#') == string::npos ) // For backward compatibility, "#1-7" is implied - { - sCharsetName = sCharsetDefinition; - nPlainLenMin = 1; - nPlainLenMax = 7; - } - else - { - vector vCharsetDefinitionPart; - if (!SeperateString(sCharsetDefinition, "#-", vCharsetDefinitionPart)) - { - printf("filename %s not identified\n", sPathName.c_str()); - return false; - } - else - { - sCharsetName = vCharsetDefinitionPart[0]; - nPlainLenMin = atoi(vCharsetDefinitionPart[1].c_str()); - nPlainLenMax = atoi(vCharsetDefinitionPart[2].c_str()); - } - } - } - // Setup - if (!SetHashRoutine(sHashRoutineName)) - { - printf("hash routine %s not supported\n", sHashRoutineName.c_str()); - return false; - } - if (!SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax)) - return false; - if (!SetRainbowTableIndex(nRainbowTableIndex)) - { - printf("invalid rainbow table index %d\n", nRainbowTableIndex); - return false; - } - m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal]; - return true; -} - -string CChainWalkContext::GetHashRoutineName() -{ - return m_sHashRoutineName; -} - -int CChainWalkContext::GetHashLen() -{ - return m_nHashLen; -} - -string CChainWalkContext::GetPlainCharsetName() -{ - return m_vCharset[0].m_sPlainCharsetName; -} - -string CChainWalkContext::GetPlainCharsetContent() -{ - return m_vCharset[0].m_sPlainCharsetContent; -} - -int CChainWalkContext::GetPlainLenMin() -{ - return m_vCharset[0].m_nPlainLenMin; -} - -int CChainWalkContext::GetPlainLenMax() -{ - return m_vCharset[0].m_nPlainLenMax; -} - -uint64 CChainWalkContext::GetPlainSpaceTotal() -{ - return m_nPlainSpaceTotal; -} - -int CChainWalkContext::GetRainbowTableIndex() -{ - return m_nRainbowTableIndex; -} - -void CChainWalkContext::Dump() -{ - printf("hash routine: %s\n", m_sHashRoutineName.c_str()); - printf("hash length: %d\n", m_nHashLen); - - printf("plain charset: "); - unsigned int i; - for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++) - { - if (isprint(m_vCharset[0].m_PlainCharset[i])) - printf("%c", m_vCharset[0].m_PlainCharset[i]); - else - printf("?"); - } - printf("\n"); - - printf("plain charset in hex: "); - for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++) - printf("%02x ", m_vCharset[0].m_PlainCharset[i]); - printf("\n"); - - printf("plain length range: %d - %d\n", m_vCharset[0].m_nPlainLenMin, m_vCharset[0].m_nPlainLenMax); - printf("plain charset name: %s\n", m_vCharset[0].m_sPlainCharsetName.c_str()); - //printf("plain charset content: %s\n", m_sPlainCharsetContent.c_str()); - //for (i = 0; i <= m_nPlainLenMax; i++) - // printf("plain space up to %d: %s\n", i, uint64tostr(m_nPlainSpaceUpToX[i]).c_str()); - printf("plain space total: %s\n", uint64tostr(m_nPlainSpaceTotal).c_str()); - - printf("rainbow table index: %d\n", m_nRainbowTableIndex); - printf("reduce offset: %s\n", uint64tostr(m_nReduceOffset).c_str()); - printf("\n"); -} - -void CChainWalkContext::SetIndex(uint64 nIndex) -{ - m_nIndex = nIndex; -} - -void CChainWalkContext::SetHash(unsigned char* pHash) -{ - memcpy(m_Hash, pHash, m_nHashLen); -} - -void CChainWalkContext::IndexToPlain() -{ - int i; - m_nPlainLen = 0; -///* - for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1; i--) - { - if (m_nIndex >= m_nPlainSpaceUpToX[i]) - { - m_nPlainLen = i + 1; - break; - } - } - - // this is an optimized version of the above -/* - for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1 - && m_nIndex < m_nPlainSpaceUpToX[i]; i--) - { } - - m_nPlainLen = i + 1; -*/ - - if(m_nPlainLen == 0) - m_nPlainLen = m_nPlainLenMinTotal; - uint64 nIndexOfX = m_nIndex - m_nPlainSpaceUpToX[m_nPlainLen - 1]; - -// this is the generic code for non x86/x86_64 platforms -#if !defined(_M_X64) && !defined(_M_IX86) && !defined(__i386__) && !defined(__x86_64__) - - // generic version (slow for non 64-bit platforms and gcc < 4.5.x) - for (i = m_nPlainLen - 1; i >= 0; i--) - { - int nCharsetLen = 0; - for(UINT4 j = 0; j < m_vCharset.size(); j++) - { - nCharsetLen += m_vCharset[j].m_nPlainLenMax; - if(i < nCharsetLen) // We found the correct charset - { - m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen]; - nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen; - break; - } - } - } - -#elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__) - - // Fast ia32 version - for (i = m_nPlainLen - 1; i >= 0; i--) - { - // 0x100000000 = 2^32 -#ifdef _M_IX86 - if (nIndexOfX < 0x100000000I64) - break; -#else - if (nIndexOfX < 0x100000000llu) - break; -#endif - - int nCharsetLen = 0; - for(UINT4 j = 0; j < m_vCharset.size(); j++) - { - nCharsetLen += m_vCharset[j].m_nPlainLenMax; - if(i < nCharsetLen) // We found the correct charset - { - m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen]; - nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen; - break; - } - } - } - - UINT4 nIndexOfX32 = (UINT4)nIndexOfX; - for (; i >= 0; i--) - { - int nCharsetLen = 0; - for(UINT4 j = 0; j < m_vCharset.size(); j++) - { - nCharsetLen += m_vCharset[j].m_nPlainLenMax; - if(i < nCharsetLen) // We found the correct charset - { - -// m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX32 % m_vCharset[j].m_nPlainCharsetLen]; -// nIndexOfX32 /= m_vCharset[j].m_nPlainCharsetLen; - - -// moving nPlainCharsetLen into the asm body and avoiding the extra temp -// variable results in a performance gain -// unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen; - unsigned int nTemp; - -#if defined(_WIN32) && !defined(__GNUC__) - - // VC++ still needs this - unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen; - - __asm - { - mov eax, nIndexOfX32 - xor edx, edx - div nPlainCharsetLen - mov nIndexOfX32, eax - mov nTemp, edx - } - m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp]; -#else - __asm__ __volatile__ ( "mov %2, %%eax;" - "xor %%edx, %%edx;" - "divl %3;" - "mov %%eax, %0;" - "mov %%edx, %1;" - : "=m"(nIndexOfX32), "=m"(nTemp) - : "m"(nIndexOfX32), "m"(m_vCharset[j].m_nPlainCharsetLen) - : "%eax", "%edx" - ); - m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp]; -#endif - break; - } - } - } -#endif -} - -void CChainWalkContext::PlainToHash() -{ - m_pHashRoutine(m_Plain, m_nPlainLen, m_Hash); -} - -void CChainWalkContext::HashToIndex(int nPos) -{ - m_nIndex = (*(uint64*)m_Hash + m_nReduceOffset + nPos) % m_nPlainSpaceTotal; -} - -uint64 CChainWalkContext::GetIndex() -{ - return m_nIndex; -} -const uint64 *CChainWalkContext::GetIndexPtr() -{ - return &m_nIndex; -} - -string CChainWalkContext::GetPlain() -{ - string sRet; - int i; - for (i = 0; i < m_nPlainLen; i++) - { - char c = m_Plain[i]; - sRet += c; - } - - return sRet; -} - -string CChainWalkContext::GetBinary() -{ - return HexToStr(m_Plain, m_nPlainLen); -} - -string CChainWalkContext::GetHash() -{ - return HexToStr(m_Hash, m_nHashLen); -} - -bool CChainWalkContext::CheckHash(unsigned char* pHash) -{ - if (memcmp(m_Hash, pHash, m_nHashLen) == 0) - return true; - - return false; -} - -bool CChainWalkContext::isOldFormat() -{ - return isOldRtFormat; -} - -bool CChainWalkContext::isRti2Format() -{ - return isRti2RtFormat; -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * Copyright 2010 Yngve AAdlandsvik + * + * This file is part of rcracki_mt. + * + * rcracki_mt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * rcracki_mt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with rcracki_mt. If not, see . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "ChainWalkContext.h" + +#include + +////////////////////////////////////////////////////////////////////// + +string CChainWalkContext::m_sHashRoutineName; +HASHROUTINE CChainWalkContext::m_pHashRoutine; +int CChainWalkContext::m_nHashLen; +int CChainWalkContext::m_nPlainLenMinTotal = 0; +int CChainWalkContext::m_nPlainLenMaxTotal = 0; +int CChainWalkContext::m_nHybridCharset = 0; +bool CChainWalkContext::isOldRtFormat = false; +bool CChainWalkContext::isRti2RtFormat = false; +vector CChainWalkContext::m_vCharset; +uint64 CChainWalkContext::m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1]; +uint64 CChainWalkContext::m_nPlainSpaceTotal; +unsigned char CChainWalkContext::m_Salt[MAX_SALT_LEN]; +int CChainWalkContext::m_nSaltLen = 0; +int CChainWalkContext::m_nRainbowTableIndex; +uint64 CChainWalkContext::m_nReduceOffset; + +////////////////////////////////////////////////////////////////////// + +CChainWalkContext::CChainWalkContext() +{ +} + +CChainWalkContext::~CChainWalkContext() +{ +} + +bool CChainWalkContext::LoadCharset(string sName) +{ + m_vCharset.clear(); + if (sName == "byte") + { + stCharset tCharset; + int i; + for (i = 0x00; i <= 0xff; i++) + tCharset.m_PlainCharset[i] = (unsigned char) i; + tCharset.m_nPlainCharsetLen = 256; + tCharset.m_sPlainCharsetName = sName; + tCharset.m_sPlainCharsetContent = "0x00, 0x01, ... 0xff"; + m_vCharset.push_back(tCharset); + return true; + } + if(sName.substr(0, 6) == "hybrid") // Hybrid charset consisting of 2 charsets + m_nHybridCharset = 1; + else + m_nHybridCharset = 0; + + bool readCharset = false; + vector vLine; + + if ( ReadLinesFromFile("charset.txt", vLine) ) + readCharset = true; + else if ( ReadLinesFromFile(GetApplicationPath() + "charset.txt", vLine) ) + readCharset = true; + + if (readCharset) + { + UINT4 i; + for (i = 0; i < vLine.size(); i++) + { + // Filter comment + if (vLine[i][0] == '#') + continue; + + vector vPart; + if (SeperateString(vLine[i], "=", vPart)) + { + // sCharsetName + string sCharsetName = TrimString(vPart[0]); + if (sCharsetName == "") + continue; + + // sCharsetName charset check + bool fCharsetNameCheckPass = true; + UINT4 j; + for (j = 0; j < sCharsetName.size(); j++) + { + if ( !isalpha(sCharsetName[j]) + && !isdigit(sCharsetName[j]) + && (sCharsetName[j] != '-')) + { + fCharsetNameCheckPass = false; + break; + } + } + if (!fCharsetNameCheckPass) + { + printf("invalid charset name %s in charset configuration file\n", sCharsetName.c_str()); + continue; + } + + // sCharsetContent + string sCharsetContent = TrimString(vPart[1]); + if (sCharsetContent == "" || sCharsetContent == "[]") + continue; + if (sCharsetContent[0] != '[' || sCharsetContent[sCharsetContent.size() - 1] != ']') + { + printf("invalid charset content %s in charset configuration file\n", sCharsetContent.c_str()); + continue; + } + sCharsetContent = sCharsetContent.substr(1, sCharsetContent.size() - 2); + if (sCharsetContent.size() > 256) + { + printf("charset content %s too long\n", sCharsetContent.c_str()); + continue; + } + + //printf("%s = [%s]\n", sCharsetName.c_str(), sCharsetContent.c_str()); + + // Is it the wanted charset? + if(m_nHybridCharset == 1) + { + vector vCharsets; + GetHybridCharsets(sName, vCharsets); + if(sCharsetName == vCharsets[m_vCharset.size()].sName) + { + stCharset tCharset; + tCharset.m_nPlainCharsetLen = sCharsetContent.size(); + memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen); + tCharset.m_sPlainCharsetName = sCharsetName; + tCharset.m_sPlainCharsetContent = sCharsetContent; + tCharset.m_nPlainLenMin = vCharsets[m_vCharset.size()].nPlainLenMin; + tCharset.m_nPlainLenMax = vCharsets[m_vCharset.size()].nPlainLenMax; + m_vCharset.push_back(tCharset); + if(vCharsets.size() == m_vCharset.size()) + return true; + i = 0; // Start the lookup over again for the next charset + } + } + else if (sCharsetName == sName) + { + stCharset tCharset; + tCharset.m_nPlainCharsetLen = sCharsetContent.size(); + memcpy(tCharset.m_PlainCharset, sCharsetContent.c_str(), tCharset.m_nPlainCharsetLen); + tCharset.m_sPlainCharsetName = sCharsetName; + tCharset.m_sPlainCharsetContent = sCharsetContent; + m_vCharset.push_back(tCharset); + return true; + } + } + } + printf("charset %s not found in charset.txt\n", sName.c_str()); + } + else + printf("can't open charset configuration file\n"); + return false; +} + +////////////////////////////////////////////////////////////////////// + +bool CChainWalkContext::SetHashRoutine(string sHashRoutineName) +{ + CHashRoutine hr; + hr.GetHashRoutine(sHashRoutineName, m_pHashRoutine, m_nHashLen); + if (m_pHashRoutine != NULL) + { + m_sHashRoutineName = sHashRoutineName; + return true; + } + else + return false; +} + +bool CChainWalkContext::SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax) +{ + // m_PlainCharset, m_nPlainCharsetLen, m_sPlainCharsetName, m_sPlainCharsetContent + if (!LoadCharset(sCharsetName)) + return false; + + if(m_vCharset.size() == 1) // Not hybrid charset + { + // m_nPlainLenMin, m_nPlainLenMax + if (nPlainLenMin < 1 || nPlainLenMax > MAX_PLAIN_LEN || nPlainLenMin > nPlainLenMax) + { + printf("invalid plaintext length range: %d - %d\n", nPlainLenMin, nPlainLenMax); + return false; + } + m_vCharset[0].m_nPlainLenMin = nPlainLenMin; + m_vCharset[0].m_nPlainLenMax = nPlainLenMax; + } + // m_nPlainSpaceUpToX + m_nPlainSpaceUpToX[0] = 0; + m_nPlainLenMaxTotal = 0; + m_nPlainLenMinTotal = 0; + uint64 nTemp = 1; + UINT4 j, k = 1; + for(j = 0; j < m_vCharset.size(); j++) + { + int i; + m_nPlainLenMaxTotal += m_vCharset[j].m_nPlainLenMax; + m_nPlainLenMinTotal += m_vCharset[j].m_nPlainLenMin; + for (i = 1; i <= m_vCharset[j].m_nPlainLenMax; i++) + { + nTemp *= m_vCharset[j].m_nPlainCharsetLen; + if (i < m_vCharset[j].m_nPlainLenMin) + m_nPlainSpaceUpToX[k] = 0; + else + m_nPlainSpaceUpToX[k] = m_nPlainSpaceUpToX[k - 1] + nTemp; + k++; + } + } + // m_nPlainSpaceTotal + m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal]; + + return true; +} + +bool CChainWalkContext::SetRainbowTableIndex(int nRainbowTableIndex) +{ + if (nRainbowTableIndex < 0) + return false; + m_nRainbowTableIndex = nRainbowTableIndex; + m_nReduceOffset = 65536 * nRainbowTableIndex; + + return true; +} + +bool CChainWalkContext::SetSalt(unsigned char *Salt, int nSaltLength) +{ + memcpy(&m_Salt[0], Salt, nSaltLength); + + m_nSaltLen = nSaltLength; +// m_sSalt = sSalt; + return true; +} + +bool CChainWalkContext::SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount) +{ + // something like lm_alpha#1-7_0_100x16_test.rt + +#ifdef _WIN32 + string::size_type nIndex = sPathName.find_last_of('\\'); +#else + string::size_type nIndex = sPathName.find_last_of('/'); +#endif + if (nIndex != string::npos) + sPathName = sPathName.substr(nIndex + 1); + + if (sPathName.size() < 3) + { + printf("%s is not a rainbow table\n", sPathName.c_str()); + return false; + } + if (sPathName.substr(sPathName.size() - 5) == ".rti2") + { + isRti2RtFormat = true; + } + else if (sPathName.substr(sPathName.size() - 4) == ".rti") + { + isOldRtFormat = false; + } + else if (sPathName.substr(sPathName.size() - 3) == ".rt") + { + isOldRtFormat = true; + } + else + { + printf("%s is not a rainbow table\n", sPathName.c_str()); + return false; + } + + // Parse + vector vPart; + if (!SeperateString(sPathName, "___x_", vPart)) + { + printf("filename %s not identified\n", sPathName.c_str()); + return false; + } + + string sHashRoutineName = vPart[0]; + int nRainbowTableIndex = atoi(vPart[2].c_str()); + nRainbowChainLen = atoi(vPart[3].c_str()); + nRainbowChainCount = atoi(vPart[4].c_str()); + + // Parse charset definition + string sCharsetDefinition = vPart[1]; + string sCharsetName; + int nPlainLenMin = 0, nPlainLenMax = 0; + +// printf("Charset: %s", sCharsetDefinition.c_str()); + + if(sCharsetDefinition.substr(0, 6) == "hybrid") // Hybrid table + { + sCharsetName = sCharsetDefinition; + } + else + { + if ( sCharsetDefinition.find('#') == string::npos ) // For backward compatibility, "#1-7" is implied + { + sCharsetName = sCharsetDefinition; + nPlainLenMin = 1; + nPlainLenMax = 7; + } + else + { + vector vCharsetDefinitionPart; + if (!SeperateString(sCharsetDefinition, "#-", vCharsetDefinitionPart)) + { + printf("filename %s not identified\n", sPathName.c_str()); + return false; + } + else + { + sCharsetName = vCharsetDefinitionPart[0]; + nPlainLenMin = atoi(vCharsetDefinitionPart[1].c_str()); + nPlainLenMax = atoi(vCharsetDefinitionPart[2].c_str()); + } + } + } + // Setup + if (!SetHashRoutine(sHashRoutineName)) + { + printf("hash routine %s not supported\n", sHashRoutineName.c_str()); + return false; + } + if (!SetPlainCharset(sCharsetName, nPlainLenMin, nPlainLenMax)) + return false; + if (!SetRainbowTableIndex(nRainbowTableIndex)) + { + printf("invalid rainbow table index %d\n", nRainbowTableIndex); + return false; + } + m_nPlainSpaceTotal = m_nPlainSpaceUpToX[m_nPlainLenMaxTotal]; + return true; +} + +string CChainWalkContext::GetHashRoutineName() +{ + return m_sHashRoutineName; +} + +int CChainWalkContext::GetHashLen() +{ + return m_nHashLen; +} + +string CChainWalkContext::GetPlainCharsetName() +{ + return m_vCharset[0].m_sPlainCharsetName; +} + +string CChainWalkContext::GetPlainCharsetContent() +{ + return m_vCharset[0].m_sPlainCharsetContent; +} + +int CChainWalkContext::GetPlainLenMin() +{ + return m_vCharset[0].m_nPlainLenMin; +} + +int CChainWalkContext::GetPlainLenMax() +{ + return m_vCharset[0].m_nPlainLenMax; +} + +uint64 CChainWalkContext::GetPlainSpaceTotal() +{ + return m_nPlainSpaceTotal; +} + +int CChainWalkContext::GetRainbowTableIndex() +{ + return m_nRainbowTableIndex; +} + +void CChainWalkContext::Dump() +{ + printf("hash routine: %s\n", m_sHashRoutineName.c_str()); + printf("hash length: %d\n", m_nHashLen); + + printf("plain charset: "); + unsigned int i; + for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++) + { + if (isprint(m_vCharset[0].m_PlainCharset[i])) + printf("%c", m_vCharset[0].m_PlainCharset[i]); + else + printf("?"); + } + printf("\n"); + + printf("plain charset in hex: "); + for (i = 0; i < m_vCharset[0].m_nPlainCharsetLen; i++) + printf("%02x ", m_vCharset[0].m_PlainCharset[i]); + printf("\n"); + + printf("plain length range: %d - %d\n", m_vCharset[0].m_nPlainLenMin, m_vCharset[0].m_nPlainLenMax); + printf("plain charset name: %s\n", m_vCharset[0].m_sPlainCharsetName.c_str()); + //printf("plain charset content: %s\n", m_sPlainCharsetContent.c_str()); + //for (i = 0; i <= m_nPlainLenMax; i++) + // printf("plain space up to %d: %s\n", i, uint64tostr(m_nPlainSpaceUpToX[i]).c_str()); + printf("plain space total: %s\n", uint64tostr(m_nPlainSpaceTotal).c_str()); + + printf("rainbow table index: %d\n", m_nRainbowTableIndex); + printf("reduce offset: %s\n", uint64tostr(m_nReduceOffset).c_str()); + printf("\n"); +} + +void CChainWalkContext::SetIndex(uint64 nIndex) +{ + m_nIndex = nIndex; +} + +void CChainWalkContext::SetHash(unsigned char* pHash) +{ + memcpy(m_Hash, pHash, m_nHashLen); +} + +void CChainWalkContext::IndexToPlain() +{ + int i; + m_nPlainLen = 0; +///* + for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1; i--) + { + if (m_nIndex >= m_nPlainSpaceUpToX[i]) + { + m_nPlainLen = i + 1; + break; + } + } + + // this is an optimized version of the above +/* + for (i = m_nPlainLenMaxTotal - 1; i >= m_nPlainLenMinTotal - 1 + && m_nIndex < m_nPlainSpaceUpToX[i]; i--) + { } + + m_nPlainLen = i + 1; +*/ + + if(m_nPlainLen == 0) + m_nPlainLen = m_nPlainLenMinTotal; + uint64 nIndexOfX = m_nIndex - m_nPlainSpaceUpToX[m_nPlainLen - 1]; + +// this is the generic code for non x86/x86_64 platforms +#if !defined(_M_X64) && !defined(_M_IX86) && !defined(__i386__) && !defined(__x86_64__) + + // generic version (slow for non 64-bit platforms and gcc < 4.5.x) + for (i = m_nPlainLen - 1; i >= 0; i--) + { + int nCharsetLen = 0; + for(UINT4 j = 0; j < m_vCharset.size(); j++) + { + nCharsetLen += m_vCharset[j].m_nPlainLenMax; + if(i < nCharsetLen) // We found the correct charset + { + m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen]; + nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen; + break; + } + } + } + +#elif defined(_M_X64) || defined(_M_IX86) || defined(__i386__) || defined(__x86_64__) + + // Fast ia32 version + for (i = m_nPlainLen - 1; i >= 0; i--) + { + // 0x100000000 = 2^32 +#ifdef _M_IX86 + if (nIndexOfX < 0x100000000I64) + break; +#else + if (nIndexOfX < 0x100000000llu) + break; +#endif + + int nCharsetLen = 0; + for(UINT4 j = 0; j < m_vCharset.size(); j++) + { + nCharsetLen += m_vCharset[j].m_nPlainLenMax; + if(i < nCharsetLen) // We found the correct charset + { + m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX % m_vCharset[j].m_nPlainCharsetLen]; + nIndexOfX /= m_vCharset[j].m_nPlainCharsetLen; + break; + } + } + } + + UINT4 nIndexOfX32 = (UINT4)nIndexOfX; + for (; i >= 0; i--) + { + int nCharsetLen = 0; + for(UINT4 j = 0; j < m_vCharset.size(); j++) + { + nCharsetLen += m_vCharset[j].m_nPlainLenMax; + if(i < nCharsetLen) // We found the correct charset + { + +// m_Plain[i] = m_vCharset[j].m_PlainCharset[nIndexOfX32 % m_vCharset[j].m_nPlainCharsetLen]; +// nIndexOfX32 /= m_vCharset[j].m_nPlainCharsetLen; + + +// moving nPlainCharsetLen into the asm body and avoiding the extra temp +// variable results in a performance gain +// unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen; + unsigned int nTemp; + +#if defined(_WIN32) && !defined(__GNUC__) + + // VC++ still needs this + unsigned int nPlainCharsetLen = m_vCharset[j].m_nPlainCharsetLen; + + __asm + { + mov eax, nIndexOfX32 + xor edx, edx + div nPlainCharsetLen + mov nIndexOfX32, eax + mov nTemp, edx + } + m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp]; +#else + __asm__ __volatile__ ( "mov %2, %%eax;" + "xor %%edx, %%edx;" + "divl %3;" + "mov %%eax, %0;" + "mov %%edx, %1;" + : "=m"(nIndexOfX32), "=m"(nTemp) + : "m"(nIndexOfX32), "m"(m_vCharset[j].m_nPlainCharsetLen) + : "%eax", "%edx" + ); + m_Plain[i] = m_vCharset[j].m_PlainCharset[nTemp]; +#endif + break; + } + } + } +#endif +} + +void CChainWalkContext::PlainToHash() +{ + m_pHashRoutine(m_Plain, m_nPlainLen, m_Hash); +} + +void CChainWalkContext::HashToIndex(int nPos) +{ + m_nIndex = (*(uint64*)m_Hash + m_nReduceOffset + nPos) % m_nPlainSpaceTotal; +} + +uint64 CChainWalkContext::GetIndex() +{ + return m_nIndex; +} +const uint64 *CChainWalkContext::GetIndexPtr() +{ + return &m_nIndex; +} + +string CChainWalkContext::GetPlain() +{ + string sRet; + int i; + for (i = 0; i < m_nPlainLen; i++) + { + char c = m_Plain[i]; + sRet += c; + } + + return sRet; +} + +string CChainWalkContext::GetBinary() +{ + return HexToStr(m_Plain, m_nPlainLen); +} + +string CChainWalkContext::GetHash() +{ + return HexToStr(m_Hash, m_nHashLen); +} + +bool CChainWalkContext::CheckHash(unsigned char* pHash) +{ + if (memcmp(m_Hash, pHash, m_nHashLen) == 0) + return true; + + return false; +} + +bool CChainWalkContext::isOldFormat() +{ + return isOldRtFormat; +} + +bool CChainWalkContext::isRti2Format() +{ + return isRti2RtFormat; +} diff --git a/Client Applications/rcracki_mt/ChainWalkContext.h b/Client Applications/rcracki_mt/ChainWalkContext.h index 154daee..3c8f276 100644 --- a/Client Applications/rcracki_mt/ChainWalkContext.h +++ b/Client Applications/rcracki_mt/ChainWalkContext.h @@ -1,104 +1,104 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef _CHAINWALKCONTEXT_H -#define _CHAINWALKCONTEXT_H - -#include "HashRoutine.h" -#include "Public.h" - -typedef struct -{ - unsigned char m_PlainCharset[255]; - unsigned int m_nPlainCharsetLen; - int m_nPlainLenMin; - int m_nPlainLenMax; - string m_sPlainCharsetName; - string m_sPlainCharsetContent; -} stCharset; -class CChainWalkContext -{ -public: - CChainWalkContext(); - virtual ~CChainWalkContext(); - -private: - static string m_sHashRoutineName; - static HASHROUTINE m_pHashRoutine; // Configuration - static int m_nHashLen; // Configuration - static bool isOldRtFormat; - static bool isRti2RtFormat; - static vector m_vCharset; - static int m_nPlainLenMinTotal, m_nPlainLenMaxTotal; - static uint64 m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1]; // Performance consideration - static uint64 m_nPlainSpaceTotal; // Performance consideration - static int m_nHybridCharset; - static int m_nRainbowTableIndex; // Configuration - static uint64 m_nReduceOffset; // Performance consideration - - // Context - uint64 m_nIndex; - unsigned char m_Plain[MAX_PLAIN_LEN]; - int m_nPlainLen; - unsigned char m_Hash[MAX_HASH_LEN]; - static unsigned char m_Salt[MAX_SALT_LEN]; - static int m_nSaltLen; -private: - static bool LoadCharset(string sCharset); - -public: - static bool SetHashRoutine(string sHashRoutineName); // Configuration - static bool SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax); // Configuration - static bool SetRainbowTableIndex(int nRainbowTableIndex); - static bool SetSalt(unsigned char *Salt, int nSaltLength);// Configuration - static bool SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount); // Wrapper - static string GetHashRoutineName(); - static int GetHashLen(); - static string GetPlainCharsetName(); - static string GetPlainCharsetContent(); - static int GetPlainLenMin(); - static int GetPlainLenMax(); - static uint64 GetPlainSpaceTotal(); - static int GetRainbowTableIndex(); - static void Dump(); - static bool isOldFormat(); - static bool isRti2Format(); - - - void SetIndex(uint64 nIndex); - void SetHash(unsigned char* pHash); // The length should be m_nHashLen - - void IndexToPlain(); - void PlainToHash(); - void HashToIndex(int nPos); - - uint64 GetIndex(); - const uint64* GetIndexPtr(); - string GetPlain(); - string GetBinary(); - string GetHash(); - bool CheckHash(unsigned char* pHash); // The length should be m_nHashLen -}; - -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef _CHAINWALKCONTEXT_H +#define _CHAINWALKCONTEXT_H + +#include "HashRoutine.h" +#include "Public.h" + +typedef struct +{ + unsigned char m_PlainCharset[255]; + unsigned int m_nPlainCharsetLen; + int m_nPlainLenMin; + int m_nPlainLenMax; + string m_sPlainCharsetName; + string m_sPlainCharsetContent; +} stCharset; +class CChainWalkContext +{ +public: + CChainWalkContext(); + virtual ~CChainWalkContext(); + +private: + static string m_sHashRoutineName; + static HASHROUTINE m_pHashRoutine; // Configuration + static int m_nHashLen; // Configuration + static bool isOldRtFormat; + static bool isRti2RtFormat; + static vector m_vCharset; + static int m_nPlainLenMinTotal, m_nPlainLenMaxTotal; + static uint64 m_nPlainSpaceUpToX[MAX_PLAIN_LEN + 1]; // Performance consideration + static uint64 m_nPlainSpaceTotal; // Performance consideration + static int m_nHybridCharset; + static int m_nRainbowTableIndex; // Configuration + static uint64 m_nReduceOffset; // Performance consideration + + // Context + uint64 m_nIndex; + unsigned char m_Plain[MAX_PLAIN_LEN]; + int m_nPlainLen; + unsigned char m_Hash[MAX_HASH_LEN]; + static unsigned char m_Salt[MAX_SALT_LEN]; + static int m_nSaltLen; +private: + static bool LoadCharset(string sCharset); + +public: + static bool SetHashRoutine(string sHashRoutineName); // Configuration + static bool SetPlainCharset(string sCharsetName, int nPlainLenMin, int nPlainLenMax); // Configuration + static bool SetRainbowTableIndex(int nRainbowTableIndex); + static bool SetSalt(unsigned char *Salt, int nSaltLength);// Configuration + static bool SetupWithPathName(string sPathName, int& nRainbowChainLen, int& nRainbowChainCount); // Wrapper + static string GetHashRoutineName(); + static int GetHashLen(); + static string GetPlainCharsetName(); + static string GetPlainCharsetContent(); + static int GetPlainLenMin(); + static int GetPlainLenMax(); + static uint64 GetPlainSpaceTotal(); + static int GetRainbowTableIndex(); + static void Dump(); + static bool isOldFormat(); + static bool isRti2Format(); + + + void SetIndex(uint64 nIndex); + void SetHash(unsigned char* pHash); // The length should be m_nHashLen + + void IndexToPlain(); + void PlainToHash(); + void HashToIndex(int nPos); + + uint64 GetIndex(); + const uint64* GetIndexPtr(); + string GetPlain(); + string GetBinary(); + string GetHash(); + bool CheckHash(unsigned char* pHash); // The length should be m_nHashLen +}; + +#endif diff --git a/Client Applications/rcracki_mt/ChainWalkSet.cpp b/Client Applications/rcracki_mt/ChainWalkSet.cpp index 84db65f..cab23a1 100644 --- a/Client Applications/rcracki_mt/ChainWalkSet.cpp +++ b/Client Applications/rcracki_mt/ChainWalkSet.cpp @@ -1,324 +1,324 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#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::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; - - 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 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 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::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::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"); -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#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::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; + + 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 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 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::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::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"); +} diff --git a/Client Applications/rcracki_mt/ChainWalkSet.h b/Client Applications/rcracki_mt/ChainWalkSet.h index 7578007..f402dd8 100644 --- a/Client Applications/rcracki_mt/ChainWalkSet.h +++ b/Client Applications/rcracki_mt/ChainWalkSet.h @@ -1,77 +1,77 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef _CHAINWALKSET_H -#define _CHAINWALKSET_H - -#include "Public.h" - -struct ChainWalk -{ - unsigned char Hash[MAX_HASH_LEN]; - //int nHashLen; // Implied - uint64* pIndexE; // mapStartPosIndexE, Len = nRainbowChainLen - 1 -}; - -class CChainWalkSet -{ -public: - CChainWalkSet(); - virtual ~CChainWalkSet(); - -private: - string m_sHashRoutineName; // Discard all if not match - string m_sPlainCharsetName; // Discard all if not match - int m_nPlainLenMin; // Discard all if not match - int m_nPlainLenMax; // Discard all if not match - int m_nRainbowTableIndex; // Discard all if not match - int m_nRainbowChainLen; // Discard all if not match - list m_lChainWalk; - bool debug; - string sPrecalcPathName; - int preCalcPart; - vector vPrecalcFiles; - -private: - void DiscardAll(); - bool FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen); - string CheckOrRotatePreCalcFile(); - void updateUsedPrecalcFiles(); - -public: - uint64* RequestWalk(unsigned char* pHash, int nHashLen, - string sHashRoutineName, - string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax, - int nRainbowTableIndex, - int nRainbowChainLen, - bool& fNewlyGenerated, - bool setDebug, - string sPrecalc); - void DiscardWalk(uint64* pIndexE); - void StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen); - void removePrecalcFiles(); -}; - -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef _CHAINWALKSET_H +#define _CHAINWALKSET_H + +#include "Public.h" + +struct ChainWalk +{ + unsigned char Hash[MAX_HASH_LEN]; + //int nHashLen; // Implied + uint64* pIndexE; // mapStartPosIndexE, Len = nRainbowChainLen - 1 +}; + +class CChainWalkSet +{ +public: + CChainWalkSet(); + virtual ~CChainWalkSet(); + +private: + string m_sHashRoutineName; // Discard all if not match + string m_sPlainCharsetName; // Discard all if not match + int m_nPlainLenMin; // Discard all if not match + int m_nPlainLenMax; // Discard all if not match + int m_nRainbowTableIndex; // Discard all if not match + int m_nRainbowChainLen; // Discard all if not match + list m_lChainWalk; + bool debug; + string sPrecalcPathName; + int preCalcPart; + vector vPrecalcFiles; + +private: + void DiscardAll(); + bool FindInFile(uint64* pIndexE, unsigned char* pHash, int nHashLen); + string CheckOrRotatePreCalcFile(); + void updateUsedPrecalcFiles(); + +public: + uint64* RequestWalk(unsigned char* pHash, int nHashLen, + string sHashRoutineName, + string sPlainCharsetName, int nPlainLenMin, int nPlainLenMax, + int nRainbowTableIndex, + int nRainbowChainLen, + bool& fNewlyGenerated, + bool setDebug, + string sPrecalc); + void DiscardWalk(uint64* pIndexE); + void StoreToFile(uint64* pIndexE, unsigned char* pHash, int nHashLen); + void removePrecalcFiles(); +}; + +#endif diff --git a/Client Applications/rcracki_mt/ChangeLog.txt b/Client Applications/rcracki_mt/ChangeLog.txt index f22f28b..ecebd60 100644 --- a/Client Applications/rcracki_mt/ChangeLog.txt +++ b/Client Applications/rcracki_mt/ChangeLog.txt @@ -1,82 +1,82 @@ -[rcracki_mt ChangeLog] - -0.6.5.1 (25 Oct 2010, 15:50:10): -* rti2 fixes courtesy of PowerBlade - -0.6.5 (24 Oct 2010, 18:21:25): -* code changes to allow building via mingw and avoid VC++ -* linux thread priority set to nice value of 2 -* rti2 support -* replaced clock_t usage with gettimeofday -* add pre-calculation timing per feature request #3025688 from sourceforge -* fix bug #3050821 from sourceforge - missing break for non x86/x86_64 arch -* improve hash performance by moving off openssl to the local faster methods -* sha1 local implementation was *slower* than openssl for x86/x86_64 - -0.6.4 (05 Jul 2010, 03:12): -* add -m to allow users to limit memory usage - courtesy of uroskn -* fix memory code that made incorrect assumptions about the MemoryPool -* fix linux memory code - using only info.freeram is incorrect -* cleanup of the nested if/elif/else stuctures -* annotate x86 specific sections of code -* licensing review and GPLv2 compliance -* cleanup of unused items -* restructure Makefile -* cleanup memory leaks - -0.6.3 (21 Oct 2009, 21:05): -* Fixed x86_64 linux compilation -* Fixed x86_64 linux segmentation fault -* Fixed 64bit support in md4 code -* Added support for: FreeBSD, NetBSD, OpenBSD, and MacOSX - -0.6.2 (2 Jul 2009, 13:37): -* Fixed linux support (tty stuff and now actually compiles) -* Fixed precalculation code - -0.6.1 (14 May 2009, 22:12): -* bug fixed where the list of rainbow tables is doubled when you resume a session and you have default RT locations in your ini - -0.6 (14 May 2009, 20:47): -* Finding .rti files recursively -* Fixed memory allocation bugs (also trying to save appropriate amount of memory for chainwalksets... these can become really large with the new tables) -* Real pause/resume function, you can resume a session with -r -* Session support, use -s session_name. Combine this with -r to resume a session other then the default -* Ini file support, store some default values such as rainbow table directories. -* Tab separated results (stdout) -* Support pause during cracking and 'skip' during unicode correction for Linux -* A readme / 'manual' ! - -0.5 (16 Apr 2009, 22:47): -* Support for the old non-indexed .rt format, it should work with both type of tables in one run... I didn't test this feature thoroughly -* Using some other pieces of code for algorithms -* Support for .lst files from Cain as input (patch from James Dickson) - use for example -c LMNT.lst -* Fixed some bugs -* Dunno anymore, left this version lying around for too long... - -0.4 (oops, a second 0.4) (13 Dec 2008, 18:20): -* Improved file reading performance - -0.4 (27 Nov 2008, 00:09): -* Source included -* Memory usage down to about 50% (tnx sc00bz for pointing out the inefficiency, tnx jci for helping with the code) -* Works under Linux! (using pthreads now instead of Windows threads) -* Speed up: implemented MD4 reference implementation, not using OpenSSL for NTLM anymore (tnx Bitweasil for supplying 98% of the code) -* Speed up: using OpenSSL a lot faster (tnx jci for pointing that out) -* Probably some more small things i forgot - -0.3 (16 Nov 2008, 01:01): -* Improved command line argument parsing (order no longer matters) -* Option to write (temporary) output to a file, use -o pick_a_nice_filename.txt -* Option to pause, press 'P' to pause/unpause (Windows only) -* For pwdump searches: unicode correction is done when case correction fails - -0.2 (28 Oct 2008, 01:42): -* False alarm checking now also multi threaded -* Search one level of subdirectories for rainbow table files - -0.1 (27 Oct 2008, 00:14): -* Initial multithreaded version, using Windows threads. -* Using multiple threads for the pre-calculation part. -* Added a simple 'progress' message, so you can see how many hashes are being pre-calculated - +[rcracki_mt ChangeLog] + +0.6.5.1 (25 Oct 2010, 15:50:10): +* rti2 fixes courtesy of PowerBlade + +0.6.5 (24 Oct 2010, 18:21:25): +* code changes to allow building via mingw and avoid VC++ +* linux thread priority set to nice value of 2 +* rti2 support +* replaced clock_t usage with gettimeofday +* add pre-calculation timing per feature request #3025688 from sourceforge +* fix bug #3050821 from sourceforge - missing break for non x86/x86_64 arch +* improve hash performance by moving off openssl to the local faster methods +* sha1 local implementation was *slower* than openssl for x86/x86_64 + +0.6.4 (05 Jul 2010, 03:12): +* add -m to allow users to limit memory usage - courtesy of uroskn +* fix memory code that made incorrect assumptions about the MemoryPool +* fix linux memory code - using only info.freeram is incorrect +* cleanup of the nested if/elif/else stuctures +* annotate x86 specific sections of code +* licensing review and GPLv2 compliance +* cleanup of unused items +* restructure Makefile +* cleanup memory leaks + +0.6.3 (21 Oct 2009, 21:05): +* Fixed x86_64 linux compilation +* Fixed x86_64 linux segmentation fault +* Fixed 64bit support in md4 code +* Added support for: FreeBSD, NetBSD, OpenBSD, and MacOSX + +0.6.2 (2 Jul 2009, 13:37): +* Fixed linux support (tty stuff and now actually compiles) +* Fixed precalculation code + +0.6.1 (14 May 2009, 22:12): +* bug fixed where the list of rainbow tables is doubled when you resume a session and you have default RT locations in your ini + +0.6 (14 May 2009, 20:47): +* Finding .rti files recursively +* Fixed memory allocation bugs (also trying to save appropriate amount of memory for chainwalksets... these can become really large with the new tables) +* Real pause/resume function, you can resume a session with -r +* Session support, use -s session_name. Combine this with -r to resume a session other then the default +* Ini file support, store some default values such as rainbow table directories. +* Tab separated results (stdout) +* Support pause during cracking and 'skip' during unicode correction for Linux +* A readme / 'manual' ! + +0.5 (16 Apr 2009, 22:47): +* Support for the old non-indexed .rt format, it should work with both type of tables in one run... I didn't test this feature thoroughly +* Using some other pieces of code for algorithms +* Support for .lst files from Cain as input (patch from James Dickson) - use for example -c LMNT.lst +* Fixed some bugs +* Dunno anymore, left this version lying around for too long... + +0.4 (oops, a second 0.4) (13 Dec 2008, 18:20): +* Improved file reading performance + +0.4 (27 Nov 2008, 00:09): +* Source included +* Memory usage down to about 50% (tnx sc00bz for pointing out the inefficiency, tnx jci for helping with the code) +* Works under Linux! (using pthreads now instead of Windows threads) +* Speed up: implemented MD4 reference implementation, not using OpenSSL for NTLM anymore (tnx Bitweasil for supplying 98% of the code) +* Speed up: using OpenSSL a lot faster (tnx jci for pointing that out) +* Probably some more small things i forgot + +0.3 (16 Nov 2008, 01:01): +* Improved command line argument parsing (order no longer matters) +* Option to write (temporary) output to a file, use -o pick_a_nice_filename.txt +* Option to pause, press 'P' to pause/unpause (Windows only) +* For pwdump searches: unicode correction is done when case correction fails + +0.2 (28 Oct 2008, 01:42): +* False alarm checking now also multi threaded +* Search one level of subdirectories for rainbow table files + +0.1 (27 Oct 2008, 00:14): +* Initial multithreaded version, using Windows threads. +* Using multiple threads for the pre-calculation part. +* Added a simple 'progress' message, so you can see how many hashes are being pre-calculated + diff --git a/Client Applications/rcracki_mt/CrackEngine.cpp b/Client Applications/rcracki_mt/CrackEngine.cpp index 1e00fce..7640a63 100644 --- a/Client Applications/rcracki_mt/CrackEngine.cpp +++ b/Client Applications/rcracki_mt/CrackEngine.cpp @@ -1,1437 +1,1437 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * 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 . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "CrackEngine.h" -#include "RTI2Reader.h" - -#ifndef _WIN32 - #include -#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 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 threadPool; - vector 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, ¶m); - #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 vHash; - //vector vIndices; - //vector 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 threadPool; - vector 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, ¶m); - #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 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 = (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, nDataToRead = 0; - gettimeofday( &tv, NULL ); - if ( doRti2Format ) - { - nDataToRead = nAllocatedSize / 16; - nDataRead = nDataToRead; - pReader->ReadChains(nDataRead, 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; - - // 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; - - // finished the current table - if( doRti2Format && nDataToRead > (nDataRead / 8) ) - { - delete pReader; - 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 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; -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * 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 . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "CrackEngine.h" +#include "RTI2Reader.h" + +#ifndef _WIN32 + #include +#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 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 threadPool; + vector 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, ¶m); + #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 vHash; + //vector vIndices; + //vector 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 threadPool; + vector 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, ¶m); + #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 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 = (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, nDataToRead = 0; + gettimeofday( &tv, NULL ); + if ( doRti2Format ) + { + nDataToRead = nAllocatedSize / 16; + nDataRead = nDataToRead; + pReader->ReadChains(nDataRead, 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; + + // 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; + + // finished the current table + if( doRti2Format && nDataToRead > (nDataRead / 8) ) + { + delete pReader; + 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 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; +} diff --git a/Client Applications/rcracki_mt/CrackEngine.h b/Client Applications/rcracki_mt/CrackEngine.h index a5bc6a6..7fdf459 100644 --- a/Client Applications/rcracki_mt/CrackEngine.h +++ b/Client Applications/rcracki_mt/CrackEngine.h @@ -1,98 +1,98 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * 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 . - */ - -#ifndef _CRACKENGINE_H -#define _CRACKENGINE_H - -#include "Public.h" -#include "HashSet.h" -#include "ChainWalkContext.h" -#include "MemoryPool.h" -#include "ChainWalkSet.h" -#include "rcrackiThread.h" -#ifdef _WIN32 -#include -#include -#endif -#include - -class CCrackEngine -{ -public: - CCrackEngine(); - virtual ~CCrackEngine(); - -private: - CChainWalkSet m_cws; - int maxThreads; - uint64 maxMem; - bool writeOutput; - bool resumeSession; - string outputFile; - string sSessionPathName; - string sProgressPathName; - string sPrecalcPathName; - //string sPrecalcIndexPathName; - bool debug; - bool keepPrecalcFiles; - - // Statistics - float m_fTotalDiskAccessTime; - float m_fTotalCryptanalysisTime; - float m_fTotalPrecalculationTime; - int m_nTotalChainWalkStep; - int m_nTotalFalseAlarm; - int m_nTotalChainWalkStepDueToFalseAlarm; - FILE *m_fChains; - -private: - void ResetStatistics(); - RainbowChain *BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart); - int BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex); - void GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain, - int nRainbowChainCount, - int nChainIndex, - int& nChainIndexFrom, - int& nChainIndexTo); - void SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart); - void SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs); - //bool CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs); - //bool CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs); - -public: - void SearchRainbowTable(string sPathName, CHashSet& hs); - void Run(vector vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug); - float GetStatTotalDiskAccessTime(); - float GetStatTotalCryptanalysisTime(); - float GetStatTotalPrecalculationTime(); - int GetStatTotalChainWalkStep(); - int GetStatTotalFalseAlarm(); - int GetStatTotalChainWalkStepDueToFalseAlarm(); - void setOutputFile(string sPathName); - void setSession(string sSessionPathName, string sProgressPathName, string sPrecalcPathName, bool keepPrecalc); -}; - -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * 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 . + */ + +#ifndef _CRACKENGINE_H +#define _CRACKENGINE_H + +#include "Public.h" +#include "HashSet.h" +#include "ChainWalkContext.h" +#include "MemoryPool.h" +#include "ChainWalkSet.h" +#include "rcrackiThread.h" +#ifdef _WIN32 +#include +#include +#endif +#include + +class CCrackEngine +{ +public: + CCrackEngine(); + virtual ~CCrackEngine(); + +private: + CChainWalkSet m_cws; + int maxThreads; + uint64 maxMem; + bool writeOutput; + bool resumeSession; + string outputFile; + string sSessionPathName; + string sProgressPathName; + string sPrecalcPathName; + //string sPrecalcIndexPathName; + bool debug; + bool keepPrecalcFiles; + + // Statistics + float m_fTotalDiskAccessTime; + float m_fTotalCryptanalysisTime; + float m_fTotalPrecalculationTime; + int m_nTotalChainWalkStep; + int m_nTotalFalseAlarm; + int m_nTotalChainWalkStepDueToFalseAlarm; + FILE *m_fChains; + +private: + void ResetStatistics(); + RainbowChain *BinarySearch(RainbowChain *pChain, int nChainCountRead, uint64 nIndex, IndexChain *pIndex, int nIndexSize, int nIndexStart); + int BinarySearchOld(RainbowChainO* pChain, int nRainbowChainCount, uint64 nIndex); + void GetChainIndexRangeWithSameEndpoint(RainbowChainO* pChain, + int nRainbowChainCount, + int nChainIndex, + int& nChainIndexFrom, + int& nChainIndexTo); + void SearchTableChunk(RainbowChain* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs, IndexChain *pIndex, int nIndexSize, int nChainStart); + void SearchTableChunkOld(RainbowChainO* pChain, int nRainbowChainLen, int nRainbowChainCount, CHashSet& hs); + //bool CheckAlarm(RainbowChain* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs); + //bool CheckAlarmOld(RainbowChainO* pChain, int nGuessedPos, unsigned char* pHash, CHashSet& hs); + +public: + void SearchRainbowTable(string sPathName, CHashSet& hs); + void Run(vector vPathName, CHashSet& hs, int i_maxThreads, uint64 i_maxMem, bool resume, bool bDebug); + float GetStatTotalDiskAccessTime(); + float GetStatTotalCryptanalysisTime(); + float GetStatTotalPrecalculationTime(); + int GetStatTotalChainWalkStep(); + int GetStatTotalFalseAlarm(); + int GetStatTotalChainWalkStepDueToFalseAlarm(); + void setOutputFile(string sPathName); + void setSession(string sSessionPathName, string sProgressPathName, string sPrecalcPathName, bool keepPrecalc); +}; + +#endif diff --git a/Client Applications/rcracki_mt/HashAlgorithm.cpp b/Client Applications/rcracki_mt/HashAlgorithm.cpp index bf04682..db22aeb 100644 --- a/Client Applications/rcracki_mt/HashAlgorithm.cpp +++ b/Client Applications/rcracki_mt/HashAlgorithm.cpp @@ -1,428 +1,428 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - * - * Changes: not using OpenSSL routines the slow way anymore, as suggested by jci. - */ - -#include "HashAlgorithm.h" - -#include "Public.h" - -#include -//#include -#include -#include -//#include -#include "fast_md5.h" -#include "md4.h" -//#include "sha1.h" -#if defined(_WIN32) && !defined(__GNUC__) - #pragma comment(lib, "libeay32.lib") -#endif - -#ifdef __NetBSD__ - #include -#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 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 +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + * + * Changes: not using OpenSSL routines the slow way anymore, as suggested by jci. + */ + +#include "HashAlgorithm.h" + +#include "Public.h" + +#include +//#include +#include +#include +//#include +#include "fast_md5.h" +#include "md4.h" +//#include "sha1.h" +#if defined(_WIN32) && !defined(__GNUC__) + #pragma comment(lib, "libeay32.lib") +#endif + +#ifdef __NetBSD__ + #include +#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 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 diff --git a/Client Applications/rcracki_mt/HashAlgorithm.h b/Client Applications/rcracki_mt/HashAlgorithm.h index a6b77b5..401784f 100644 --- a/Client Applications/rcracki_mt/HashAlgorithm.h +++ b/Client Applications/rcracki_mt/HashAlgorithm.h @@ -1,64 +1,64 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef _HASHALGORITHM_H -#define _HASHALGORITHM_H - -void HashLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashNTLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -//void HashMD2(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashMD4(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashDoubleMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -//void HashRIPEMD160(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashMSCACHE(unsigned char *pPlain, int nPlainLen, unsigned char* pHash); - -//**************************************************************************** -// MySQL Password Hashing -//**************************************************************************** - -void HashMySQL323(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashMySQLSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); - -//**************************************************************************** -// Cisco PIX Password Hashing -//**************************************************************************** - -void HashPIX(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); - -//**************************************************************************** -// (HALF) LM CHALL hashing -void HashLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashHALFLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); - -// From mao -void HashNTLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); -void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); - -#if !defined(_WIN32) || defined(__GNUC__) -char *strupr(char *s1); -#endif -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef _HASHALGORITHM_H +#define _HASHALGORITHM_H + +void HashLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashNTLM(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +//void HashMD2(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashMD4(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashDoubleMD5(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +//void HashRIPEMD160(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashMSCACHE(unsigned char *pPlain, int nPlainLen, unsigned char* pHash); + +//**************************************************************************** +// MySQL Password Hashing +//**************************************************************************** + +void HashMySQL323(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashMySQLSHA1(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); + +//**************************************************************************** +// Cisco PIX Password Hashing +//**************************************************************************** + +void HashPIX(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); + +//**************************************************************************** +// (HALF) LM CHALL hashing +void HashLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashHALFLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); + +// From mao +void HashNTLMCHALL(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); +void HashORACLE(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); + +#if !defined(_WIN32) || defined(__GNUC__) +char *strupr(char *s1); +#endif +#endif diff --git a/Client Applications/rcracki_mt/HashRoutine.cpp b/Client Applications/rcracki_mt/HashRoutine.cpp index c85193f..595f13d 100644 --- a/Client Applications/rcracki_mt/HashRoutine.cpp +++ b/Client Applications/rcracki_mt/HashRoutine.cpp @@ -1,96 +1,96 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "HashRoutine.h" -#include "HashAlgorithm.h" - -////////////////////////////////////////////////////////////////////// - -CHashRoutine::CHashRoutine() -{ - // Notice: MIN_HASH_LEN <= nHashLen <= MAX_HASH_LEN - - - AddHashRoutine("lm", HashLM, 8); - AddHashRoutine("ntlm", HashNTLM, 16); -// AddHashRoutine("md2", HashMD2, 16); - AddHashRoutine("md4", HashMD4, 16); - AddHashRoutine("md5", HashMD5, 16); - AddHashRoutine("doublemd5", HashDoubleMD5, 16); - AddHashRoutine("sha1", HashSHA1, 20); -// AddHashRoutine("ripemd160", HashRIPEMD160, 20); - AddHashRoutine("mysql323", HashMySQL323, 8); - AddHashRoutine("mysqlsha1", HashMySQLSHA1, 20); - AddHashRoutine("ciscopix", HashPIX, 16); - AddHashRoutine("mscache", HashMSCACHE, 16); - AddHashRoutine("halflmchall", HashHALFLMCHALL, 8); - - // Added from mao - AddHashRoutine("lmchall", HashLMCHALL, 24); - AddHashRoutine("ntlmchall", HashNTLMCHALL, 24); - AddHashRoutine("oracle", HashORACLE, 8); -} - -CHashRoutine::~CHashRoutine() -{ -} - -void CHashRoutine::AddHashRoutine(string sHashRoutineName, HASHROUTINE pHashRoutine, int nHashLen) -{ - vHashRoutineName.push_back(sHashRoutineName); - vHashRoutine.push_back(pHashRoutine); - vHashLen.push_back(nHashLen); -} - -string CHashRoutine::GetAllHashRoutineName() -{ - string sRet; - UINT4 i; - for (i = 0; i < vHashRoutineName.size(); i++) - sRet += vHashRoutineName[i] + " "; - - return sRet; -} - -void CHashRoutine::GetHashRoutine(string sHashRoutineName, HASHROUTINE& pHashRoutine, int& nHashLen) -{ - UINT4 i; - for (i = 0; i < vHashRoutineName.size(); i++) - { - if (sHashRoutineName == vHashRoutineName[i]) - { - pHashRoutine = vHashRoutine[i]; - nHashLen = vHashLen[i]; - return; - } - } - - pHashRoutine = NULL; - nHashLen = 0; -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "HashRoutine.h" +#include "HashAlgorithm.h" + +////////////////////////////////////////////////////////////////////// + +CHashRoutine::CHashRoutine() +{ + // Notice: MIN_HASH_LEN <= nHashLen <= MAX_HASH_LEN + + + AddHashRoutine("lm", HashLM, 8); + AddHashRoutine("ntlm", HashNTLM, 16); +// AddHashRoutine("md2", HashMD2, 16); + AddHashRoutine("md4", HashMD4, 16); + AddHashRoutine("md5", HashMD5, 16); + AddHashRoutine("doublemd5", HashDoubleMD5, 16); + AddHashRoutine("sha1", HashSHA1, 20); +// AddHashRoutine("ripemd160", HashRIPEMD160, 20); + AddHashRoutine("mysql323", HashMySQL323, 8); + AddHashRoutine("mysqlsha1", HashMySQLSHA1, 20); + AddHashRoutine("ciscopix", HashPIX, 16); + AddHashRoutine("mscache", HashMSCACHE, 16); + AddHashRoutine("halflmchall", HashHALFLMCHALL, 8); + + // Added from mao + AddHashRoutine("lmchall", HashLMCHALL, 24); + AddHashRoutine("ntlmchall", HashNTLMCHALL, 24); + AddHashRoutine("oracle", HashORACLE, 8); +} + +CHashRoutine::~CHashRoutine() +{ +} + +void CHashRoutine::AddHashRoutine(string sHashRoutineName, HASHROUTINE pHashRoutine, int nHashLen) +{ + vHashRoutineName.push_back(sHashRoutineName); + vHashRoutine.push_back(pHashRoutine); + vHashLen.push_back(nHashLen); +} + +string CHashRoutine::GetAllHashRoutineName() +{ + string sRet; + UINT4 i; + for (i = 0; i < vHashRoutineName.size(); i++) + sRet += vHashRoutineName[i] + " "; + + return sRet; +} + +void CHashRoutine::GetHashRoutine(string sHashRoutineName, HASHROUTINE& pHashRoutine, int& nHashLen) +{ + UINT4 i; + for (i = 0; i < vHashRoutineName.size(); i++) + { + if (sHashRoutineName == vHashRoutineName[i]) + { + pHashRoutine = vHashRoutine[i]; + nHashLen = vHashLen[i]; + return; + } + } + + pHashRoutine = NULL; + nHashLen = 0; +} diff --git a/Client Applications/rcracki_mt/HashRoutine.h b/Client Applications/rcracki_mt/HashRoutine.h index 2d53125..eaa10ce 100644 --- a/Client Applications/rcracki_mt/HashRoutine.h +++ b/Client Applications/rcracki_mt/HashRoutine.h @@ -1,55 +1,55 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef _HASHROUTINE_H -#define _HASHROUTINE_H - -#include -#include - -#include "global.h" - -using namespace std; - -typedef void (*HASHROUTINE)(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); - -class CHashRoutine -{ -public: - CHashRoutine(); - virtual ~CHashRoutine(); - -private: - vector vHashRoutineName; - vector vHashRoutine; - vector vHashLen; - void AddHashRoutine(string sHashRoutineName, HASHROUTINE pHashRoutine, int nHashLen); - -public: - string GetAllHashRoutineName(); - void GetHashRoutine(string sHashRoutineName, HASHROUTINE& pHashRoutine, int& nHashLen); -}; - -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef _HASHROUTINE_H +#define _HASHROUTINE_H + +#include +#include + +#include "global.h" + +using namespace std; + +typedef void (*HASHROUTINE)(unsigned char* pPlain, int nPlainLen, unsigned char* pHash); + +class CHashRoutine +{ +public: + CHashRoutine(); + virtual ~CHashRoutine(); + +private: + vector vHashRoutineName; + vector vHashRoutine; + vector vHashLen; + void AddHashRoutine(string sHashRoutineName, HASHROUTINE pHashRoutine, int nHashLen); + +public: + string GetAllHashRoutineName(); + void GetHashRoutine(string sHashRoutineName, HASHROUTINE& pHashRoutine, int& nHashLen); +}; + +#endif diff --git a/Client Applications/rcracki_mt/HashSet.cpp b/Client Applications/rcracki_mt/HashSet.cpp index 683af0b..a625475 100644 --- a/Client Applications/rcracki_mt/HashSet.cpp +++ b/Client Applications/rcracki_mt/HashSet.cpp @@ -1,183 +1,183 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "HashSet.h" - -CHashSet::CHashSet() -{ -} - -CHashSet::~CHashSet() -{ -} - -void CHashSet::AddHash(string sHash) -{ - if (sHash == "aad3b435b51404ee") - return; - - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (m_vHash[i] == sHash) - return; - } - - //printf("debug: adding hash %s\n", sHash.c_str()); - - m_vHash.push_back(sHash); - m_vFound.push_back(false); - m_vPlain.push_back(""); - m_vBinary.push_back(""); -} - -string CHashSet::GetHashInfo(int i) -{ - string found; - if (m_vFound[i]) - found = "1"; - else - found = "0"; - - string buffer = m_vHash[i] + ":" + found + ":" + m_vPlain[i] + ":" + m_vBinary[i]; - - return buffer; -} - -bool CHashSet::AnyhashLeft() -{ - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (!m_vFound[i]) - return true; - } - - return false; -} - -bool CHashSet::AnyHashLeftWithLen(int nLen) -{ - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (!m_vFound[i]) - if (m_vHash[i].size() == (unsigned long)nLen * 2) - return true; - } - - return false; -} - -void CHashSet::GetLeftHashWithLen(vector& vHash, int nLen) -{ - vHash.clear(); - - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (!m_vFound[i]) - if (m_vHash[i].size() == (unsigned long)nLen * 2) - vHash.push_back(m_vHash[i]); - } -} - -void CHashSet::AddHashInfo(string sHash, bool found, string sPlain, string sBinary) -{ - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (m_vHash[i] == sHash) - return; - } - - m_vHash.push_back(sHash); - m_vFound.push_back(found); - m_vPlain.push_back(sPlain); - m_vBinary.push_back(sBinary); -} - -void CHashSet::SetPlain(string sHash, string sPlain, string sBinary) -{ - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (m_vHash[i] == sHash) - { - m_vFound[i] = true; - m_vPlain[i] = sPlain; - m_vBinary[i] = sBinary; - return; - } - } -} - -bool CHashSet::GetPlain(string sHash, string& sPlain, string& sBinary) -{ - if (sHash == "aad3b435b51404ee") - { - sPlain = ""; - sBinary = ""; - return true; - } - - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (m_vHash[i] == sHash) - { - if (m_vFound[i]) - { - sPlain = m_vPlain[i]; - sBinary = m_vBinary[i]; - return true; - } - } - } - - return false; -} - -int CHashSet::GetStatHashFound() -{ - int nHashFound = 0; - UINT4 i; - for (i = 0; i < m_vHash.size(); i++) - { - if (m_vFound[i]) - nHashFound++; - } - - return nHashFound; -} - -int CHashSet::GetStatHashTotal() -{ - return (int) m_vHash.size(); -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "HashSet.h" + +CHashSet::CHashSet() +{ +} + +CHashSet::~CHashSet() +{ +} + +void CHashSet::AddHash(string sHash) +{ + if (sHash == "aad3b435b51404ee") + return; + + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (m_vHash[i] == sHash) + return; + } + + //printf("debug: adding hash %s\n", sHash.c_str()); + + m_vHash.push_back(sHash); + m_vFound.push_back(false); + m_vPlain.push_back(""); + m_vBinary.push_back(""); +} + +string CHashSet::GetHashInfo(int i) +{ + string found; + if (m_vFound[i]) + found = "1"; + else + found = "0"; + + string buffer = m_vHash[i] + ":" + found + ":" + m_vPlain[i] + ":" + m_vBinary[i]; + + return buffer; +} + +bool CHashSet::AnyhashLeft() +{ + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (!m_vFound[i]) + return true; + } + + return false; +} + +bool CHashSet::AnyHashLeftWithLen(int nLen) +{ + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (!m_vFound[i]) + if (m_vHash[i].size() == (unsigned long)nLen * 2) + return true; + } + + return false; +} + +void CHashSet::GetLeftHashWithLen(vector& vHash, int nLen) +{ + vHash.clear(); + + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (!m_vFound[i]) + if (m_vHash[i].size() == (unsigned long)nLen * 2) + vHash.push_back(m_vHash[i]); + } +} + +void CHashSet::AddHashInfo(string sHash, bool found, string sPlain, string sBinary) +{ + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (m_vHash[i] == sHash) + return; + } + + m_vHash.push_back(sHash); + m_vFound.push_back(found); + m_vPlain.push_back(sPlain); + m_vBinary.push_back(sBinary); +} + +void CHashSet::SetPlain(string sHash, string sPlain, string sBinary) +{ + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (m_vHash[i] == sHash) + { + m_vFound[i] = true; + m_vPlain[i] = sPlain; + m_vBinary[i] = sBinary; + return; + } + } +} + +bool CHashSet::GetPlain(string sHash, string& sPlain, string& sBinary) +{ + if (sHash == "aad3b435b51404ee") + { + sPlain = ""; + sBinary = ""; + return true; + } + + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (m_vHash[i] == sHash) + { + if (m_vFound[i]) + { + sPlain = m_vPlain[i]; + sBinary = m_vBinary[i]; + return true; + } + } + } + + return false; +} + +int CHashSet::GetStatHashFound() +{ + int nHashFound = 0; + UINT4 i; + for (i = 0; i < m_vHash.size(); i++) + { + if (m_vFound[i]) + nHashFound++; + } + + return nHashFound; +} + +int CHashSet::GetStatHashTotal() +{ + return (int) m_vHash.size(); +} diff --git a/Client Applications/rcracki_mt/HashSet.h b/Client Applications/rcracki_mt/HashSet.h index d3f410a..f7f37b2 100644 --- a/Client Applications/rcracki_mt/HashSet.h +++ b/Client Applications/rcracki_mt/HashSet.h @@ -1,59 +1,59 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef _HASHSET_H -#define _HASHSET_H - -#include "Public.h" - -class CHashSet -{ -public: - CHashSet(); - virtual ~CHashSet(); - -private: - vector m_vHash; - vector m_vFound; - vector m_vPlain; - vector m_vBinary; - -public: - void AddHash(string sHash); // lowercase, len % 2 == 0, MIN_HASH_LEN * 2 <= len <= MAX_HASH_LEN * 2 - bool AnyhashLeft(); - bool AnyHashLeftWithLen(int nLen); - void GetLeftHashWithLen(vector& vHash, int nLen); - - void SetPlain(string sHash, string sPlain, string sBinary); - bool GetPlain(string sHash, string& sPlain, string& sBinary); - - int GetStatHashFound(); - int GetStatHashTotal(); - - string GetHashInfo(int i); - void AddHashInfo(string sHash, bool found, string sPlain, string sBinary); -}; - -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef _HASHSET_H +#define _HASHSET_H + +#include "Public.h" + +class CHashSet +{ +public: + CHashSet(); + virtual ~CHashSet(); + +private: + vector m_vHash; + vector m_vFound; + vector m_vPlain; + vector m_vBinary; + +public: + void AddHash(string sHash); // lowercase, len % 2 == 0, MIN_HASH_LEN * 2 <= len <= MAX_HASH_LEN * 2 + bool AnyhashLeft(); + bool AnyHashLeftWithLen(int nLen); + void GetLeftHashWithLen(vector& vHash, int nLen); + + void SetPlain(string sHash, string sPlain, string sBinary); + bool GetPlain(string sHash, string& sPlain, string& sBinary); + + int GetStatHashFound(); + int GetStatHashTotal(); + + string GetHashInfo(int i); + void AddHashInfo(string sHash, bool found, string sPlain, string sBinary); +}; + +#endif diff --git a/Client Applications/rcracki_mt/MemoryPool.cpp b/Client Applications/rcracki_mt/MemoryPool.cpp index 3673446..10e235c 100644 --- a/Client Applications/rcracki_mt/MemoryPool.cpp +++ b/Client Applications/rcracki_mt/MemoryPool.cpp @@ -1,110 +1,110 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * 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 . - */ - -#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; - } -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * 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 . + */ + +#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; + } +} diff --git a/Client Applications/rcracki_mt/MemoryPool.h b/Client Applications/rcracki_mt/MemoryPool.h index 62ae527..9304748 100644 --- a/Client Applications/rcracki_mt/MemoryPool.h +++ b/Client Applications/rcracki_mt/MemoryPool.h @@ -1,49 +1,49 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * 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 . - */ - -#ifndef _MEMORYPOOL_H -#define _MEMORYPOOL_H - -#include "global.h" - -class CMemoryPool -{ -public: - CMemoryPool(unsigned int bytesSaved, bool bDebug, uint64 maxMem); - virtual ~CMemoryPool(); - -private: - bool debug; - unsigned char* m_pMem; - uint64 m_nMemSize; - - uint64 m_nMemMax; - -public: - unsigned char* Allocate(unsigned int nFileLen, uint64& nAllocatedSize); -}; - -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * 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 . + */ + +#ifndef _MEMORYPOOL_H +#define _MEMORYPOOL_H + +#include "global.h" + +class CMemoryPool +{ +public: + CMemoryPool(unsigned int bytesSaved, bool bDebug, uint64 maxMem); + virtual ~CMemoryPool(); + +private: + bool debug; + unsigned char* m_pMem; + uint64 m_nMemSize; + + uint64 m_nMemMax; + +public: + unsigned char* Allocate(unsigned int nFileLen, uint64& nAllocatedSize); +}; + +#endif diff --git a/Client Applications/rcracki_mt/Public.cpp b/Client Applications/rcracki_mt/Public.cpp index 41a9515..5324924 100644 --- a/Client Applications/rcracki_mt/Public.cpp +++ b/Client Applications/rcracki_mt/Public.cpp @@ -1,437 +1,437 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "Public.h" - -#ifdef _WIN32 - #include -#endif - -#if defined(_WIN32) && !defined(__GNUC__) - #include - #include - - #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 - - #if defined(BSD) - #include - #elif defined(__linux__) - #include - #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& 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 vParts; - SeperateString(sChar, ",", vParts); - for(UINT4 i = 0; i < vParts.size(); i++) - { - tCharset stCharset; - vector vParts2; - SeperateString(vParts[i], "#", vParts2); - stCharset.sName = vParts2[0]; - vector 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& 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& 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 \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 \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 +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "Public.h" + +#ifdef _WIN32 + #include +#endif + +#if defined(_WIN32) && !defined(__GNUC__) + #include + #include + + #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 + + #if defined(BSD) + #include + #elif defined(__linux__) + #include + #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& 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 vParts; + SeperateString(sChar, ",", vParts); + for(UINT4 i = 0; i < vParts.size(); i++) + { + tCharset stCharset; + vector vParts2; + SeperateString(vParts[i], "#", vParts2); + stCharset.sName = vParts2[0]; + vector 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& 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& 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 \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 \n"); + printf("http://www.antsight.com/zsl/rainbowcrack/\n\n"); +} + +// XXX nmap is GPL2, will check newer releases regarding license +// Code comes from nmap, used for the linux implementation of kbhit() +#ifndef _WIN32 + +static int tty_fd = 0; +struct termios saved_ti; + +int tty_getchar() +{ + int c, numChars; + + if (tty_fd && tcgetpgrp(tty_fd) == getpid()) { + c = 0; + numChars = read(tty_fd, &c, 1); + if (numChars > 0) return c; + } + + return -1; +} + +void tty_done() +{ + if (!tty_fd) return; + + tcsetattr(tty_fd, TCSANOW, &saved_ti); + + close(tty_fd); + tty_fd = 0; +} + +void tty_init() +{ + struct termios ti; + + if (tty_fd) + return; + + if ((tty_fd = open("/dev/tty", O_RDONLY | O_NONBLOCK)) < 0) return; + + tcgetattr(tty_fd, &ti); + saved_ti = ti; + ti.c_lflag &= ~(ICANON | ECHO); + ti.c_cc[VMIN] = 1; + ti.c_cc[VTIME] = 0; + tcsetattr(tty_fd, TCSANOW, &ti); + + atexit(tty_done); +} + +void tty_flush(void) +{ + tcflush(tty_fd, TCIFLUSH); +} +// end nmap code +#endif diff --git a/Client Applications/rcracki_mt/Public.h b/Client Applications/rcracki_mt/Public.h index 27d4dcd..89bbc80 100644 --- a/Client Applications/rcracki_mt/Public.h +++ b/Client Applications/rcracki_mt/Public.h @@ -1,138 +1,138 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef _PUBLIC_H -#define _PUBLIC_H - -#include -#include -#include - -#include -#include -#include - -#include "global.h" - -using namespace std; - - -struct RainbowChainO -{ - uint64 nIndexS; - uint64 nIndexE; -}; -//struct RainbowChain -//{ -// //uint64 nChain; -// uint64 nIndexS; -// int nIndexE; -// int nCheckPoint; -//}; -union RainbowChain -{ - //uint64 nChain; - uint64 nIndexS; - struct - { - unsigned short foo[3]; - unsigned short nIndexE; - }; - //int nCheckPoint; -}; -//struct RainbowChain -//{ -// uint64 nIndexS : 48; -// unsigned short nIndexE : 16; -//}; -//struct IndexChain -//{ -// uint64 nPrefix; -// int nFirstChain; -// int nChainCount; -// //unsigned short nChainCount; //(maybe union with nPrefix, 1 byte spoiled) -//}; -#pragma pack(1) -union IndexChain -{ - uint64 nPrefix; //5 - struct - { - unsigned char foo[5]; - int nFirstChain; //4 - unsigned short nChainCount; //2 - }; - //unsigned short nChainCount; (maybe union with nPrefix, 1 byte spoiled, no pack(1) needed) -}; -#pragma pack() -typedef struct -{ - string sName; - int nPlainLenMin; - int nPlainLenMax; -} tCharset; - -#define MAX_PLAIN_LEN 256 -#define MIN_HASH_LEN 8 -#define MAX_HASH_LEN 256 -#define MAX_SALT_LEN 256 - -// XXX nmap is GPL2, will check newer releases regarding license -// Code comes from nmap, used for the linux implementation of kbhit() -#ifndef _WIN32 -#include -#include -#include - -int tty_getchar(); -void tty_done(); -void tty_init(); -void tty_flush(void); -// end nmap code -#endif - -#if defined(_WIN32) && !defined(__GNUC__) - int gettimeofday( struct timeval *tv, struct timezone *tz ); -#endif - -#if !defined(_WIN32) || defined(__GNUC__) - #include -#endif - -timeval sub_timeofday( timeval tv2, timeval tv ); - -unsigned int GetFileLen(FILE* file); -string TrimString(string s); -bool ReadLinesFromFile(string sPathName, vector& vLine); -bool SeperateString(string s, string sSeperator, vector& vPart); -string uint64tostr(uint64 n); -string uint64tohexstr(uint64 n); -string HexToStr(const unsigned char* pData, int nLen); -uint64 GetAvailPhysMemorySize(); -string GetApplicationPath(); -void ParseHash(string sHash, unsigned char* pHash, int& nHashLen); -bool GetHybridCharsets(string sCharset, vector& vCharset); -void Logo(); -bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary); - -#endif +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef _PUBLIC_H +#define _PUBLIC_H + +#include +#include +#include + +#include +#include +#include + +#include "global.h" + +using namespace std; + + +struct RainbowChainO +{ + uint64 nIndexS; + uint64 nIndexE; +}; +//struct RainbowChain +//{ +// //uint64 nChain; +// uint64 nIndexS; +// int nIndexE; +// int nCheckPoint; +//}; +union RainbowChain +{ + //uint64 nChain; + uint64 nIndexS; + struct + { + unsigned short foo[3]; + unsigned short nIndexE; + }; + //int nCheckPoint; +}; +//struct RainbowChain +//{ +// uint64 nIndexS : 48; +// unsigned short nIndexE : 16; +//}; +//struct IndexChain +//{ +// uint64 nPrefix; +// int nFirstChain; +// int nChainCount; +// //unsigned short nChainCount; //(maybe union with nPrefix, 1 byte spoiled) +//}; +#pragma pack(1) +union IndexChain +{ + uint64 nPrefix; //5 + struct + { + unsigned char foo[5]; + int nFirstChain; //4 + unsigned short nChainCount; //2 + }; + //unsigned short nChainCount; (maybe union with nPrefix, 1 byte spoiled, no pack(1) needed) +}; +#pragma pack() +typedef struct +{ + string sName; + int nPlainLenMin; + int nPlainLenMax; +} tCharset; + +#define MAX_PLAIN_LEN 256 +#define MIN_HASH_LEN 8 +#define MAX_HASH_LEN 256 +#define MAX_SALT_LEN 256 + +// XXX nmap is GPL2, will check newer releases regarding license +// Code comes from nmap, used for the linux implementation of kbhit() +#ifndef _WIN32 +#include +#include +#include + +int tty_getchar(); +void tty_done(); +void tty_init(); +void tty_flush(void); +// end nmap code +#endif + +#if defined(_WIN32) && !defined(__GNUC__) + int gettimeofday( struct timeval *tv, struct timezone *tz ); +#endif + +#if !defined(_WIN32) || defined(__GNUC__) + #include +#endif + +timeval sub_timeofday( timeval tv2, timeval tv ); + +unsigned int GetFileLen(FILE* file); +string TrimString(string s); +bool ReadLinesFromFile(string sPathName, vector& vLine); +bool SeperateString(string s, string sSeperator, vector& vPart); +string uint64tostr(uint64 n); +string uint64tohexstr(uint64 n); +string HexToStr(const unsigned char* pData, int nLen); +uint64 GetAvailPhysMemorySize(); +string GetApplicationPath(); +void ParseHash(string sHash, unsigned char* pHash, int& nHashLen); +bool GetHybridCharsets(string sCharset, vector& vCharset); +void Logo(); +bool writeResultLineToFile(string sOutputFile, string sHash, string sPlain, string sBinary); + +#endif diff --git a/Client Applications/rcracki_mt/README.txt b/Client Applications/rcracki_mt/README.txt index 3719dd6..875cf56 100644 --- a/Client Applications/rcracki_mt/README.txt +++ b/Client Applications/rcracki_mt/README.txt @@ -1,171 +1,171 @@ -[rcracki_mt README] - -USAGE -================ -example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 4 -o save.txt C:\md5 - -Start rcracki_mt without any arguments to view usage information in short. This README describes the various -options in more detail. Many options can be set to a default value by editing rcracki_mt.ini. Command line -arguments get priority over settings in the ini file. - -INPUT ----------------- -rcracki_mt takes one hash on the command line (using -h) or an input file containing the hashes. rcracki_mt supports -three formats for the input file. Use one of the following options to specify the format followed by the filename: - --l: specify a list of hashes (one hash per line) --f: specify a pwdump file --c: specify a .lst file (format in which Cain stores hashes and results) - -SELECTING RAINBOW TABLES ----------------- -Any command line argument that is not an option will be interpreted as a directory to search for rainbow tables, -multiple directories can be specified. rcracki_mt recursively scans all specified directories for *.rti (indexed) -and *.rt (old/original) files. You can use .rt & .rti files at once, but this hasn't been tested thoroughly. - -You can set default locations to search for rainbow tables in rcracki_mt.ini. You need to use these in combination -with the command line argument -a [algorithm]. See the comments in the ini file for examples. - -SESSIONS & RESUMING ----------------- -Rcracki_mt has session support, which means that it stores its progress. This allows you to interrupt the session -and resume later on. This also allows sessions that stopped because of a crash (application or even system) to -resume. To use this feature, start rcracki_mt with all the options you'd like, then specify a session name with: - --s session_name: specify a session name - -Now during cracking, all your valuable precalculations are stored to disk, as well as progress (which files have -been checked) and cracked hashes. If you decide to interrupt the session (using CTRL+C), you can resume it using -the -r option. For example: - -rcracki_mt -r -s my_personal_hashes - -While resuming rcracki_mt you can/have to specify the less important options again, like number of threads and -showing debug information. Usually you will have these settings set to a default value in the .ini file anyway. -Session are deleted after the run is completed. You can choose to keep the precalculation work on disk, for example -if you want to reuse your session later on. Use the '-k' option to enable this feature. - -Rcracki_mt has a default session which gets overwritten every time you start a new job without specifying a session -name. It might be interesting to always keep precalculation work by enabling this feature in rcracki_mt.ini. But -pay attention, these precalculations can become quite large on disk. Currently there is a maximum of around 500 GB -of storage for these precalculations. You can always decide to manually remove the .precalc and .precalc.index -files from disk. Always remove both at the same time, you will screw up your results if you don't. A possible -'todo' for development is to do some verification before using stored precalculations. - -OPTIONAL ----------------- --t: Number of threads to use (for precalculation and false alarm checking) -Note: In Windows the crack threads run with lower priority. - --o: specify an output file to store found hashes in a colon (:) separated format. - Hashes are saved immediately when found. Especially useful if you have a large list of hashes. - --v: Show more information during cracking, for debugging purposes. Please use this flag if you want to show -output and report a bug. - - -EXTRA FEATURES ----------------- -You can pause a running rcracki_mt by using 'P'. It might not pause right away, it actually pauses after doing -precalculation or false alarm checking for one hash. Resume by pressing 'P' again. This pause option is different -from the session/resume feature, as this just pauses a running job, you don't stop rcracki_mt this way. - -If you are trying to crack a pwdump or Cain (.lst) file, containing both LM and NTLM hashes, rcracki_mt will try -and crack the LM hashes. The result will be an uppercase password, which rcracki_mt will then try to correct with -the right casing, using the NTLM hashes. If this fails it will try and perform Unicode correction, using a built-in -mapping. If you happen to have an LM hash coupled with the wrong NTLM hash, this attempt to perform Unicode -correction might take 'forever'. You can press 'S' to skip this step for the current hash. - - -HISTORY AND AUTHORS -================ -rcracki_mt originally started as a modification of a modification (rcracki) of the original RainbowCrack (rcrack). -These programs are all used to perform a rainbow table attack on password hashes, implementing Philippe Oechslin's -faster time-memory trade-off technique. - -Original rcrack code was written by Zhu Shuanglei . - -Martin Westergaard Jørgensen wrote rcracki (improved) to support the rainbow tables -generated by the distributed project www.freerainbowtables.com. These tables are perfected and indexed, making them -faster and smaller. Rcracki also supported hybrid tables. - -Daniël Niggebrugge further enhanced this version and made it multi threaded, creating rcracki_mt. More -features were added over time, making it less of an unofficial version with every release. - -James Nobis - improved *nix compatibility and 64-bit compatability and -continues work on the project. - - -SUPPORTED HASH ALGORITHMS -================ -Hash types supported by rcracki_mt are: LM, NTLM, MD2, MD4, MD5, DoubleMD5, SHA1, RIPEMD160, MSCACHE, MySQL323, -MySQLSHA1, PIX, LMCHALL, HALFLMCHALL, NTLMCHALL, ORACLE - -Actual indexed&perfected tables that were generated by the Free Rainbow Tables project: LM, MD5, NTL, FASTLM, -HALFLMCHALL, SHA1 - - -SUPPORTED PLATFORMS -================ -Rcracki_mt is released both as win32 binary and as source package. Rcracki_mt should work on any Microsoft Windows system, but is only tested on a 32 bit Windows XP. - -The source should work on Linux distributions. It has been tested on: -32-bit Ubuntu -32-bit Debian GNU/Linux -64-bit Debian GNU/Linux - -The source should also work on other platforms and has been tested on: -32-bit MacOSX - -32-bit FreeBSD -64-bit FreeBSD -32-bit NetBSD -32-bit OpenBSD - you must install and use eg++ from ports -64-bit OpenBSD - -Only compilation has been tested on: -64-bit MacOSX - -Please note that to compile under the BSDs you must use gmake. - -OpenBSD threading is a work in progress. - -'OPTIONAL' TODO -================ -- verification of an endpoint when restoring a chainwalkset from disk. -- read multiple chainwalksets from disk at once to try and speed up this process. -- read next table (part) from disk while doing cryptanalysis - - -LINKS -================ -rcracki_mt @ SourceForge: https://sourceforge.net/projects/rcracki/ -Original rcrack: http://www.antsight.com/zsl/rainbowcrack/ -Free Rainbow Tables: http://www.freerainbowtables.com/ -My personal blog: http://blog.distracted.nl/ -Download free rainbow tables: http://tbhost.eu/ -Download free rainbow tables (mirror): http://freerainbowtables.mirror.garr.it/mirrors/freerainbowtables/ - - -THANKS -================ -the_drag0n Writing part of this README - Patch to support Cain .lst files -Joao Inacio Supplying some faster algorithm implementations - - -FAQ -================ -Q: Why do I get this message all the time? "this table contains hashes with length 8 only" -A: You are probably trying to crack LM hashes. You have to split up the hash in 2 parts of 16 hex characters each. - -Q: rcracki_mt is so slow when I'm cracking 5000 hashes, why is that? -A: Rainbow table attacks are only useful for a certain amount of hashes, mainly because of the precalculations that -are needed for every hash you are cracking. At a certain point it is faster to brute force the same key space then -to try and use rainbow tables. Especially if you use a GPU enabled brute forcer, this limit might be reached very -soon. Play around with these to find you limits. - -Q: How can I speed up rcracki_mt? -A: This depends on quite some factors. If your jobs usually comprise of disk access time, you can try and speed up -your storage. For example by using RAID and/or by using solid state disks. If you are trying to crack many hashes -at the same time, you might be better off with buying a faster CPU. +[rcracki_mt README] + +USAGE +================ +example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 4 -o save.txt C:\md5 + +Start rcracki_mt without any arguments to view usage information in short. This README describes the various +options in more detail. Many options can be set to a default value by editing rcracki_mt.ini. Command line +arguments get priority over settings in the ini file. + +INPUT +---------------- +rcracki_mt takes one hash on the command line (using -h) or an input file containing the hashes. rcracki_mt supports +three formats for the input file. Use one of the following options to specify the format followed by the filename: + +-l: specify a list of hashes (one hash per line) +-f: specify a pwdump file +-c: specify a .lst file (format in which Cain stores hashes and results) + +SELECTING RAINBOW TABLES +---------------- +Any command line argument that is not an option will be interpreted as a directory to search for rainbow tables, +multiple directories can be specified. rcracki_mt recursively scans all specified directories for *.rti (indexed) +and *.rt (old/original) files. You can use .rt & .rti files at once, but this hasn't been tested thoroughly. + +You can set default locations to search for rainbow tables in rcracki_mt.ini. You need to use these in combination +with the command line argument -a [algorithm]. See the comments in the ini file for examples. + +SESSIONS & RESUMING +---------------- +Rcracki_mt has session support, which means that it stores its progress. This allows you to interrupt the session +and resume later on. This also allows sessions that stopped because of a crash (application or even system) to +resume. To use this feature, start rcracki_mt with all the options you'd like, then specify a session name with: + +-s session_name: specify a session name + +Now during cracking, all your valuable precalculations are stored to disk, as well as progress (which files have +been checked) and cracked hashes. If you decide to interrupt the session (using CTRL+C), you can resume it using +the -r option. For example: + +rcracki_mt -r -s my_personal_hashes + +While resuming rcracki_mt you can/have to specify the less important options again, like number of threads and +showing debug information. Usually you will have these settings set to a default value in the .ini file anyway. +Session are deleted after the run is completed. You can choose to keep the precalculation work on disk, for example +if you want to reuse your session later on. Use the '-k' option to enable this feature. + +Rcracki_mt has a default session which gets overwritten every time you start a new job without specifying a session +name. It might be interesting to always keep precalculation work by enabling this feature in rcracki_mt.ini. But +pay attention, these precalculations can become quite large on disk. Currently there is a maximum of around 500 GB +of storage for these precalculations. You can always decide to manually remove the .precalc and .precalc.index +files from disk. Always remove both at the same time, you will screw up your results if you don't. A possible +'todo' for development is to do some verification before using stored precalculations. + +OPTIONAL +---------------- +-t: Number of threads to use (for precalculation and false alarm checking) +Note: In Windows the crack threads run with lower priority. + +-o: specify an output file to store found hashes in a colon (:) separated format. + Hashes are saved immediately when found. Especially useful if you have a large list of hashes. + +-v: Show more information during cracking, for debugging purposes. Please use this flag if you want to show +output and report a bug. + + +EXTRA FEATURES +---------------- +You can pause a running rcracki_mt by using 'P'. It might not pause right away, it actually pauses after doing +precalculation or false alarm checking for one hash. Resume by pressing 'P' again. This pause option is different +from the session/resume feature, as this just pauses a running job, you don't stop rcracki_mt this way. + +If you are trying to crack a pwdump or Cain (.lst) file, containing both LM and NTLM hashes, rcracki_mt will try +and crack the LM hashes. The result will be an uppercase password, which rcracki_mt will then try to correct with +the right casing, using the NTLM hashes. If this fails it will try and perform Unicode correction, using a built-in +mapping. If you happen to have an LM hash coupled with the wrong NTLM hash, this attempt to perform Unicode +correction might take 'forever'. You can press 'S' to skip this step for the current hash. + + +HISTORY AND AUTHORS +================ +rcracki_mt originally started as a modification of a modification (rcracki) of the original RainbowCrack (rcrack). +These programs are all used to perform a rainbow table attack on password hashes, implementing Philippe Oechslin's +faster time-memory trade-off technique. + +Original rcrack code was written by Zhu Shuanglei . + +Martin Westergaard Jørgensen wrote rcracki (improved) to support the rainbow tables +generated by the distributed project www.freerainbowtables.com. These tables are perfected and indexed, making them +faster and smaller. Rcracki also supported hybrid tables. + +Daniël Niggebrugge further enhanced this version and made it multi threaded, creating rcracki_mt. More +features were added over time, making it less of an unofficial version with every release. + +James Nobis - improved *nix compatibility and 64-bit compatability and +continues work on the project. + + +SUPPORTED HASH ALGORITHMS +================ +Hash types supported by rcracki_mt are: LM, NTLM, MD2, MD4, MD5, DoubleMD5, SHA1, RIPEMD160, MSCACHE, MySQL323, +MySQLSHA1, PIX, LMCHALL, HALFLMCHALL, NTLMCHALL, ORACLE + +Actual indexed&perfected tables that were generated by the Free Rainbow Tables project: LM, MD5, NTL, FASTLM, +HALFLMCHALL, SHA1 + + +SUPPORTED PLATFORMS +================ +Rcracki_mt is released both as win32 binary and as source package. Rcracki_mt should work on any Microsoft Windows system, but is only tested on a 32 bit Windows XP. + +The source should work on Linux distributions. It has been tested on: +32-bit Ubuntu +32-bit Debian GNU/Linux +64-bit Debian GNU/Linux + +The source should also work on other platforms and has been tested on: +32-bit MacOSX + +32-bit FreeBSD +64-bit FreeBSD +32-bit NetBSD +32-bit OpenBSD - you must install and use eg++ from ports +64-bit OpenBSD + +Only compilation has been tested on: +64-bit MacOSX + +Please note that to compile under the BSDs you must use gmake. + +OpenBSD threading is a work in progress. + +'OPTIONAL' TODO +================ +- verification of an endpoint when restoring a chainwalkset from disk. +- read multiple chainwalksets from disk at once to try and speed up this process. +- read next table (part) from disk while doing cryptanalysis + + +LINKS +================ +rcracki_mt @ SourceForge: https://sourceforge.net/projects/rcracki/ +Original rcrack: http://www.antsight.com/zsl/rainbowcrack/ +Free Rainbow Tables: http://www.freerainbowtables.com/ +My personal blog: http://blog.distracted.nl/ +Download free rainbow tables: http://tbhost.eu/ +Download free rainbow tables (mirror): http://freerainbowtables.mirror.garr.it/mirrors/freerainbowtables/ + + +THANKS +================ +the_drag0n Writing part of this README + Patch to support Cain .lst files +Joao Inacio Supplying some faster algorithm implementations + + +FAQ +================ +Q: Why do I get this message all the time? "this table contains hashes with length 8 only" +A: You are probably trying to crack LM hashes. You have to split up the hash in 2 parts of 16 hex characters each. + +Q: rcracki_mt is so slow when I'm cracking 5000 hashes, why is that? +A: Rainbow table attacks are only useful for a certain amount of hashes, mainly because of the precalculations that +are needed for every hash you are cracking. At a certain point it is faster to brute force the same key space then +to try and use rainbow tables. Especially if you use a GPU enabled brute forcer, this limit might be reached very +soon. Play around with these to find you limits. + +Q: How can I speed up rcracki_mt? +A: This depends on quite some factors. If your jobs usually comprise of disk access time, you can try and speed up +your storage. For example by using RAID and/or by using solid state disks. If you are trying to crack many hashes +at the same time, you might be better off with buying a faster CPU. diff --git a/Client Applications/rcracki_mt/RainbowCrack.cpp b/Client Applications/rcracki_mt/RainbowCrack.cpp index 2959787..ccd9421 100644 --- a/Client Applications/rcracki_mt/RainbowCrack.cpp +++ b/Client Applications/rcracki_mt/RainbowCrack.cpp @@ -1,869 +1,869 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright (C) Zhu Shuanglei - * Copyright Martin Westergaard Jørgensen - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009 James Dickson - * Copyright 2009, 2010 James Nobis - * Copyright 2010 uroskn - * - * Modified by Martin Westergaard Jørgensen to support * indexed and hybrid tables - * - * Modified by neinbrucke to support multi threading and a bunch of other stuff :) - * - * 2009-01-04 - - Slightly modified (or "fulhack" as - * we say in sweden) to support cain .lst files. - * - * This file is part of rcracki_mt. - * - * rcracki_mt is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 2 of the License, or - * (at your option) any later version. - * - * rcracki_mt is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with rcracki_mt. If not, see . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "CrackEngine.h" -#include "lm2ntlm.h" -#include - -#ifdef _WIN32 - #include -#else - #include - #include - #include - #include -#endif - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma comment(lib, "libeay32.lib") -#endif - -////////////////////////////////////////////////////////////////////// - -#ifdef _WIN32 -void GetTableList(string sWildCharPathName, vector& vPathName) -{ - //vPathName.clear(); - - string sPath; - string::size_type n = sWildCharPathName.find_last_of('\\'); - - if ( n == (sWildCharPathName.size() - 1) ) - { - sWildCharPathName = sWildCharPathName.substr(0, n); - n = sWildCharPathName.find_last_of('\\'); - } - - if (n != string::npos) - sPath = sWildCharPathName.substr(0, n + 1); - - _finddata_t fd; - - long handle = _findfirst(sWildCharPathName.c_str(), &fd); - if (handle != -1) - { - do - { - string sName = fd.name; - if (sName.size()>3) { - if (sName.substr(sName.size()-3, 3) == ".rt" && !(fd.attrib & _A_SUBDIR)) - { - string sPathName = sPath + sName; - vPathName.push_back(sPathName); - } - } - if (sName.size()>4) { - if (sName.substr(sName.size()-4, 4) == ".rti" && !(fd.attrib & _A_SUBDIR)) - { - string sPathName = sPath + sName; - vPathName.push_back(sPathName); - } - } - if (sName.size()>5) { - if (sName.substr(sName.size()-5, 5) == ".rti2" && !(fd.attrib & _A_SUBDIR)) - { - string sPathName = sPath + sName; - vPathName.push_back(sPathName); - } - } - - if (sName != "." && sName != ".." && (fd.attrib & _A_SUBDIR)) - { - string sPath_sub = sPath + sName + '\\'; - string sWildCharPathName_sub = sPath_sub + '*'; - GetTableList(sWildCharPathName_sub, vPathName); - } - - } while (_findnext(handle, &fd) == 0); - - _findclose(handle); - } - //printf("Found %d rainbowtables (files) in %d sub directories...\n", vPathName.size(), subDir_count); -} -#else -//void GetTableList(int argc, char* argv[], vector& vPathName) -void GetTableList(string sWildCharPathName, vector& vPathName) -{ - //vPathName.clear(); - - struct stat buf; - if (lstat(sWildCharPathName.c_str(), &buf) == 0) - { - if (S_ISDIR(buf.st_mode)) - { - DIR *dir = opendir(sWildCharPathName.c_str()); - if(dir) - { - struct dirent *pDir=NULL; - while((pDir = readdir(dir)) != NULL) - { - string filename = ""; - filename += (*pDir).d_name; - if (filename != "." && filename != "..") - { - string new_filename = sWildCharPathName + '/' + filename; - GetTableList(new_filename, vPathName); - } - } - closedir(dir); - } - } - else if (S_ISREG(buf.st_mode)) - { - if (sWildCharPathName.size()>3) - { - if (sWildCharPathName.substr(sWildCharPathName.size()-3, 3) == ".rt") - { - vPathName.push_back(sWildCharPathName); - } - } - if (sWildCharPathName.size()>4) - { - if (sWildCharPathName.substr(sWildCharPathName.size()-4, 4) == ".rti") - { - //string sPathName_sub = sPath_sub + sName_sub; - vPathName.push_back(sWildCharPathName); - //printf("sPathName_sub: %s\n", sPathName_sub.c_str()); - } - } - if ( sWildCharPathName.size() > 5 ) - { - if ( sWildCharPathName.substr( sWildCharPathName.size() - 5, 5 ) == ".rti2" ) - { - vPathName.push_back( sWildCharPathName ); - } - } - } - } -} -#endif - -bool NormalizeHash(string& sHash) -{ - string sNormalizedHash = sHash; - - if ( sNormalizedHash.size() % 2 != 0 - || sNormalizedHash.size() < MIN_HASH_LEN * 2 - || sNormalizedHash.size() > MAX_HASH_LEN * 2) - return false; - - // Make lower - UINT4 i; - for (i = 0; i < sNormalizedHash.size(); i++) - { - if (sNormalizedHash[i] >= 'A' && sNormalizedHash[i] <= 'F') - sNormalizedHash[i] = (char) sNormalizedHash[i] - 'A' + 'a'; - } - - // Character check - for (i = 0; i < sNormalizedHash.size(); i++) - { - if ( (sNormalizedHash[i] < 'a' || sNormalizedHash[i] > 'f') - && (sNormalizedHash[i] < '0' || sNormalizedHash[i] > '9')) - return false; - } - - sHash = sNormalizedHash; - return true; -} - -void LoadLMHashFromPwdumpFile(string sPathName, vector& vUserName, vector& vLMHash, vector& vNTLMHash) -{ - vector vLine; - if (ReadLinesFromFile(sPathName, vLine)) - { - UINT4 i; - for (i = 0; i < vLine.size(); i++) - { - vector vPart; - if (SeperateString(vLine[i], "::::", vPart)) - { - string sUserName = vPart[0]; - string sLMHash = vPart[2]; - string sNTLMHash = vPart[3]; - - if (sLMHash.size() == 32 && sNTLMHash.size() == 32) - { - if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash)) - { - vUserName.push_back(sUserName); - vLMHash.push_back(sLMHash); - vNTLMHash.push_back(sNTLMHash); - } - else - printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str()); - } - } - } - } - else - printf("can't open %s\n", sPathName.c_str()); -} - -// 2009-01-04 - james.dickson - Added this so we can load hashes from cain .LST files. -void LoadLMHashFromCainLSTFile(string sPathName, vector& vUserName, vector& vLMHash, vector& vNTLMHash) -{ - vector vLine; - if (ReadLinesFromFile(sPathName, vLine)) - { - UINT4 i; - for (i = 0; i < vLine.size(); i++) - { - vector vPart; - if (SeperateString(vLine[i], "\t\t\t\t\t\t", vPart)) - { - string sUserName = vPart[0]; - string sLMHash = vPart[4]; - string sNTLMHash = vPart[5]; - - if (sLMHash.size() == 32 && sNTLMHash.size() == 32) - { - if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash)) - { - vUserName.push_back(sUserName); - vLMHash.push_back(sLMHash); - vNTLMHash.push_back(sNTLMHash); - } - else - printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str()); - } - } - } - } - else - printf("can't open %s\n", sPathName.c_str()); -} - -bool NTLMPasswordSeek(unsigned char* pLMPassword, int nLMPasswordLen, int nLMPasswordNext, - unsigned char* pNTLMHash, string& sNTLMPassword) -{ - if (nLMPasswordNext == nLMPasswordLen) - { - unsigned char md[MD4_DIGEST_LENGTH]; - MD4_NEW(pLMPassword, nLMPasswordLen * 2, md); - - if (memcmp(md, pNTLMHash, MD4_DIGEST_LENGTH) == 0) - { - sNTLMPassword = ""; - int i; - for (i = 0; i < nLMPasswordLen; i++) - sNTLMPassword += char(pLMPassword[i * 2]); - return true; - } - else - return false; - } - - if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword)) - return true; - - if ( pLMPassword[nLMPasswordNext * 2] >= 'A' - && pLMPassword[nLMPasswordNext * 2] <= 'Z') - { - pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'A' + 'a'; - if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword)) - return true; - pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'a' + 'A'; - } - - return false; -} - -bool LMPasswordCorrectCase(string sLMPassword, unsigned char* pNTLMHash, string& sNTLMPassword) -{ - if (sLMPassword.size() == 0) - { - sNTLMPassword = ""; - return true; - } - - unsigned char* pLMPassword = new unsigned char[sLMPassword.size() * 2]; - UINT4 i; - for (i = 0; i < sLMPassword.size(); i++) - { - pLMPassword[i * 2 ] = sLMPassword[i]; - pLMPassword[i * 2 + 1] = 0x00; - } - bool fRet = NTLMPasswordSeek(pLMPassword, sLMPassword.size(), 0, pNTLMHash, sNTLMPassword); - - delete pLMPassword; - - return fRet; -} - -void Usage() -{ - Logo(); - - printf("usage: rcracki_mt -h hash rainbow_table_pathname\n"); - printf(" rcracki_mt -l hash_list_file rainbow_table_pathname\n"); - printf(" rcracki_mt -f pwdump_file rainbow_table_pathname\n"); - printf(" rcracki_mt -c lst_file rainbow_table_pathname\n"); - printf("\n"); - printf("-h hash: use raw hash as input\n"); - printf("-l hash_list_file: use hash list file as input, each hash in a line\n"); - printf("-f pwdump_file: use pwdump file as input, handles lanmanager hash only\n"); - printf("-c lst_file: use .lst (cain format) file as input\n"); - printf("-r [-s session_name]: resume from previous session, optional session name\n"); - printf("rainbow_table_pathname: pathname(s) of the rainbow table(s)\n"); - printf("\n"); - printf("Extra options: -t [nr] use this amount of threads/cores, default is 1\n"); - printf(" -o [output_file] write (temporary) results to this file\n"); - printf(" -s [session_name] write session data with this name\n"); - printf(" -k keep precalculation on disk\n"); - printf(" -m [megabytes] limit memory usage\n"); - printf(" -v show debug information\n"); - printf("\n"); -#ifdef _WIN32 - printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]\\MD5\n"); - printf(" rcracki_mt -l hash.txt [path_to_specific_table]\\*\n"); -#else - printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]/MD5\n"); - printf(" rcracki_mt -l hash.txt [path_to_specific_table]/*\n"); -#endif - printf(" rcracki_mt -f hash.txt -t 4 -o results.txt *.rti\n"); -} - -int main(int argc, char* argv[]) -{ - if (argc < 2) - { - Usage(); - return 0; - } - - vector vPathName; - vector vDefaultRainbowTablePath; - string sWildCharPathName = ""; - string sInputType = ""; - string sInput = ""; - string outputFile = ""; - string sApplicationPath = ""; - string sIniPathName = "rcracki_mt.ini"; - bool writeOutput = false; - string sSessionPathName = "rcracki.session"; - string sProgressPathName = "rcracki.progress"; - string sPrecalcPathName = "rcracki.precalc"; - bool resumeSession = false; - bool useDefaultRainbowTablePath = false; - bool debug = false; - bool keepPrecalcFiles = false; - string sAlgorithm = ""; - int maxThreads = 1; - uint64 maxMem = 0; - CHashSet hs; - - // Read defaults from ini file; - bool readFromIni = false; - vector vLine; - if (ReadLinesFromFile(sIniPathName, vLine)) { - readFromIni = true; - } - else if (ReadLinesFromFile(GetApplicationPath() + sIniPathName, vLine)) { - readFromIni = true; - } - if (readFromIni) - { - UINT4 i; - for (i = 0; i < vLine.size(); i++) - { - if (vLine[i].substr(0,1) != "#") - { - vector vPart; - if (SeperateString(vLine[i], "=", vPart)) - { - string sOption = vPart[0]; - string sValue = vPart[1]; - - if (sOption == "Threads") { - maxThreads = atoi(sValue.c_str()); - } - else if (sOption == "MaxMemoryUsage" ) { - maxMem = atoi(sValue.c_str()) * 1024 *1024; - } - else if (sOption == "DefaultResultsFile") { - outputFile = sValue; - } - else if (sOption == "AlwaysStoreResultsToFile") { - if (sValue == "1") - writeOutput = true; - } - else if (sOption.substr(0,24) == "DefaultRainbowTablePath.") { - //printf("Default RT path: %s\n", sValue.c_str()); - vDefaultRainbowTablePath.push_back(vLine[i]); - } - else if (sOption == "DefaultAlgorithm") { - useDefaultRainbowTablePath = true; - sAlgorithm = sValue; - } - else if (sOption == "AlwaysDebug") { - if (sValue == "1") - debug = true; - } - else if (sOption == "AlwaysKeepPrecalcFiles") { - if (sValue == "1") - keepPrecalcFiles = true; - } - else { - printf("illegal option %s in ini file %s\n", sOption.c_str(), sIniPathName.c_str()); - return 0; - } - } - } - } - if (writeOutput && outputFile == "") - { - printf("You need to specify a 'DefaultResultsFile' with 'AlwaysStoreResultsToFile=1'\n"); - writeOutput = false; - } - } - - // Parse command line arguments - int i; - for (i = 1; i < argc; i++) - { - string cla = argv[i]; - if (cla == "-h") { - sInputType = cla; - i++; - if (i < argc) - sInput = argv[i]; - } - else if (cla == "-l") { - sInputType = cla; - i++; - if (i < argc) - sInput = argv[i]; - } - else if (cla == "-f") { - sInputType = cla; - i++; - if (i < argc) - sInput = argv[i]; - } - else if (cla == "-c") { - sInputType = cla; - i++; - if (i < argc) - sInput = argv[i]; - } - else if (cla == "-t") { - i++; - if (i < argc) - maxThreads = atoi(argv[i]); - } - else if ( cla == "-m" ) { - i++; - if ( i < argc ) - maxMem = atoi(argv[i]) * 1024 * 1024; - } - else if (cla == "-o") { - writeOutput = true; - i++; - if (i < argc) - outputFile = argv[i]; - } - else if (cla == "-r") { - resumeSession = true; - } - else if (cla == "-s") { - i++; - if (i < argc) - { - sSessionPathName = argv[i]; - sSessionPathName += ".session"; - sProgressPathName = argv[i]; - sProgressPathName += ".progress"; - sPrecalcPathName = argv[i]; - sPrecalcPathName += ".precalc"; - } - } - else if (cla == "-v") { - debug = true; - } - else if (cla == "-k") { - keepPrecalcFiles = true; - } - else if (cla == "-a") { - useDefaultRainbowTablePath = true; - i++; - if (i < argc) - sAlgorithm = argv[i]; - } - else { - GetTableList(cla, vPathName); - } - } - - if (debug && !readFromIni) - printf("Debug: Couldn't read rcracki_mt.ini, continuing anyway.\n"); - - // Load session data if we are resuming - if (resumeSession) - { - vPathName.clear(); - vector sSessionData; - if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData)) - { - UINT4 i; - for (i = 0; i < sSessionData.size(); i++) - { - vector vPart; - if (SeperateString(sSessionData[i], "=", vPart)) - { - string sOption = vPart[0]; - string sValue = vPart[1]; - - if (sOption == "sPathName") { - vPathName.push_back(sValue); - } - else if (sOption == "sInputType") { - sInputType = sValue; - } - else if (sOption == "sInput") { - sInput = sValue; - } - else if (sOption == "outputFile") { - writeOutput = true; - outputFile = sValue; - } - else if (sOption == "keepPrecalcFiles") { - if (sValue == "1") - keepPrecalcFiles = true; - } - } - } - } - else { - printf("Couldn't open session file %s\n", sSessionPathName.c_str()); - return 0; - } - } - - if (maxThreads<1) - maxThreads = 1; - - // don't load these if we are resuming a session that already has a list of tables - if (useDefaultRainbowTablePath && !resumeSession) - { - UINT4 i; - for (i = 0; i < vDefaultRainbowTablePath.size(); i++) - { - vector vPart; - if (SeperateString(vDefaultRainbowTablePath[i], ".=", vPart)) - { - string lineAlgorithm = vPart[1]; - string linePath = vPart[2]; - - if (lineAlgorithm == sAlgorithm) - GetTableList(linePath, vPathName); - } - } - } - - printf("Using %d threads for pre-calculation and false alarm checking...\n", maxThreads); - - setvbuf(stdout, NULL, _IONBF,0); - if (vPathName.size() == 0) - { - printf("no rainbow table found\n"); - return 0; - } - printf("Found %lu rainbowtable files...\n\n", - (unsigned long)vPathName.size()); - - bool fCrackerType; // true: hash cracker, false: lm cracker - vector vHash; // hash cracker - vector vUserName; // lm cracker - vector vLMHash; // lm cracker - vector vNTLMHash; // lm cracker - if (sInputType == "-h") - { - fCrackerType = true; - - string sHash = sInput; - if (NormalizeHash(sHash)) - vHash.push_back(sHash); - else - printf("invalid hash: %s\n", sHash.c_str()); - } - else if (sInputType == "-l") - { - fCrackerType = true; - - string sPathName = sInput; - vector vLine; - if (ReadLinesFromFile(sPathName, vLine)) - { - UINT4 i; - for (i = 0; i < vLine.size(); i++) - { - string sHash = vLine[i]; - if (NormalizeHash(sHash)) - vHash.push_back(sHash); - else - printf("invalid hash: %s\n", sHash.c_str()); - } - } - else - printf("can't open %s\n", sPathName.c_str()); - } - else if (sInputType == "-f") - { - fCrackerType = false; - - string sPathName = sInput; - LoadLMHashFromPwdumpFile(sPathName, vUserName, vLMHash, vNTLMHash); - } - else if (sInputType == "-c") - { - // 2009-01-04 - james.dickson - Added this for cain-files. - fCrackerType = false; - string sPathName = sInput; - LoadLMHashFromCainLSTFile(sPathName, vUserName, vLMHash, vNTLMHash); - } - else - { - Usage(); - return 0; - } - - if (fCrackerType && vHash.size() == 0) - { - printf("no hashes found"); - return 0; - } - if (!fCrackerType && vLMHash.size() == 0) - { - return 0; - printf("no hashes found"); - } - - if (fCrackerType) - { - UINT4 i; - for (i = 0; i < vHash.size(); i++) - hs.AddHash(vHash[i]); - } - else - { - UINT4 i; - for (i = 0; i < vLMHash.size(); i++) - { - hs.AddHash(vLMHash[i].substr(0, 16)); - hs.AddHash(vLMHash[i].substr(16, 16)); - } - } - - // Load found hashes from session file - if (resumeSession) - { - vector sSessionData; - if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData)) - { - UINT4 i; - for (i = 0; i < sSessionData.size(); i++) - { - vector vPart; - if (SeperateString(sSessionData[i], "=", vPart)) - { - string sOption = vPart[0]; - string sValue = vPart[1]; - - if (sOption == "sHash") { - vector vPartHash; - if (SeperateString(sValue, "::", vPartHash)) - { - string sHash = vPartHash[0]; - string sBinary = vPartHash[1]; - string sPlain = vPartHash[2]; - - hs.SetPlain(sHash, sPlain, sBinary); - } - } - } - } - } - } - - // (Over)write session data if we are not resuming - if (!resumeSession) - { - FILE* file = fopen(sSessionPathName.c_str(), "w"); - string buffer = ""; - - if (file!=NULL) - { - buffer += "sInputType=" + sInputType + "\n"; - buffer += "sInput=" + sInput + "\n"; - - UINT4 i; - for (i = 0; i < vPathName.size(); i++) - { - buffer += "sPathName=" + vPathName[i] + "\n"; - } - - if (writeOutput) - buffer += "outputFile=" + outputFile + "\n"; - - if (keepPrecalcFiles) - buffer += "keepPrecalcFiles=1\n"; - - fputs (buffer.c_str(), file); - fclose (file); - } - file = fopen(sProgressPathName.c_str(), "w"); - fclose (file); - } - - // Run - CCrackEngine ce; - if (writeOutput) - ce.setOutputFile(outputFile); - ce.setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles); - ce.Run(vPathName, hs, maxThreads, maxMem, resumeSession, debug); - - // Remove session files - if (debug) printf("Debug: Removing session files.\n"); - - if (remove(sSessionPathName.c_str()) == 0) - remove(sProgressPathName.c_str()); - else - if (debug) printf("Debug: Failed removing session files.\n"); - - // Statistics - printf("statistics\n"); - printf("-------------------------------------------------------\n"); - printf("plaintext found: %d of %d (%.2f%%)\n", hs.GetStatHashFound(), - hs.GetStatHashTotal(), - 100.0f * hs.GetStatHashFound() / hs.GetStatHashTotal()); - printf("total disk access time: %.2f s\n", ce.GetStatTotalDiskAccessTime()); - printf("total cryptanalysis time: %.2f s\n", ce.GetStatTotalCryptanalysisTime()); - printf("total pre-calculation time: %.2f s\n", ce.GetStatTotalPrecalculationTime()); - printf("total chain walk step: %d\n", ce.GetStatTotalChainWalkStep()); - printf("total false alarm: %d\n", ce.GetStatTotalFalseAlarm()); - printf("total chain walk step due to false alarm: %d\n", ce.GetStatTotalChainWalkStepDueToFalseAlarm()); -// printf("total chain walk step skipped due to checkpoints: %d\n", ce.GetStatTotalFalseAlarmSkipped()); // Checkpoints not used - yet - printf("\n"); - - // Result - printf("result\n"); - printf("-------------------------------------------------------\n"); - if (fCrackerType) - { - UINT4 i; - for (i = 0; i < vHash.size(); i++) - { - string sPlain, sBinary; - if (!hs.GetPlain(vHash[i], sPlain, sBinary)) - { - sPlain = ""; - sBinary = ""; - } - - printf("%s\t%s\thex:%s\n", vHash[i].c_str(), sPlain.c_str(), sBinary.c_str()); - } - } - else - { - UINT4 i; - for (i = 0; i < vLMHash.size(); i++) - { - string sPlain1, sBinary1; - bool fPart1Found = hs.GetPlain(vLMHash[i].substr(0, 16), sPlain1, sBinary1); - if (!fPart1Found) - { - sPlain1 = ""; - sBinary1 = ""; - } - - string sPlain2, sBinary2; - bool fPart2Found = hs.GetPlain(vLMHash[i].substr(16, 16), sPlain2, sBinary2); - if (!fPart2Found) - { - sPlain2 = ""; - sBinary2 = ""; - } - - string sPlain = sPlain1 + sPlain2; - string sBinary = sBinary1 + sBinary2; - - // Correct case - if (fPart1Found && fPart2Found) - { - unsigned char NTLMHash[16]; - int nHashLen; - ParseHash(vNTLMHash[i], NTLMHash, nHashLen); - if (nHashLen != 16) - printf("debug: nHashLen mismatch\n"); - string sNTLMPassword; - if (LMPasswordCorrectCase(sPlain, NTLMHash, sNTLMPassword)) - { - sPlain = sNTLMPassword; - sBinary = HexToStr((const unsigned char*)sNTLMPassword.c_str(), sNTLMPassword.size()); - } - else - { - printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(), sPlain.c_str(), sBinary.c_str()); - LM2NTLMcorrector corrector; - if (corrector.LMPasswordCorrectUnicode(sBinary, NTLMHash, sNTLMPassword)) - { - sPlain = sNTLMPassword; - sBinary = corrector.getBinary(); - if (writeOutput) - { - if (!writeResultLineToFile(outputFile, vNTLMHash[i].c_str(), sPlain.c_str(), sBinary.c_str())) - printf("Couldn't write final result to file!\n"); - } - } - else { - printf("case correction for password %s failed!\n", sPlain.c_str()); - } - } - } - - // Display - printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(), - sPlain.c_str(), - sBinary.c_str()); - - } - } - - return 0; -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright (C) Zhu Shuanglei + * Copyright Martin Westergaard Jørgensen + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009 James Dickson + * Copyright 2009, 2010 James Nobis + * Copyright 2010 uroskn + * + * Modified by Martin Westergaard Jørgensen to support * indexed and hybrid tables + * + * Modified by neinbrucke to support multi threading and a bunch of other stuff :) + * + * 2009-01-04 - - Slightly modified (or "fulhack" as + * we say in sweden) to support cain .lst files. + * + * This file is part of rcracki_mt. + * + * rcracki_mt is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 2 of the License, or + * (at your option) any later version. + * + * rcracki_mt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with rcracki_mt. If not, see . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "CrackEngine.h" +#include "lm2ntlm.h" +#include + +#ifdef _WIN32 + #include +#else + #include + #include + #include + #include +#endif + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma comment(lib, "libeay32.lib") +#endif + +////////////////////////////////////////////////////////////////////// + +#ifdef _WIN32 +void GetTableList(string sWildCharPathName, vector& vPathName) +{ + //vPathName.clear(); + + string sPath; + string::size_type n = sWildCharPathName.find_last_of('\\'); + + if ( n == (sWildCharPathName.size() - 1) ) + { + sWildCharPathName = sWildCharPathName.substr(0, n); + n = sWildCharPathName.find_last_of('\\'); + } + + if (n != string::npos) + sPath = sWildCharPathName.substr(0, n + 1); + + _finddata_t fd; + + long handle = _findfirst(sWildCharPathName.c_str(), &fd); + if (handle != -1) + { + do + { + string sName = fd.name; + if (sName.size()>3) { + if (sName.substr(sName.size()-3, 3) == ".rt" && !(fd.attrib & _A_SUBDIR)) + { + string sPathName = sPath + sName; + vPathName.push_back(sPathName); + } + } + if (sName.size()>4) { + if (sName.substr(sName.size()-4, 4) == ".rti" && !(fd.attrib & _A_SUBDIR)) + { + string sPathName = sPath + sName; + vPathName.push_back(sPathName); + } + } + if (sName.size()>5) { + if (sName.substr(sName.size()-5, 5) == ".rti2" && !(fd.attrib & _A_SUBDIR)) + { + string sPathName = sPath + sName; + vPathName.push_back(sPathName); + } + } + + if (sName != "." && sName != ".." && (fd.attrib & _A_SUBDIR)) + { + string sPath_sub = sPath + sName + '\\'; + string sWildCharPathName_sub = sPath_sub + '*'; + GetTableList(sWildCharPathName_sub, vPathName); + } + + } while (_findnext(handle, &fd) == 0); + + _findclose(handle); + } + //printf("Found %d rainbowtables (files) in %d sub directories...\n", vPathName.size(), subDir_count); +} +#else +//void GetTableList(int argc, char* argv[], vector& vPathName) +void GetTableList(string sWildCharPathName, vector& vPathName) +{ + //vPathName.clear(); + + struct stat buf; + if (lstat(sWildCharPathName.c_str(), &buf) == 0) + { + if (S_ISDIR(buf.st_mode)) + { + DIR *dir = opendir(sWildCharPathName.c_str()); + if(dir) + { + struct dirent *pDir=NULL; + while((pDir = readdir(dir)) != NULL) + { + string filename = ""; + filename += (*pDir).d_name; + if (filename != "." && filename != "..") + { + string new_filename = sWildCharPathName + '/' + filename; + GetTableList(new_filename, vPathName); + } + } + closedir(dir); + } + } + else if (S_ISREG(buf.st_mode)) + { + if (sWildCharPathName.size()>3) + { + if (sWildCharPathName.substr(sWildCharPathName.size()-3, 3) == ".rt") + { + vPathName.push_back(sWildCharPathName); + } + } + if (sWildCharPathName.size()>4) + { + if (sWildCharPathName.substr(sWildCharPathName.size()-4, 4) == ".rti") + { + //string sPathName_sub = sPath_sub + sName_sub; + vPathName.push_back(sWildCharPathName); + //printf("sPathName_sub: %s\n", sPathName_sub.c_str()); + } + } + if ( sWildCharPathName.size() > 5 ) + { + if ( sWildCharPathName.substr( sWildCharPathName.size() - 5, 5 ) == ".rti2" ) + { + vPathName.push_back( sWildCharPathName ); + } + } + } + } +} +#endif + +bool NormalizeHash(string& sHash) +{ + string sNormalizedHash = sHash; + + if ( sNormalizedHash.size() % 2 != 0 + || sNormalizedHash.size() < MIN_HASH_LEN * 2 + || sNormalizedHash.size() > MAX_HASH_LEN * 2) + return false; + + // Make lower + UINT4 i; + for (i = 0; i < sNormalizedHash.size(); i++) + { + if (sNormalizedHash[i] >= 'A' && sNormalizedHash[i] <= 'F') + sNormalizedHash[i] = (char) sNormalizedHash[i] - 'A' + 'a'; + } + + // Character check + for (i = 0; i < sNormalizedHash.size(); i++) + { + if ( (sNormalizedHash[i] < 'a' || sNormalizedHash[i] > 'f') + && (sNormalizedHash[i] < '0' || sNormalizedHash[i] > '9')) + return false; + } + + sHash = sNormalizedHash; + return true; +} + +void LoadLMHashFromPwdumpFile(string sPathName, vector& vUserName, vector& vLMHash, vector& vNTLMHash) +{ + vector vLine; + if (ReadLinesFromFile(sPathName, vLine)) + { + UINT4 i; + for (i = 0; i < vLine.size(); i++) + { + vector vPart; + if (SeperateString(vLine[i], "::::", vPart)) + { + string sUserName = vPart[0]; + string sLMHash = vPart[2]; + string sNTLMHash = vPart[3]; + + if (sLMHash.size() == 32 && sNTLMHash.size() == 32) + { + if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash)) + { + vUserName.push_back(sUserName); + vLMHash.push_back(sLMHash); + vNTLMHash.push_back(sNTLMHash); + } + else + printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str()); + } + } + } + } + else + printf("can't open %s\n", sPathName.c_str()); +} + +// 2009-01-04 - james.dickson - Added this so we can load hashes from cain .LST files. +void LoadLMHashFromCainLSTFile(string sPathName, vector& vUserName, vector& vLMHash, vector& vNTLMHash) +{ + vector vLine; + if (ReadLinesFromFile(sPathName, vLine)) + { + UINT4 i; + for (i = 0; i < vLine.size(); i++) + { + vector vPart; + if (SeperateString(vLine[i], "\t\t\t\t\t\t", vPart)) + { + string sUserName = vPart[0]; + string sLMHash = vPart[4]; + string sNTLMHash = vPart[5]; + + if (sLMHash.size() == 32 && sNTLMHash.size() == 32) + { + if (NormalizeHash(sLMHash) && NormalizeHash(sNTLMHash)) + { + vUserName.push_back(sUserName); + vLMHash.push_back(sLMHash); + vNTLMHash.push_back(sNTLMHash); + } + else + printf("invalid lm/ntlm hash %s:%s\n", sLMHash.c_str(), sNTLMHash.c_str()); + } + } + } + } + else + printf("can't open %s\n", sPathName.c_str()); +} + +bool NTLMPasswordSeek(unsigned char* pLMPassword, int nLMPasswordLen, int nLMPasswordNext, + unsigned char* pNTLMHash, string& sNTLMPassword) +{ + if (nLMPasswordNext == nLMPasswordLen) + { + unsigned char md[MD4_DIGEST_LENGTH]; + MD4_NEW(pLMPassword, nLMPasswordLen * 2, md); + + if (memcmp(md, pNTLMHash, MD4_DIGEST_LENGTH) == 0) + { + sNTLMPassword = ""; + int i; + for (i = 0; i < nLMPasswordLen; i++) + sNTLMPassword += char(pLMPassword[i * 2]); + return true; + } + else + return false; + } + + if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword)) + return true; + + if ( pLMPassword[nLMPasswordNext * 2] >= 'A' + && pLMPassword[nLMPasswordNext * 2] <= 'Z') + { + pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'A' + 'a'; + if (NTLMPasswordSeek(pLMPassword, nLMPasswordLen, nLMPasswordNext + 1, pNTLMHash, sNTLMPassword)) + return true; + pLMPassword[nLMPasswordNext * 2] = (unsigned char) pLMPassword[nLMPasswordNext * 2] - 'a' + 'A'; + } + + return false; +} + +bool LMPasswordCorrectCase(string sLMPassword, unsigned char* pNTLMHash, string& sNTLMPassword) +{ + if (sLMPassword.size() == 0) + { + sNTLMPassword = ""; + return true; + } + + unsigned char* pLMPassword = new unsigned char[sLMPassword.size() * 2]; + UINT4 i; + for (i = 0; i < sLMPassword.size(); i++) + { + pLMPassword[i * 2 ] = sLMPassword[i]; + pLMPassword[i * 2 + 1] = 0x00; + } + bool fRet = NTLMPasswordSeek(pLMPassword, sLMPassword.size(), 0, pNTLMHash, sNTLMPassword); + + delete pLMPassword; + + return fRet; +} + +void Usage() +{ + Logo(); + + printf("usage: rcracki_mt -h hash rainbow_table_pathname\n"); + printf(" rcracki_mt -l hash_list_file rainbow_table_pathname\n"); + printf(" rcracki_mt -f pwdump_file rainbow_table_pathname\n"); + printf(" rcracki_mt -c lst_file rainbow_table_pathname\n"); + printf("\n"); + printf("-h hash: use raw hash as input\n"); + printf("-l hash_list_file: use hash list file as input, each hash in a line\n"); + printf("-f pwdump_file: use pwdump file as input, handles lanmanager hash only\n"); + printf("-c lst_file: use .lst (cain format) file as input\n"); + printf("-r [-s session_name]: resume from previous session, optional session name\n"); + printf("rainbow_table_pathname: pathname(s) of the rainbow table(s)\n"); + printf("\n"); + printf("Extra options: -t [nr] use this amount of threads/cores, default is 1\n"); + printf(" -o [output_file] write (temporary) results to this file\n"); + printf(" -s [session_name] write session data with this name\n"); + printf(" -k keep precalculation on disk\n"); + printf(" -m [megabytes] limit memory usage\n"); + printf(" -v show debug information\n"); + printf("\n"); +#ifdef _WIN32 + printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]\\MD5\n"); + printf(" rcracki_mt -l hash.txt [path_to_specific_table]\\*\n"); +#else + printf("example: rcracki_mt -h 5d41402abc4b2a76b9719d911017c592 -t 2 [path]/MD5\n"); + printf(" rcracki_mt -l hash.txt [path_to_specific_table]/*\n"); +#endif + printf(" rcracki_mt -f hash.txt -t 4 -o results.txt *.rti\n"); +} + +int main(int argc, char* argv[]) +{ + if (argc < 2) + { + Usage(); + return 0; + } + + vector vPathName; + vector vDefaultRainbowTablePath; + string sWildCharPathName = ""; + string sInputType = ""; + string sInput = ""; + string outputFile = ""; + string sApplicationPath = ""; + string sIniPathName = "rcracki_mt.ini"; + bool writeOutput = false; + string sSessionPathName = "rcracki.session"; + string sProgressPathName = "rcracki.progress"; + string sPrecalcPathName = "rcracki.precalc"; + bool resumeSession = false; + bool useDefaultRainbowTablePath = false; + bool debug = false; + bool keepPrecalcFiles = false; + string sAlgorithm = ""; + int maxThreads = 1; + uint64 maxMem = 0; + CHashSet hs; + + // Read defaults from ini file; + bool readFromIni = false; + vector vLine; + if (ReadLinesFromFile(sIniPathName, vLine)) { + readFromIni = true; + } + else if (ReadLinesFromFile(GetApplicationPath() + sIniPathName, vLine)) { + readFromIni = true; + } + if (readFromIni) + { + UINT4 i; + for (i = 0; i < vLine.size(); i++) + { + if (vLine[i].substr(0,1) != "#") + { + vector vPart; + if (SeperateString(vLine[i], "=", vPart)) + { + string sOption = vPart[0]; + string sValue = vPart[1]; + + if (sOption == "Threads") { + maxThreads = atoi(sValue.c_str()); + } + else if (sOption == "MaxMemoryUsage" ) { + maxMem = atoi(sValue.c_str()) * 1024 *1024; + } + else if (sOption == "DefaultResultsFile") { + outputFile = sValue; + } + else if (sOption == "AlwaysStoreResultsToFile") { + if (sValue == "1") + writeOutput = true; + } + else if (sOption.substr(0,24) == "DefaultRainbowTablePath.") { + //printf("Default RT path: %s\n", sValue.c_str()); + vDefaultRainbowTablePath.push_back(vLine[i]); + } + else if (sOption == "DefaultAlgorithm") { + useDefaultRainbowTablePath = true; + sAlgorithm = sValue; + } + else if (sOption == "AlwaysDebug") { + if (sValue == "1") + debug = true; + } + else if (sOption == "AlwaysKeepPrecalcFiles") { + if (sValue == "1") + keepPrecalcFiles = true; + } + else { + printf("illegal option %s in ini file %s\n", sOption.c_str(), sIniPathName.c_str()); + return 0; + } + } + } + } + if (writeOutput && outputFile == "") + { + printf("You need to specify a 'DefaultResultsFile' with 'AlwaysStoreResultsToFile=1'\n"); + writeOutput = false; + } + } + + // Parse command line arguments + int i; + for (i = 1; i < argc; i++) + { + string cla = argv[i]; + if (cla == "-h") { + sInputType = cla; + i++; + if (i < argc) + sInput = argv[i]; + } + else if (cla == "-l") { + sInputType = cla; + i++; + if (i < argc) + sInput = argv[i]; + } + else if (cla == "-f") { + sInputType = cla; + i++; + if (i < argc) + sInput = argv[i]; + } + else if (cla == "-c") { + sInputType = cla; + i++; + if (i < argc) + sInput = argv[i]; + } + else if (cla == "-t") { + i++; + if (i < argc) + maxThreads = atoi(argv[i]); + } + else if ( cla == "-m" ) { + i++; + if ( i < argc ) + maxMem = atoi(argv[i]) * 1024 * 1024; + } + else if (cla == "-o") { + writeOutput = true; + i++; + if (i < argc) + outputFile = argv[i]; + } + else if (cla == "-r") { + resumeSession = true; + } + else if (cla == "-s") { + i++; + if (i < argc) + { + sSessionPathName = argv[i]; + sSessionPathName += ".session"; + sProgressPathName = argv[i]; + sProgressPathName += ".progress"; + sPrecalcPathName = argv[i]; + sPrecalcPathName += ".precalc"; + } + } + else if (cla == "-v") { + debug = true; + } + else if (cla == "-k") { + keepPrecalcFiles = true; + } + else if (cla == "-a") { + useDefaultRainbowTablePath = true; + i++; + if (i < argc) + sAlgorithm = argv[i]; + } + else { + GetTableList(cla, vPathName); + } + } + + if (debug && !readFromIni) + printf("Debug: Couldn't read rcracki_mt.ini, continuing anyway.\n"); + + // Load session data if we are resuming + if (resumeSession) + { + vPathName.clear(); + vector sSessionData; + if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData)) + { + UINT4 i; + for (i = 0; i < sSessionData.size(); i++) + { + vector vPart; + if (SeperateString(sSessionData[i], "=", vPart)) + { + string sOption = vPart[0]; + string sValue = vPart[1]; + + if (sOption == "sPathName") { + vPathName.push_back(sValue); + } + else if (sOption == "sInputType") { + sInputType = sValue; + } + else if (sOption == "sInput") { + sInput = sValue; + } + else if (sOption == "outputFile") { + writeOutput = true; + outputFile = sValue; + } + else if (sOption == "keepPrecalcFiles") { + if (sValue == "1") + keepPrecalcFiles = true; + } + } + } + } + else { + printf("Couldn't open session file %s\n", sSessionPathName.c_str()); + return 0; + } + } + + if (maxThreads<1) + maxThreads = 1; + + // don't load these if we are resuming a session that already has a list of tables + if (useDefaultRainbowTablePath && !resumeSession) + { + UINT4 i; + for (i = 0; i < vDefaultRainbowTablePath.size(); i++) + { + vector vPart; + if (SeperateString(vDefaultRainbowTablePath[i], ".=", vPart)) + { + string lineAlgorithm = vPart[1]; + string linePath = vPart[2]; + + if (lineAlgorithm == sAlgorithm) + GetTableList(linePath, vPathName); + } + } + } + + printf("Using %d threads for pre-calculation and false alarm checking...\n", maxThreads); + + setvbuf(stdout, NULL, _IONBF,0); + if (vPathName.size() == 0) + { + printf("no rainbow table found\n"); + return 0; + } + printf("Found %lu rainbowtable files...\n\n", + (unsigned long)vPathName.size()); + + bool fCrackerType; // true: hash cracker, false: lm cracker + vector vHash; // hash cracker + vector vUserName; // lm cracker + vector vLMHash; // lm cracker + vector vNTLMHash; // lm cracker + if (sInputType == "-h") + { + fCrackerType = true; + + string sHash = sInput; + if (NormalizeHash(sHash)) + vHash.push_back(sHash); + else + printf("invalid hash: %s\n", sHash.c_str()); + } + else if (sInputType == "-l") + { + fCrackerType = true; + + string sPathName = sInput; + vector vLine; + if (ReadLinesFromFile(sPathName, vLine)) + { + UINT4 i; + for (i = 0; i < vLine.size(); i++) + { + string sHash = vLine[i]; + if (NormalizeHash(sHash)) + vHash.push_back(sHash); + else + printf("invalid hash: %s\n", sHash.c_str()); + } + } + else + printf("can't open %s\n", sPathName.c_str()); + } + else if (sInputType == "-f") + { + fCrackerType = false; + + string sPathName = sInput; + LoadLMHashFromPwdumpFile(sPathName, vUserName, vLMHash, vNTLMHash); + } + else if (sInputType == "-c") + { + // 2009-01-04 - james.dickson - Added this for cain-files. + fCrackerType = false; + string sPathName = sInput; + LoadLMHashFromCainLSTFile(sPathName, vUserName, vLMHash, vNTLMHash); + } + else + { + Usage(); + return 0; + } + + if (fCrackerType && vHash.size() == 0) + { + printf("no hashes found"); + return 0; + } + if (!fCrackerType && vLMHash.size() == 0) + { + return 0; + printf("no hashes found"); + } + + if (fCrackerType) + { + UINT4 i; + for (i = 0; i < vHash.size(); i++) + hs.AddHash(vHash[i]); + } + else + { + UINT4 i; + for (i = 0; i < vLMHash.size(); i++) + { + hs.AddHash(vLMHash[i].substr(0, 16)); + hs.AddHash(vLMHash[i].substr(16, 16)); + } + } + + // Load found hashes from session file + if (resumeSession) + { + vector sSessionData; + if (ReadLinesFromFile(sSessionPathName.c_str(), sSessionData)) + { + UINT4 i; + for (i = 0; i < sSessionData.size(); i++) + { + vector vPart; + if (SeperateString(sSessionData[i], "=", vPart)) + { + string sOption = vPart[0]; + string sValue = vPart[1]; + + if (sOption == "sHash") { + vector vPartHash; + if (SeperateString(sValue, "::", vPartHash)) + { + string sHash = vPartHash[0]; + string sBinary = vPartHash[1]; + string sPlain = vPartHash[2]; + + hs.SetPlain(sHash, sPlain, sBinary); + } + } + } + } + } + } + + // (Over)write session data if we are not resuming + if (!resumeSession) + { + FILE* file = fopen(sSessionPathName.c_str(), "w"); + string buffer = ""; + + if (file!=NULL) + { + buffer += "sInputType=" + sInputType + "\n"; + buffer += "sInput=" + sInput + "\n"; + + UINT4 i; + for (i = 0; i < vPathName.size(); i++) + { + buffer += "sPathName=" + vPathName[i] + "\n"; + } + + if (writeOutput) + buffer += "outputFile=" + outputFile + "\n"; + + if (keepPrecalcFiles) + buffer += "keepPrecalcFiles=1\n"; + + fputs (buffer.c_str(), file); + fclose (file); + } + file = fopen(sProgressPathName.c_str(), "w"); + fclose (file); + } + + // Run + CCrackEngine ce; + if (writeOutput) + ce.setOutputFile(outputFile); + ce.setSession(sSessionPathName, sProgressPathName, sPrecalcPathName, keepPrecalcFiles); + ce.Run(vPathName, hs, maxThreads, maxMem, resumeSession, debug); + + // Remove session files + if (debug) printf("Debug: Removing session files.\n"); + + if (remove(sSessionPathName.c_str()) == 0) + remove(sProgressPathName.c_str()); + else + if (debug) printf("Debug: Failed removing session files.\n"); + + // Statistics + printf("statistics\n"); + printf("-------------------------------------------------------\n"); + printf("plaintext found: %d of %d (%.2f%%)\n", hs.GetStatHashFound(), + hs.GetStatHashTotal(), + 100.0f * hs.GetStatHashFound() / hs.GetStatHashTotal()); + printf("total disk access time: %.2f s\n", ce.GetStatTotalDiskAccessTime()); + printf("total cryptanalysis time: %.2f s\n", ce.GetStatTotalCryptanalysisTime()); + printf("total pre-calculation time: %.2f s\n", ce.GetStatTotalPrecalculationTime()); + printf("total chain walk step: %d\n", ce.GetStatTotalChainWalkStep()); + printf("total false alarm: %d\n", ce.GetStatTotalFalseAlarm()); + printf("total chain walk step due to false alarm: %d\n", ce.GetStatTotalChainWalkStepDueToFalseAlarm()); +// printf("total chain walk step skipped due to checkpoints: %d\n", ce.GetStatTotalFalseAlarmSkipped()); // Checkpoints not used - yet + printf("\n"); + + // Result + printf("result\n"); + printf("-------------------------------------------------------\n"); + if (fCrackerType) + { + UINT4 i; + for (i = 0; i < vHash.size(); i++) + { + string sPlain, sBinary; + if (!hs.GetPlain(vHash[i], sPlain, sBinary)) + { + sPlain = ""; + sBinary = ""; + } + + printf("%s\t%s\thex:%s\n", vHash[i].c_str(), sPlain.c_str(), sBinary.c_str()); + } + } + else + { + UINT4 i; + for (i = 0; i < vLMHash.size(); i++) + { + string sPlain1, sBinary1; + bool fPart1Found = hs.GetPlain(vLMHash[i].substr(0, 16), sPlain1, sBinary1); + if (!fPart1Found) + { + sPlain1 = ""; + sBinary1 = ""; + } + + string sPlain2, sBinary2; + bool fPart2Found = hs.GetPlain(vLMHash[i].substr(16, 16), sPlain2, sBinary2); + if (!fPart2Found) + { + sPlain2 = ""; + sBinary2 = ""; + } + + string sPlain = sPlain1 + sPlain2; + string sBinary = sBinary1 + sBinary2; + + // Correct case + if (fPart1Found && fPart2Found) + { + unsigned char NTLMHash[16]; + int nHashLen; + ParseHash(vNTLMHash[i], NTLMHash, nHashLen); + if (nHashLen != 16) + printf("debug: nHashLen mismatch\n"); + string sNTLMPassword; + if (LMPasswordCorrectCase(sPlain, NTLMHash, sNTLMPassword)) + { + sPlain = sNTLMPassword; + sBinary = HexToStr((const unsigned char*)sNTLMPassword.c_str(), sNTLMPassword.size()); + } + else + { + printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(), sPlain.c_str(), sBinary.c_str()); + LM2NTLMcorrector corrector; + if (corrector.LMPasswordCorrectUnicode(sBinary, NTLMHash, sNTLMPassword)) + { + sPlain = sNTLMPassword; + sBinary = corrector.getBinary(); + if (writeOutput) + { + if (!writeResultLineToFile(outputFile, vNTLMHash[i].c_str(), sPlain.c_str(), sBinary.c_str())) + printf("Couldn't write final result to file!\n"); + } + } + else { + printf("case correction for password %s failed!\n", sPlain.c_str()); + } + } + } + + // Display + printf("%-14s\t%s\thex:%s\n", vUserName[i].c_str(), + sPlain.c_str(), + sBinary.c_str()); + + } + } + + return 0; +} diff --git a/Client Applications/rcracki_mt/lm2ntlm.cpp b/Client Applications/rcracki_mt/lm2ntlm.cpp index 33fd94d..a335ad3 100644 --- a/Client Applications/rcracki_mt/lm2ntlm.cpp +++ b/Client Applications/rcracki_mt/lm2ntlm.cpp @@ -1,2269 +1,2269 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "lm2ntlm.h" - -LM2NTLMcorrector::LM2NTLMcorrector() -{ - progressCurrentCombination = 0; - totalCurrentCombination = 1; - counterOverall = 0; - countCombinations = 0; - countTotalCombinations = 0; - counter = 0; - fillMapW(); - aborting = false; - sBinary = ""; - -} - -string LM2NTLMcorrector::getBinary() -{ - return sBinary; -} - -bool LM2NTLMcorrector::LMPasswordCorrectUnicode(string hexPassword, unsigned char* pNTLMHash, string& sNTLMPassword) //, unsigned char* pLMPassword -{ - string sPlain = ""; - - UINT4 i; - for (i = 0; i < hexPassword.size() / 2; i++) - { - string sSub = hexPassword.substr(i * 2, 2); - int nValue; - sscanf(sSub.c_str(), "%02x", &nValue); - sPlain += (unsigned char)nValue; - } - - memcpy(NTLMHash, pNTLMHash, MD4_DIGEST_LENGTH); - - - unsigned long int tmpLength = sPlain.size() * 2; - unsigned char* pLMPassword = new unsigned char[tmpLength]; - - //printf("Searching for unicode password.\n"); - printf("Failed case correction, trying unicode correction for: %s\n", sPlain.c_str()); - //printf("NTLM hash: %s\n\n", sNTLMHash.c_str()); - - setvbuf(stdout, NULL, _IONBF,0); - - startClock = clock(); - previousClock = clock(); - -#ifndef _WIN32 - tty_init(); -#endif - - if (startCorrecting(sPlain, sNTLMPassword, pLMPassword)) - { - sBinary = ByteToStr(pLMPassword, tmpLength).c_str(); - //printf("\nFound unicode password: %s\n", sNTLMPassword.c_str()); - //printf("Password in hex: %s\n", sBinary.c_str()); - writeEndStats(); -#ifndef _WIN32 - tty_done(); -#endif - return true; - } - else - { - //printf("\ncase correction for password %s fail!\n", sPlain.c_str()); - writeEndStats(); -#ifndef _WIN32 - tty_done(); -#endif - return false; - } -} - -bool LM2NTLMcorrector::startCorrecting(string sLMPassword, string& sNTLMPassword, unsigned char* pLMPassword) -{ - if (sLMPassword.size() == 0) - { - sNTLMPassword = ""; - return true; - } - - string muteMe = sLMPassword; - int length = muteMe.size(); - - unsigned char* pMuteMe = new unsigned char[length]; - unsigned char* pTempMute = new unsigned char[length * 2]; - - int i; - for (i = 0; i < length; i++) - { - pMuteMe[i] = muteMe[i]; - pTempMute[i * 2 ] = muteMe[i]; - pTempMute[i * 2 + 1] = 0x00; - unsigned char muteChar = pMuteMe[i]; - int sizeMapForChar = m_mapChar[muteChar].size(); - int j; - for (j = 0; j < sizeMapForChar; j++) - { - currentCharmap[i][j] = m_mapChar[muteChar][j]; - } - } - - int* jAtPos = new int[length]; - int* sizeAtPos = new int[length]; - bool* fullAtPos = new bool[length]; - - int setSize; - for (setSize = 0; setSize <= length; setSize++) - { - int cntFull = 0; - - // clear all 'fullatpos' before new setSize - int i; - for (i=0; i < length; i++) - { - fullAtPos[i] = false; - } - - //printf("Trying full unicode map for %d/%d characters...\t\t\n", setSize, length); - printf("Trying full unicode map for %d/%d characters...%-20s\n", setSize, length, ""); - - bool notFirst = true; - - // start at end and set 'full' combination - countCombinations = 0; - countTotalCombinations = calculateTotalCombinations(length, setSize); - - int sPos = length - 1; - while (sPos >= 0 && notFirst) // finding combinations for current 'setSize' - { - if (aborting) - return false; - - if (cntFull < setSize) - { - if (fullAtPos[sPos] == false) - { - fullAtPos[sPos] = true; - cntFull++; - } - sPos--; - } - else - { - if (fullAtPos[sPos] == false && setSize > 0) - { - fullAtPos[sPos] = true; - cntFull++; - - // reset positions after sPos - int k; - for (k = sPos+1; k < length; k++) - { - if (fullAtPos[k] == true) - { - fullAtPos[k] = false; - cntFull--; - } - } - // start at end again - sPos = length - 1; - } - else - { - sPos--; - } - } - // we have a combination - if (cntFull == setSize) - { - countCombinations++; - - setupCombinationAtPositions(length, pMuteMe, pTempMute, jAtPos, fullAtPos, sizeAtPos); - - if (checkPermutations(length, pTempMute, jAtPos, sizeAtPos, pLMPassword, sNTLMPassword)) - { - return true; - } - } - - if (setSize == 0) - notFirst = false; - } - } - return false; -} - -// set up combination at positions -void LM2NTLMcorrector::setupCombinationAtPositions(int length, unsigned char* pMuteMe, unsigned char* pTempMute, int* jAtPos, bool* fullAtPos, int* sizeAtPos) -{ - progressCurrentCombination = 0; - totalCurrentCombination = 1; - - int i; - for (i=0; i < length; i++) - { - pTempMute[i*2] = currentCharmap[i][0]; - pTempMute[i*2+1] = currentCharmap[i][1]; // reset to first char in map - - jAtPos[i] = 0; // reset charcounter for this char (that is all chars) - - // based on combination, set full map or only upper/lowercase - if (fullAtPos[i] == true) - { - unsigned char muteChar = pMuteMe[i]; - long unsigned int sizeMapForChar = m_mapChar[muteChar].size()/2; // 2 bytes per char - sizeAtPos[i] = sizeMapForChar; - } - else - { - sizeAtPos[i] = 2; - } - - totalCurrentCombination *= sizeAtPos[i]; - } - //printf("Trying %I64u passwords for current combination\t\t\r", totalCurrentCombination); -} - -// go check all permutations for this combination -bool LM2NTLMcorrector::checkPermutations(int length, unsigned char* pTempMute, int* jAtPos, int* sizeAtPos, unsigned char* pLMPassword, string& sNTLMPassword) -{ - int pos = length - 1; - - while (pos >= 0) - { - counter++; - - pos = length - 1; - - int jAtCurPos = jAtPos[pos]; - int sizeMapForCharPos = sizeAtPos[pos]; - // move to start of string and find character with permutations left - while (jAtCurPos >= sizeMapForCharPos-1 && pos >= -1) - { - pos--; - if (pos >= 0 ) - { - jAtCurPos = jAtPos[pos]; - sizeMapForCharPos = sizeAtPos[pos]; - } - } - if (pos < 0) - continue; - - // next permutation for character - jAtCurPos++; - jAtPos[pos] = jAtCurPos; - - pTempMute[pos*2] = currentCharmap[pos][jAtCurPos*2]; - pTempMute[pos*2+1] = currentCharmap[pos][jAtCurPos*2+1]; - - // reset positions after pos - int k; - for (k = pos+1; k < length; k++) - { - jAtPos[k] = 0; - pTempMute[k*2] = currentCharmap[k][0]; // reset to first char in map - pTempMute[k*2+1] = currentCharmap[k][1]; - } - - if (checkNTLMPassword(pTempMute, length, sNTLMPassword) == true) - { - int i; - for (i = 0; i < length*2; i++) - pLMPassword[i] = pTempMute[i]; - return true; - } - - if (counter > 10000) // don't check clocks too often - { - clock_t currentClock = clock(); - float fTime = 1.0f * (currentClock - previousClock); - if (fTime > 1.0f * CLOCKS_PER_SEC) - { - float progressPercentageCurrentCombination = progressCurrentCombination * 100.0f / totalCurrentCombination; - float fTime = 1.0f * (currentClock - startClock) / CLOCKS_PER_SEC; - float currentSpeed = (counterOverall + progressCurrentCombination) / fTime / 1000000; - - //printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)\t\t\t\t\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed); - printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)%-30s\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed, ""); - - previousClock = clock(); - #ifdef _WIN32 - if (_kbhit()) - { - int ch = _getch(); - ch = toupper(ch); - if (ch == 'S') - { - aborting = true; - printf( "\nAborting unicode correction for this hash...\n"); - } - else - { - printf( "\nPress 'S' to skip unicode correction for this hash...\n"); - } - } - #else - int c = tty_getchar(); - if (c >= 0) { - tty_flush(); - if (c==115) { // = s - aborting = true; - printf( "\nAborting unicode correction for this hash...\n"); - } - else { - printf( "\nPress 's' to skip unicode correction for this hash...\n"); - } - } - #endif - if (aborting) - return false; - } - counter = 0; - } - - progressCurrentCombination++; - counterOverall++; - } - return false; -} - -// check password, maybe integrate this function in checkPermutations() for performance reasons. -bool LM2NTLMcorrector::checkNTLMPassword(unsigned char* pLMPassword, int nLMPasswordLen, string& sNTLMPassword) -{ - unsigned char md[MD4_DIGEST_LENGTH]; - - //MD4(pLMPassword, nLMPasswordLen * 2, md); - /* - MD4_CTX ctx; - MD4_Init(&ctx); - MD4_Update(&ctx, pLMPassword, nLMPasswordLen * 2); - MD4_Final(md, &ctx);*/ - - MD4_NEW( pLMPassword, nLMPasswordLen * 2, md ); - - if (memcmp(md, NTLMHash, MD4_DIGEST_LENGTH) == 0) - { - sNTLMPassword = ""; - int i; - for (i = 0; i < nLMPasswordLen; i++) { - sNTLMPassword += char(pLMPassword[i * 2]); - } - return true; - } - else - return false; -} - -void LM2NTLMcorrector::checkAbort() -{ -#ifdef _WIN32 - if (_kbhit()) - { - int ch = _getch(); - ch = toupper(ch); - if (ch == 'S') - { - aborting = true; - printf( "\nAborting unicode correction for this hash...\n"); - } - else - { - printf( "\nPress 'S' to skip unicode correction for this hash...\n"); - } - } -#endif -} - -void LM2NTLMcorrector::writeEndStats() -{ - clock_t endClock = clock(); - if (endClock - startClock > 0) - { - float fTime = 1.0f * (endClock - startClock) / CLOCKS_PER_SEC; - float speedOverall = counterOverall / fTime / 1000000; - printf("\nTried %s passwords in %.2f s (%.2f Mhashes/s)\n", uint64tostr(counterOverall).c_str(), fTime, speedOverall); - } - - printf("\n"); -} - -int LM2NTLMcorrector::calculateTotalCombinations(int length, int setSize) -{ - return factorial(length) / (factorial(setSize) * factorial(length-setSize)); -} - -int LM2NTLMcorrector::factorial (int num) -{ - int result = 1; - int i; - for (i = 1; i <= num; ++i) - result *= i; - return result; -} - -// convert some bytes into a string -string LM2NTLMcorrector::ByteToStr(const unsigned char* pData, int nLen) -{ - string sRet = ""; - int i; - for (i = 0; i < nLen/2; i++) - { - char szByte[3]; - sprintf(szByte, "%02x", pData[i*2+1]); // swap 2-byte characters again - sRet += szByte; - sprintf(szByte, "%02x", pData[i*2]); - sRet += szByte; - } - - return sRet; -} - -void LM2NTLMcorrector::addToMapW(unsigned char key, unsigned char value1, unsigned char value2) -{ - unsigned long int cnt = m_mapChar[key].size(); - m_mapChar[key][cnt] = value2; - m_mapChar[key][cnt+1] = value1; //reverse for endiannes -} - -// construct the mappings, would be nicer in a separate (importable) file -void LM2NTLMcorrector::fillMapW() -{ - addToMapW(0x01, 0x00, 0x01); - addToMapW(0x01, 0x26, 0x3A); - addToMapW(0x02, 0x00, 0x02); - addToMapW(0x02, 0x26, 0x3B); - addToMapW(0x03, 0x00, 0x03); - addToMapW(0x03, 0x26, 0x65); - addToMapW(0x04, 0x00, 0x04); - addToMapW(0x04, 0x26, 0x66); - addToMapW(0x05, 0x00, 0x05); - addToMapW(0x05, 0x26, 0x63); - addToMapW(0x06, 0x00, 0x06); - addToMapW(0x06, 0x26, 0x60); - addToMapW(0x07, 0x00, 0x07); - addToMapW(0x07, 0x00, 0xB7); - addToMapW(0x07, 0x20, 0x22); - addToMapW(0x07, 0x20, 0x24); - addToMapW(0x07, 0x20, 0x26); - addToMapW(0x07, 0x22, 0x19); - addToMapW(0x07, 0x22, 0xC5); - addToMapW(0x07, 0x30, 0xFB); - addToMapW(0x08, 0x00, 0x08); - addToMapW(0x08, 0x25, 0xD8); - addToMapW(0x09, 0x00, 0x09); - addToMapW(0x09, 0x20, 0xDD); - addToMapW(0x09, 0x25, 0xCB); - addToMapW(0x09, 0x30, 0x07); - addToMapW(0x0a, 0x00, 0x0A); - addToMapW(0x0a, 0x25, 0xD9); - addToMapW(0x0b, 0x00, 0x0B); - addToMapW(0x0b, 0x26, 0x42); - addToMapW(0x0c, 0x00, 0x0C); - addToMapW(0x0c, 0x26, 0x40); - addToMapW(0x0d, 0x00, 0x0D); - addToMapW(0x0d, 0x26, 0x6A); - addToMapW(0x0e, 0x00, 0x0E); - addToMapW(0x0e, 0x26, 0x6B); - addToMapW(0x0f, 0x00, 0x0F); - addToMapW(0x0f, 0x00, 0xA4); - addToMapW(0x0f, 0x26, 0x3C); - addToMapW(0x10, 0x00, 0x10); - addToMapW(0x10, 0x25, 0xBA); - addToMapW(0x11, 0x00, 0x11); - addToMapW(0x11, 0x25, 0xC4); - addToMapW(0x12, 0x00, 0x12); - addToMapW(0x12, 0x21, 0x95); - addToMapW(0x13, 0x00, 0x13); - addToMapW(0x13, 0x20, 0x3C); - addToMapW(0x14, 0x00, 0x14); - addToMapW(0x14, 0x00, 0xB6); - addToMapW(0x15, 0x00, 0x15); - addToMapW(0x15, 0x00, 0xA7); - addToMapW(0x16, 0x00, 0x16); - addToMapW(0x16, 0x02, 0xC9); - addToMapW(0x16, 0x25, 0xAC); - addToMapW(0x17, 0x00, 0x17); - addToMapW(0x17, 0x21, 0xA8); - addToMapW(0x18, 0x00, 0x18); - addToMapW(0x18, 0x21, 0x91); - addToMapW(0x19, 0x00, 0x19); - addToMapW(0x19, 0x21, 0x93); - addToMapW(0x1a, 0x00, 0x1A); - addToMapW(0x1a, 0x21, 0x92); - addToMapW(0x1b, 0x00, 0x1B); - addToMapW(0x1b, 0x21, 0x90); - addToMapW(0x1c, 0x00, 0x1C); - addToMapW(0x1c, 0x22, 0x1F); - addToMapW(0x1d, 0x00, 0x1D); - addToMapW(0x1d, 0x21, 0x94); - addToMapW(0x1e, 0x00, 0x1E); - addToMapW(0x1e, 0x25, 0xB2); - addToMapW(0x1f, 0x00, 0x1F); - addToMapW(0x1f, 0x25, 0xBC); - addToMapW(0x20, 0x00, 0x20); - addToMapW(0x20, 0x20, 0x00); - addToMapW(0x20, 0x20, 0x01); - addToMapW(0x20, 0x20, 0x02); - addToMapW(0x20, 0x20, 0x03); - addToMapW(0x20, 0x20, 0x04); - addToMapW(0x20, 0x20, 0x05); - addToMapW(0x20, 0x20, 0x06); - addToMapW(0x20, 0x30, 0x00); - addToMapW(0x21, 0x00, 0x21); - addToMapW(0x21, 0x00, 0xA1); - addToMapW(0x21, 0x01, 0xC3); - addToMapW(0x21, 0xFF, 0x01); - addToMapW(0x22, 0x00, 0x22); - addToMapW(0x22, 0x00, 0xA8); - addToMapW(0x22, 0x02, 0xBA); - addToMapW(0x22, 0x03, 0x08); - addToMapW(0x22, 0x03, 0x0E); - addToMapW(0x22, 0x20, 0x1C); - addToMapW(0x22, 0x20, 0x1D); - addToMapW(0x22, 0x20, 0x1E); - addToMapW(0x22, 0x20, 0x33); - addToMapW(0x22, 0x20, 0x35); - addToMapW(0x22, 0x27, 0x5D); - addToMapW(0x22, 0x27, 0x5E); - addToMapW(0x22, 0x30, 0x1D); - addToMapW(0x22, 0x30, 0x1E); - addToMapW(0x22, 0x30, 0x1F); - addToMapW(0x22, 0xFF, 0x02); - addToMapW(0x23, 0x00, 0x23); - addToMapW(0x23, 0xFF, 0x03); - addToMapW(0x24, 0x00, 0x24); - addToMapW(0x24, 0xFF, 0x04); - addToMapW(0x25, 0x00, 0x25); - addToMapW(0x25, 0x06, 0x6A); - addToMapW(0x25, 0x20, 0x30); - addToMapW(0x25, 0xFF, 0x05); - addToMapW(0x26, 0x00, 0x26); - addToMapW(0x26, 0xFF, 0x06); - addToMapW(0x27, 0x00, 0x27); - addToMapW(0x27, 0x00, 0xB4); - addToMapW(0x27, 0x02, 0xB9); - addToMapW(0x27, 0x02, 0xBB); - addToMapW(0x27, 0x02, 0xBC); - addToMapW(0x27, 0x02, 0xC8); - addToMapW(0x27, 0x02, 0xCA); - addToMapW(0x27, 0x02, 0xCB); - addToMapW(0x27, 0x03, 0x00); - addToMapW(0x27, 0x03, 0x01); - addToMapW(0x27, 0x20, 0x18); - addToMapW(0x27, 0x20, 0x19); - addToMapW(0x27, 0x20, 0x1A); - addToMapW(0x27, 0x20, 0x32); - addToMapW(0x27, 0x27, 0x5B); - addToMapW(0x27, 0x27, 0x5C); - addToMapW(0x27, 0xFF, 0x07); - addToMapW(0x28, 0x00, 0x28); - addToMapW(0x28, 0x23, 0x20); - addToMapW(0x28, 0xFF, 0x08); - addToMapW(0x29, 0x00, 0x29); - addToMapW(0x29, 0x23, 0x21); - addToMapW(0x29, 0xFF, 0x09); - addToMapW(0x2a, 0x00, 0x2A); - addToMapW(0x2a, 0x22, 0x17); - addToMapW(0x2a, 0xFF, 0x0A); - addToMapW(0x2b, 0x00, 0x2B); - addToMapW(0x2b, 0x00, 0xB1); - addToMapW(0x2b, 0x20, 0x20); - addToMapW(0x2b, 0x20, 0x21); - addToMapW(0x2b, 0xFF, 0x0B); - addToMapW(0x2c, 0x00, 0x2C); - addToMapW(0x2c, 0x00, 0xB8); - addToMapW(0x2c, 0x03, 0x27); - addToMapW(0x2c, 0x20, 0x1A); - addToMapW(0x2c, 0x20, 0x1E); - addToMapW(0x2c, 0xFF, 0x0C); - addToMapW(0x2d, 0x00, 0x2D); - addToMapW(0x2d, 0x00, 0xAC); - addToMapW(0x2d, 0x00, 0xAD); - addToMapW(0x2d, 0x20, 0x10); - addToMapW(0x2d, 0x20, 0x11); - addToMapW(0x2d, 0x20, 0x13); - addToMapW(0x2d, 0x20, 0x14); - addToMapW(0x2d, 0x22, 0x12); - addToMapW(0x2d, 0x22, 0x13); - addToMapW(0x2d, 0xFF, 0x0D); - addToMapW(0x2e, 0x00, 0x2E); - addToMapW(0x2e, 0x20, 0x26); - addToMapW(0x2e, 0xFF, 0x0E); - addToMapW(0x2f, 0x00, 0x2F); - addToMapW(0x2f, 0x20, 0x44); - addToMapW(0x2f, 0x22, 0x15); - addToMapW(0x2f, 0x22, 0x16); - addToMapW(0x2f, 0xFF, 0x0F); - addToMapW(0x30, 0x00, 0x30); - addToMapW(0x30, 0x20, 0x70); - addToMapW(0x30, 0x20, 0x80); - addToMapW(0x30, 0xFF, 0x10); - addToMapW(0x31, 0x00, 0x31); - addToMapW(0x31, 0x00, 0xB9); - addToMapW(0x31, 0x00, 0xBC); - addToMapW(0x31, 0x00, 0xBD); - addToMapW(0x31, 0x20, 0x81); - addToMapW(0x31, 0xFF, 0x11); - addToMapW(0x32, 0x00, 0x32); - addToMapW(0x32, 0x00, 0xB2); - addToMapW(0x32, 0x20, 0x82); - addToMapW(0x32, 0xFF, 0x12); - addToMapW(0x33, 0x00, 0x33); - addToMapW(0x33, 0x00, 0xB3); - addToMapW(0x33, 0x00, 0xBE); - addToMapW(0x33, 0x20, 0x83); - addToMapW(0x33, 0xFF, 0x13); - addToMapW(0x34, 0x00, 0x34); - addToMapW(0x34, 0x20, 0x74); - addToMapW(0x34, 0x20, 0x84); - addToMapW(0x34, 0xFF, 0x14); - addToMapW(0x35, 0x00, 0x35); - addToMapW(0x35, 0x20, 0x75); - addToMapW(0x35, 0x20, 0x85); - addToMapW(0x35, 0xFF, 0x15); - addToMapW(0x36, 0x00, 0x36); - addToMapW(0x36, 0x20, 0x76); - addToMapW(0x36, 0x20, 0x86); - addToMapW(0x36, 0xFF, 0x16); - addToMapW(0x37, 0x00, 0x37); - addToMapW(0x37, 0x20, 0x77); - addToMapW(0x37, 0x20, 0x87); - addToMapW(0x37, 0xFF, 0x17); - addToMapW(0x38, 0x00, 0x38); - addToMapW(0x38, 0x20, 0x78); - addToMapW(0x38, 0x20, 0x88); - addToMapW(0x38, 0x22, 0x1E); - addToMapW(0x38, 0xFF, 0x18); - addToMapW(0x39, 0x00, 0x39); - addToMapW(0x39, 0x20, 0x78); - addToMapW(0x39, 0x20, 0x89); - addToMapW(0x39, 0xFF, 0x19); - addToMapW(0x3a, 0x00, 0x3A); - addToMapW(0x3a, 0x05, 0x89); - addToMapW(0x3a, 0x20, 0x26); - addToMapW(0x3a, 0x22, 0x36); - addToMapW(0x3a, 0xFF, 0x1A); - addToMapW(0x3b, 0x00, 0x3B); - addToMapW(0x3b, 0x03, 0x7E); - addToMapW(0x3b, 0xFF, 0x1B); - addToMapW(0x3c, 0x00, 0x3C); - addToMapW(0x3c, 0x00, 0xAB); - addToMapW(0x3c, 0x20, 0x39); - addToMapW(0x3c, 0x23, 0x29); - addToMapW(0x3c, 0x30, 0x08); - addToMapW(0x3c, 0xFF, 0x1C); - addToMapW(0x3d, 0x00, 0x3D); - addToMapW(0x3d, 0x22, 0x61); - addToMapW(0x3d, 0x22, 0x64); - addToMapW(0x3d, 0x22, 0x65); - addToMapW(0x3d, 0xFF, 0x1D); - addToMapW(0x3e, 0x00, 0x3E); - addToMapW(0x3e, 0x00, 0xBB); - addToMapW(0x3e, 0x20, 0x3A); - addToMapW(0x3e, 0x23, 0x2A); - addToMapW(0x3e, 0x30, 0x09); - addToMapW(0x3e, 0xFF, 0x1E); - addToMapW(0x3f, 0x00, 0x3F); - addToMapW(0x40, 0x00, 0x40); - addToMapW(0x40, 0xFF, 0x20); - addToMapW(0x41, 0x00, 0x41); - addToMapW(0x41, 0x00, 0x61); - addToMapW(0x41, 0x00, 0xAA); - addToMapW(0x41, 0x00, 0xC0); - addToMapW(0x41, 0x00, 0xC1); - addToMapW(0x41, 0x00, 0xC2); - addToMapW(0x41, 0x00, 0xC3); - addToMapW(0x41, 0x00, 0xC4); - addToMapW(0x41, 0x00, 0xC5); - addToMapW(0x41, 0x00, 0xC6); - addToMapW(0x41, 0x00, 0xE0); - addToMapW(0x41, 0x00, 0xE1); - addToMapW(0x41, 0x00, 0xE2); - addToMapW(0x41, 0x00, 0xE3); - addToMapW(0x41, 0x00, 0xE4); - addToMapW(0x41, 0x00, 0xE5); - addToMapW(0x41, 0x00, 0xE6); - addToMapW(0x41, 0x01, 0x00); - addToMapW(0x41, 0x01, 0x01); - addToMapW(0x41, 0x01, 0x02); - addToMapW(0x41, 0x01, 0x03); - addToMapW(0x41, 0x01, 0x04); - addToMapW(0x41, 0x01, 0x05); - addToMapW(0x41, 0x01, 0xCD); - addToMapW(0x41, 0x01, 0xCE); - addToMapW(0x41, 0x01, 0xDE); - addToMapW(0x41, 0x01, 0xDF); - addToMapW(0x41, 0x03, 0xB1); - addToMapW(0x41, 0x21, 0x2B); - addToMapW(0x41, 0xFF, 0x21); - addToMapW(0x41, 0xFF, 0x41); - addToMapW(0x42, 0x00, 0x42); - addToMapW(0x42, 0x00, 0x62); - addToMapW(0x42, 0x01, 0x80); - addToMapW(0x42, 0x21, 0x2C); - addToMapW(0x42, 0xFF, 0x22); - addToMapW(0x42, 0xFF, 0x42); - addToMapW(0x43, 0x00, 0x43); - addToMapW(0x43, 0x00, 0x63); - addToMapW(0x43, 0x00, 0xA2); - addToMapW(0x43, 0x00, 0xA9); - addToMapW(0x43, 0x00, 0xC7); - addToMapW(0x43, 0x00, 0xE7); - addToMapW(0x43, 0x00, 0xE8); - addToMapW(0x43, 0x01, 0x06); - addToMapW(0x43, 0x01, 0x07); - addToMapW(0x43, 0x01, 0x08); - addToMapW(0x43, 0x01, 0x09); - addToMapW(0x43, 0x01, 0x0A); - addToMapW(0x43, 0x01, 0x0B); - addToMapW(0x43, 0x01, 0x0C); - addToMapW(0x43, 0x01, 0x0D); - addToMapW(0x43, 0x21, 0x02); - addToMapW(0x43, 0x21, 0x2D); - addToMapW(0x43, 0xFF, 0x23); - addToMapW(0x43, 0xFF, 0x43); - addToMapW(0x44, 0x00, 0x44); - addToMapW(0x44, 0x00, 0x64); - addToMapW(0x44, 0x00, 0xD0); - addToMapW(0x44, 0x00, 0xF0); - addToMapW(0x44, 0x01, 0x0E); - addToMapW(0x44, 0x01, 0x0F); - addToMapW(0x44, 0x01, 0x10); - addToMapW(0x44, 0x01, 0x11); - addToMapW(0x44, 0x01, 0x89); - addToMapW(0x44, 0x03, 0xB4); - addToMapW(0x44, 0x26, 0x6A); - addToMapW(0x44, 0x26, 0x6B); - addToMapW(0x44, 0xFF, 0x24); - addToMapW(0x44, 0xFF, 0x44); - addToMapW(0x45, 0x00, 0x45); - addToMapW(0x45, 0x00, 0x65); - addToMapW(0x45, 0x00, 0xC8); - addToMapW(0x45, 0x00, 0xC9); - addToMapW(0x45, 0x00, 0xCA); - addToMapW(0x45, 0x00, 0xCB); - addToMapW(0x45, 0x00, 0xE8); - addToMapW(0x45, 0x00, 0xE9); - addToMapW(0x45, 0x00, 0xEA); - addToMapW(0x45, 0x00, 0xEB); - addToMapW(0x45, 0x01, 0x12); - addToMapW(0x45, 0x01, 0x13); - addToMapW(0x45, 0x01, 0x14); - addToMapW(0x45, 0x01, 0x15); - addToMapW(0x45, 0x01, 0x16); - addToMapW(0x45, 0x01, 0x17); - addToMapW(0x45, 0x01, 0x18); - addToMapW(0x45, 0x01, 0x19); - addToMapW(0x45, 0x01, 0x1A); - addToMapW(0x45, 0x01, 0x1B); - addToMapW(0x45, 0x03, 0xB5); - addToMapW(0x45, 0x21, 0x07); - addToMapW(0x45, 0x21, 0x2E); - addToMapW(0x45, 0x21, 0x2F); - addToMapW(0x45, 0x21, 0x30); - addToMapW(0x45, 0xFF, 0x25); - addToMapW(0x45, 0xFF, 0x45); - addToMapW(0x46, 0x00, 0x46); - addToMapW(0x46, 0x00, 0x66); - addToMapW(0x46, 0x01, 0x91); - addToMapW(0x46, 0x01, 0x92); - addToMapW(0x46, 0x03, 0xA6); - addToMapW(0x46, 0x03, 0xC6); - addToMapW(0x46, 0x21, 0x31); - addToMapW(0x46, 0xFF, 0x26); - addToMapW(0x46, 0xFF, 0x46); - addToMapW(0x47, 0x00, 0x47); - addToMapW(0x47, 0x00, 0x67); - addToMapW(0x47, 0x01, 0x1C); - addToMapW(0x47, 0x01, 0x1D); - addToMapW(0x47, 0x01, 0x1E); - addToMapW(0x47, 0x01, 0x1F); - addToMapW(0x47, 0x01, 0x20); - addToMapW(0x47, 0x01, 0x21); - addToMapW(0x47, 0x01, 0x22); - addToMapW(0x47, 0x01, 0x23); - addToMapW(0x47, 0x01, 0xE4); - addToMapW(0x47, 0x01, 0xE5); - addToMapW(0x47, 0x01, 0xE6); - addToMapW(0x47, 0x01, 0xE7); - addToMapW(0x47, 0x02, 0x61); - addToMapW(0x47, 0x03, 0x93); - addToMapW(0x47, 0x21, 0x0A); - addToMapW(0x47, 0xFF, 0x27); - addToMapW(0x47, 0xFF, 0x47); - addToMapW(0x48, 0x00, 0x48); - addToMapW(0x48, 0x00, 0x68); - addToMapW(0x48, 0x01, 0x24); - addToMapW(0x48, 0x01, 0x25); - addToMapW(0x48, 0x01, 0x26); - addToMapW(0x48, 0x01, 0x27); - addToMapW(0x48, 0x04, 0xBB); - addToMapW(0x48, 0x21, 0x0B); - addToMapW(0x48, 0x21, 0x0C); - addToMapW(0x48, 0x21, 0x0D); - addToMapW(0x48, 0x21, 0x0E); - addToMapW(0x48, 0xFF, 0x28); - addToMapW(0x48, 0xFF, 0x48); - addToMapW(0x49, 0x00, 0x49); - addToMapW(0x49, 0x00, 0x69); - addToMapW(0x49, 0x00, 0xCC); - addToMapW(0x49, 0x00, 0xCD); - addToMapW(0x49, 0x00, 0xCE); - addToMapW(0x49, 0x00, 0xCF); - addToMapW(0x49, 0x00, 0xEC); - addToMapW(0x49, 0x00, 0xED); - addToMapW(0x49, 0x00, 0xEE); - addToMapW(0x49, 0x00, 0xEF); - addToMapW(0x49, 0x01, 0x28); - addToMapW(0x49, 0x01, 0x29); - addToMapW(0x49, 0x01, 0x2A); - addToMapW(0x49, 0x01, 0x2B); - addToMapW(0x49, 0x01, 0x2C); - addToMapW(0x49, 0x01, 0x2D); - addToMapW(0x49, 0x01, 0x2E); - addToMapW(0x49, 0x01, 0x2F); - addToMapW(0x49, 0x01, 0x30); - addToMapW(0x49, 0x01, 0x31); - addToMapW(0x49, 0x01, 0x97); - addToMapW(0x49, 0x01, 0xCF); - addToMapW(0x49, 0x01, 0xD0); - addToMapW(0x49, 0x21, 0x10); - addToMapW(0x49, 0x21, 0x11); - addToMapW(0x49, 0xFF, 0x29); - addToMapW(0x49, 0xFF, 0x49); - addToMapW(0x4a, 0x00, 0x4A); - addToMapW(0x4a, 0x00, 0x6A); - addToMapW(0x4a, 0x01, 0x34); - addToMapW(0x4a, 0x01, 0x35); - addToMapW(0x4a, 0x01, 0xF0); - addToMapW(0x4a, 0xFF, 0x2A); - addToMapW(0x4a, 0xFF, 0x4A); - addToMapW(0x4b, 0x00, 0x4B); - addToMapW(0x4b, 0x00, 0x6B); - addToMapW(0x4b, 0x01, 0x36); - addToMapW(0x4b, 0x01, 0x37); - addToMapW(0x4b, 0x01, 0xE8); - addToMapW(0x4b, 0x01, 0xE9); - addToMapW(0x4b, 0x21, 0x2A); - addToMapW(0x4b, 0xFF, 0x2B); - addToMapW(0x4b, 0xFF, 0x4B); - addToMapW(0x4c, 0x00, 0x4C); - addToMapW(0x4c, 0x00, 0x6C); - addToMapW(0x4c, 0x00, 0xA3); - addToMapW(0x4c, 0x01, 0x39); - addToMapW(0x4c, 0x01, 0x3A); - addToMapW(0x4c, 0x01, 0x3B); - addToMapW(0x4c, 0x01, 0x3C); - addToMapW(0x4c, 0x01, 0x3D); - addToMapW(0x4c, 0x01, 0x3E); - addToMapW(0x4c, 0x01, 0x41); - addToMapW(0x4c, 0x01, 0x42); - addToMapW(0x4c, 0x01, 0x9A); - addToMapW(0x4c, 0x20, 0xA4); - addToMapW(0x4c, 0x21, 0x12); - addToMapW(0x4c, 0x21, 0x13); - addToMapW(0x4c, 0xFF, 0x2C); - addToMapW(0x4c, 0xFF, 0x4C); - addToMapW(0x4d, 0x00, 0x4D); - addToMapW(0x4d, 0x00, 0x6D); - addToMapW(0x4d, 0x21, 0x33); - addToMapW(0x4d, 0xFF, 0x2D); - addToMapW(0x4d, 0xFF, 0x4D); - addToMapW(0x4e, 0x00, 0x4E); - addToMapW(0x4e, 0x00, 0x6E); - addToMapW(0x4e, 0x00, 0xD1); - addToMapW(0x4e, 0x00, 0xF1); - addToMapW(0x4e, 0x01, 0x43); - addToMapW(0x4e, 0x01, 0x44); - addToMapW(0x4e, 0x01, 0x45); - addToMapW(0x4e, 0x01, 0x46); - addToMapW(0x4e, 0x01, 0x47); - addToMapW(0x4e, 0x01, 0x48); - addToMapW(0x4e, 0x20, 0x7F); - addToMapW(0x4e, 0x21, 0x15); - addToMapW(0x4e, 0x22, 0x29); - addToMapW(0x4e, 0xFF, 0x2E); - addToMapW(0x4e, 0xFF, 0x4E); - addToMapW(0x4f, 0x00, 0x4F); - addToMapW(0x4f, 0x00, 0x6F); - addToMapW(0x4f, 0x00, 0xB0); - addToMapW(0x4f, 0x00, 0xBA); - addToMapW(0x4f, 0x00, 0xD2); - addToMapW(0x4f, 0x00, 0xD3); - addToMapW(0x4f, 0x00, 0xD4); - addToMapW(0x4f, 0x00, 0xD5); - addToMapW(0x4f, 0x00, 0xD6); - addToMapW(0x4f, 0x00, 0xD8); - addToMapW(0x4f, 0x00, 0xF2); - addToMapW(0x4f, 0x00, 0xF3); - addToMapW(0x4f, 0x00, 0xF4); - addToMapW(0x4f, 0x00, 0xF5); - addToMapW(0x4f, 0x00, 0xF6); - addToMapW(0x4f, 0x00, 0xF8); - addToMapW(0x4f, 0x01, 0x4C); - addToMapW(0x4f, 0x01, 0x4D); - addToMapW(0x4f, 0x01, 0x4E); - addToMapW(0x4f, 0x01, 0x4F); - addToMapW(0x4f, 0x01, 0x50); - addToMapW(0x4f, 0x01, 0x51); - addToMapW(0x4f, 0x01, 0x52); - addToMapW(0x4f, 0x01, 0x53); - addToMapW(0x4f, 0x01, 0x9F); - addToMapW(0x4f, 0x01, 0xA0); - addToMapW(0x4f, 0x01, 0xA1); - addToMapW(0x4f, 0x01, 0xD1); - addToMapW(0x4f, 0x01, 0xD2); - addToMapW(0x4f, 0x01, 0xEA); - addToMapW(0x4f, 0x01, 0xEB); - addToMapW(0x4f, 0x01, 0xEC); - addToMapW(0x4f, 0x01, 0xED); - addToMapW(0x4f, 0x03, 0xA9); - addToMapW(0x4f, 0x20, 0xDD); - addToMapW(0x4f, 0x21, 0x26); - addToMapW(0x4f, 0x21, 0x34); - addToMapW(0x4f, 0x22, 0x05); - addToMapW(0x4f, 0x30, 0x07); - addToMapW(0x4f, 0xFF, 0x2F); - addToMapW(0x4f, 0xFF, 0x4F); - addToMapW(0x50, 0x00, 0x50); - addToMapW(0x50, 0x00, 0x70); - addToMapW(0x50, 0x03, 0xC0); - addToMapW(0x50, 0x20, 0xA7); - addToMapW(0x50, 0x21, 0x18); - addToMapW(0x50, 0x21, 0x19); - addToMapW(0x50, 0xFF, 0x30); - addToMapW(0x50, 0xFF, 0x50); - addToMapW(0x51, 0x00, 0x51); - addToMapW(0x51, 0x00, 0x71); - addToMapW(0x51, 0x21, 0x1A); - addToMapW(0x51, 0xFF, 0x31); - addToMapW(0x51, 0xFF, 0x51); - addToMapW(0x52, 0x00, 0x52); - addToMapW(0x52, 0x00, 0x72); - addToMapW(0x52, 0x00, 0xAE); - addToMapW(0x52, 0x01, 0x54); - addToMapW(0x52, 0x01, 0x55); - addToMapW(0x52, 0x01, 0x56); - addToMapW(0x52, 0x01, 0x57); - addToMapW(0x52, 0x01, 0x58); - addToMapW(0x52, 0x01, 0x59); - addToMapW(0x52, 0x21, 0x1B); - addToMapW(0x52, 0x21, 0x1C); - addToMapW(0x52, 0x21, 0x1D); - addToMapW(0x52, 0xFF, 0x32); - addToMapW(0x52, 0xFF, 0x52); - addToMapW(0x53, 0x00, 0x53); - addToMapW(0x53, 0x00, 0x73); - addToMapW(0x53, 0x00, 0xDF); - addToMapW(0x53, 0x01, 0x5A); - addToMapW(0x53, 0x01, 0x5B); - addToMapW(0x53, 0x01, 0x5C); - addToMapW(0x53, 0x01, 0x5D); - addToMapW(0x53, 0x01, 0x5E); - addToMapW(0x53, 0x01, 0x5F); - addToMapW(0x53, 0x01, 0x60); - addToMapW(0x53, 0x01, 0x61); - addToMapW(0x53, 0x01, 0xA9); - addToMapW(0x53, 0x03, 0xA3); - addToMapW(0x53, 0x03, 0xC3); - addToMapW(0x53, 0x22, 0x11); - addToMapW(0x53, 0xFF, 0x33); - addToMapW(0x53, 0xFF, 0x53); - addToMapW(0x54, 0x00, 0x54); - addToMapW(0x54, 0x00, 0x74); - addToMapW(0x54, 0x00, 0xDE); - addToMapW(0x54, 0x00, 0xFE); - addToMapW(0x54, 0x01, 0x62); - addToMapW(0x54, 0x01, 0x63); - addToMapW(0x54, 0x01, 0x64); - addToMapW(0x54, 0x01, 0x65); - addToMapW(0x54, 0x01, 0x66); - addToMapW(0x54, 0x01, 0x67); - addToMapW(0x54, 0x01, 0xAB); - addToMapW(0x54, 0x01, 0xAE); - addToMapW(0x54, 0x03, 0xC4); - addToMapW(0x54, 0x21, 0x22); - addToMapW(0x54, 0xFF, 0x34); - addToMapW(0x54, 0xFF, 0x54); - addToMapW(0x55, 0x00, 0x55); - addToMapW(0x55, 0x00, 0x75); - addToMapW(0x55, 0x00, 0xB5); - addToMapW(0x55, 0x00, 0xD9); - addToMapW(0x55, 0x00, 0xDA); - addToMapW(0x55, 0x00, 0xDB); - addToMapW(0x55, 0x00, 0xDC); - addToMapW(0x55, 0x00, 0xF9); - addToMapW(0x55, 0x00, 0xFA); - addToMapW(0x55, 0x00, 0xFB); - addToMapW(0x55, 0x00, 0xFC); - addToMapW(0x55, 0x01, 0x68); - addToMapW(0x55, 0x01, 0x69); - addToMapW(0x55, 0x01, 0x6A); - addToMapW(0x55, 0x01, 0x6B); - addToMapW(0x55, 0x01, 0x6C); - addToMapW(0x55, 0x01, 0x6D); - addToMapW(0x55, 0x01, 0x6E); - addToMapW(0x55, 0x01, 0x6F); - addToMapW(0x55, 0x01, 0x70); - addToMapW(0x55, 0x01, 0x71); - addToMapW(0x55, 0x01, 0x72); - addToMapW(0x55, 0x01, 0x73); - addToMapW(0x55, 0x01, 0xAF); - addToMapW(0x55, 0x01, 0xB0); - addToMapW(0x55, 0x01, 0xD3); - addToMapW(0x55, 0x01, 0xD4); - addToMapW(0x55, 0x01, 0xD5); - addToMapW(0x55, 0x01, 0xD6); - addToMapW(0x55, 0x01, 0xD7); - addToMapW(0x55, 0x01, 0xD8); - addToMapW(0x55, 0x01, 0xD9); - addToMapW(0x55, 0x01, 0xDA); - addToMapW(0x55, 0x01, 0xDB); - addToMapW(0x55, 0x01, 0xDC); - addToMapW(0x55, 0x03, 0xBC); - addToMapW(0x55, 0xFF, 0x35); - addToMapW(0x55, 0xFF, 0x55); - addToMapW(0x56, 0x00, 0x56); - addToMapW(0x56, 0x00, 0x76); - addToMapW(0x56, 0x22, 0x1A); - addToMapW(0x56, 0x27, 0x13); - addToMapW(0x56, 0xFF, 0x36); - addToMapW(0x56, 0xFF, 0x56); - addToMapW(0x57, 0x00, 0x57); - addToMapW(0x57, 0x00, 0x77); - addToMapW(0x57, 0x01, 0x74); - addToMapW(0x57, 0x01, 0x75); - addToMapW(0x57, 0xFF, 0x37); - addToMapW(0x57, 0xFF, 0x57); - addToMapW(0x58, 0x00, 0x58); - addToMapW(0x58, 0x00, 0x78); - addToMapW(0x58, 0x00, 0xD7); - addToMapW(0x58, 0xFF, 0x38); - addToMapW(0x58, 0xFF, 0x58); - addToMapW(0x59, 0x00, 0x59); - addToMapW(0x59, 0x00, 0x79); - addToMapW(0x59, 0x00, 0xA5); - addToMapW(0x59, 0x00, 0xDD); - addToMapW(0x59, 0x00, 0xFD); - addToMapW(0x59, 0x00, 0xFF); - addToMapW(0x59, 0x01, 0x76); - addToMapW(0x59, 0x01, 0x77); - addToMapW(0x59, 0x01, 0x78); - addToMapW(0x59, 0xFF, 0x39); - addToMapW(0x59, 0xFF, 0x59); - addToMapW(0x5a, 0x00, 0x5A); - addToMapW(0x5a, 0x00, 0x7A); - addToMapW(0x5a, 0x01, 0x79); - addToMapW(0x5a, 0x01, 0x7A); - addToMapW(0x5a, 0x01, 0x7B); - addToMapW(0x5a, 0x01, 0x7C); - addToMapW(0x5a, 0x01, 0x7D); - addToMapW(0x5a, 0x01, 0x7E); - addToMapW(0x5a, 0x01, 0xB6); - addToMapW(0x5a, 0x21, 0x24); - addToMapW(0x5a, 0x21, 0x28); - addToMapW(0x5a, 0xFF, 0x3A); - addToMapW(0x5a, 0xFF, 0x5A); - addToMapW(0x5b, 0x00, 0x5B); - addToMapW(0x5b, 0x30, 0x1A); - addToMapW(0x5b, 0xFF, 0x3B); - addToMapW(0x5c, 0x00, 0x5C); - addToMapW(0x5c, 0x00, 0xA5); - addToMapW(0x5c, 0x22, 0x16); - addToMapW(0x5c, 0xFF, 0x3C); - addToMapW(0x5d, 0x00, 0x5D); - addToMapW(0x5d, 0x30, 0x1B); - addToMapW(0x5d, 0xFF, 0x3D); - addToMapW(0x5e, 0x00, 0x5E); - addToMapW(0x5e, 0x02, 0xC4); - addToMapW(0x5e, 0x02, 0xC6); - addToMapW(0x5e, 0x02, 0xC7); - addToMapW(0x5e, 0x02, 0xD8); - addToMapW(0x5e, 0x03, 0x02); - addToMapW(0x5e, 0x03, 0x06); - addToMapW(0x5e, 0x03, 0x0C); - addToMapW(0x5e, 0x23, 0x03); - addToMapW(0x5e, 0xFF, 0x3E); - addToMapW(0x5f, 0x00, 0x5F); - addToMapW(0x5f, 0x00, 0xAF); - addToMapW(0x5f, 0x00, 0xBE); - addToMapW(0x5f, 0x00, 0xDE); - addToMapW(0x5f, 0x00, 0xFE); - addToMapW(0x5f, 0x02, 0xCD); - addToMapW(0x5f, 0x03, 0x31); - addToMapW(0x5f, 0x03, 0x32); - addToMapW(0x5f, 0x20, 0x17); - addToMapW(0x5f, 0x30, 0xFC); - addToMapW(0x5f, 0xFF, 0x3F); - addToMapW(0x60, 0x00, 0x60); - addToMapW(0x60, 0x02, 0xCB); - addToMapW(0x60, 0x03, 0x00); - addToMapW(0x60, 0x20, 0x18); - addToMapW(0x60, 0x20, 0x35); - addToMapW(0x60, 0xFF, 0x40); - addToMapW(0x7b, 0x00, 0x7B); - addToMapW(0x7b, 0xFF, 0x5B); - addToMapW(0x7c, 0x00, 0x7C); - addToMapW(0x7c, 0x00, 0xA6); - addToMapW(0x7c, 0x01, 0xC0); - addToMapW(0x7c, 0x22, 0x23); - addToMapW(0x7c, 0x27, 0x58); - addToMapW(0x7c, 0xFF, 0x5C); - addToMapW(0x7d, 0x00, 0x7D); - addToMapW(0x7d, 0x30, 0x1B); - addToMapW(0x7d, 0xFF, 0x5D); - addToMapW(0x7e, 0x00, 0x7E); - addToMapW(0x7e, 0x02, 0xDC); - addToMapW(0x7e, 0x03, 0x03); - addToMapW(0x7e, 0x22, 0x3C); - addToMapW(0x7e, 0x22, 0x48); - addToMapW(0x7e, 0xFF, 0x5E); - addToMapW(0x7f, 0x00, 0x7F); - addToMapW(0x7f, 0x23, 0x02); - addToMapW(0x7f, 0x26, 0x60); - addToMapW(0x7f, 0x26, 0x63); - addToMapW(0x7f, 0x26, 0x65); - addToMapW(0x7f, 0x26, 0x66); - addToMapW(0x80, 0x00, 0x80); - addToMapW(0x80, 0x00, 0xC7); - addToMapW(0x80, 0x00, 0xE7); - addToMapW(0x80, 0x01, 0x06); - addToMapW(0x80, 0x01, 0x07); - addToMapW(0x80, 0x03, 0x91); - addToMapW(0x80, 0x03, 0xB1); - addToMapW(0x80, 0x04, 0x10); - addToMapW(0x80, 0x04, 0x30); - addToMapW(0x80, 0x05, 0xD0); - addToMapW(0x80, 0x20, 0xAC); - addToMapW(0x81, 0x00, 0x81); - addToMapW(0x81, 0x03, 0x92); - addToMapW(0x81, 0x03, 0xB2); - addToMapW(0x81, 0x04, 0x02); - addToMapW(0x81, 0x04, 0x11); - addToMapW(0x81, 0x04, 0x31); - addToMapW(0x81, 0x04, 0x52); - addToMapW(0x81, 0x05, 0xD1); - addToMapW(0x82, 0x00, 0x82); - addToMapW(0x82, 0x03, 0x93); - addToMapW(0x82, 0x03, 0xB3); - addToMapW(0x82, 0x04, 0x12); - addToMapW(0x82, 0x04, 0x32); - addToMapW(0x82, 0x05, 0xD2); - addToMapW(0x82, 0x20, 0x1A); - addToMapW(0x83, 0x00, 0x83); - addToMapW(0x83, 0x03, 0x94); - addToMapW(0x83, 0x03, 0xB4); - addToMapW(0x83, 0x04, 0x03); - addToMapW(0x83, 0x04, 0x13); - addToMapW(0x83, 0x04, 0x33); - addToMapW(0x83, 0x04, 0x53); - addToMapW(0x83, 0x05, 0xD3); - addToMapW(0x84, 0x00, 0x84); - addToMapW(0x84, 0x03, 0x95); - addToMapW(0x84, 0x03, 0xB5); - addToMapW(0x84, 0x04, 0x14); - addToMapW(0x84, 0x04, 0x34); - addToMapW(0x84, 0x05, 0xD4); - addToMapW(0x84, 0x20, 0x1E); - addToMapW(0x85, 0x03, 0x96); - addToMapW(0x85, 0x03, 0xB6); - addToMapW(0x85, 0x04, 0x01); - addToMapW(0x85, 0x04, 0x15); - addToMapW(0x85, 0x04, 0x35); - addToMapW(0x85, 0x04, 0x51); - addToMapW(0x85, 0x05, 0xD5); - addToMapW(0x85, 0x20, 0x26); - addToMapW(0x86, 0x00, 0x86); - addToMapW(0x86, 0x03, 0x97); - addToMapW(0x86, 0x03, 0xB7); - addToMapW(0x86, 0x04, 0x16); - addToMapW(0x86, 0x04, 0x36); - addToMapW(0x86, 0x05, 0xD6); - addToMapW(0x86, 0x20, 0x20); - addToMapW(0x87, 0x00, 0x87); - addToMapW(0x87, 0x03, 0x98); - addToMapW(0x87, 0x03, 0xB8); - addToMapW(0x87, 0x04, 0x04); - addToMapW(0x87, 0x04, 0x17); - addToMapW(0x87, 0x04, 0x37); - addToMapW(0x87, 0x04, 0x54); - addToMapW(0x87, 0x05, 0xD7); - addToMapW(0x87, 0x20, 0x21); - addToMapW(0x88, 0x00, 0x88); - addToMapW(0x88, 0x02, 0xC6); - addToMapW(0x88, 0x03, 0x99); - addToMapW(0x88, 0x03, 0xB9); - addToMapW(0x88, 0x04, 0x18); - addToMapW(0x88, 0x04, 0x38); - addToMapW(0x88, 0x05, 0xD8); - addToMapW(0x89, 0x00, 0x89); - addToMapW(0x89, 0x03, 0x9A); - addToMapW(0x89, 0x03, 0xBA); - addToMapW(0x89, 0x04, 0x05); - addToMapW(0x89, 0x04, 0x19); - addToMapW(0x89, 0x04, 0x39); - addToMapW(0x89, 0x04, 0x55); - addToMapW(0x89, 0x05, 0xD9); - addToMapW(0x89, 0x20, 0x30); - addToMapW(0x8a, 0x00, 0x8A); - addToMapW(0x8a, 0x01, 0x50); - addToMapW(0x8a, 0x01, 0x51); - addToMapW(0x8a, 0x01, 0x56); - addToMapW(0x8a, 0x01, 0x57); - addToMapW(0x8a, 0x03, 0x9B); - addToMapW(0x8a, 0x03, 0xBB); - addToMapW(0x8a, 0x04, 0x1A); - addToMapW(0x8a, 0x04, 0x3A); - addToMapW(0x8a, 0x05, 0xDA); - addToMapW(0x8b, 0x00, 0x8B); - addToMapW(0x8b, 0x03, 0x9C); - addToMapW(0x8b, 0x03, 0xBC); - addToMapW(0x8b, 0x04, 0x06); - addToMapW(0x8b, 0x04, 0x1B); - addToMapW(0x8b, 0x04, 0x3B); - addToMapW(0x8b, 0x04, 0x56); - addToMapW(0x8b, 0x05, 0xDB); - addToMapW(0x8b, 0x20, 0x39); - addToMapW(0x8c, 0x00, 0x8C); - addToMapW(0x8c, 0x01, 0x52); - addToMapW(0x8c, 0x01, 0x53); - addToMapW(0x8c, 0x03, 0x9D); - addToMapW(0x8c, 0x03, 0xBD); - addToMapW(0x8c, 0x04, 0x1C); - addToMapW(0x8c, 0x04, 0x3C); - addToMapW(0x8c, 0x05, 0xDC); - addToMapW(0x8d, 0x00, 0x8D); - addToMapW(0x8d, 0x01, 0x31); - addToMapW(0x8d, 0x01, 0x79); - addToMapW(0x8d, 0x01, 0x7A); - addToMapW(0x8d, 0x03, 0x9E); - addToMapW(0x8d, 0x03, 0xBE); - addToMapW(0x8d, 0x04, 0x07); - addToMapW(0x8d, 0x04, 0x1D); - addToMapW(0x8d, 0x04, 0x3D); - addToMapW(0x8d, 0x04, 0x57); - addToMapW(0x8d, 0x05, 0xDD); - addToMapW(0x8e, 0x00, 0x8E); - addToMapW(0x8e, 0x00, 0xC4); - addToMapW(0x8e, 0x00, 0xE4); - addToMapW(0x8e, 0x03, 0x9F); - addToMapW(0x8e, 0x03, 0xBF); - addToMapW(0x8e, 0x04, 0x1E); - addToMapW(0x8e, 0x04, 0x3E); - addToMapW(0x8e, 0x05, 0xDE); - addToMapW(0x8f, 0x00, 0x8F); - addToMapW(0x8f, 0x00, 0xC5); - addToMapW(0x8f, 0x00, 0xE5); - addToMapW(0x8f, 0x01, 0x06); - addToMapW(0x8f, 0x01, 0x07); - addToMapW(0x8f, 0x03, 0xA0); - addToMapW(0x8f, 0x03, 0xC0); - addToMapW(0x8f, 0x04, 0x08); - addToMapW(0x8f, 0x04, 0x1F); - addToMapW(0x8f, 0x04, 0x3F); - addToMapW(0x8f, 0x04, 0x58); - addToMapW(0x8f, 0x05, 0xDF); - addToMapW(0x8f, 0x21, 0x2B); - addToMapW(0x90, 0x00, 0x90); - addToMapW(0x90, 0x00, 0xC9); - addToMapW(0x90, 0x00, 0xE9); - addToMapW(0x90, 0x03, 0xA1); - addToMapW(0x90, 0x03, 0xC1); - addToMapW(0x90, 0x04, 0x20); - addToMapW(0x90, 0x04, 0x40); - addToMapW(0x90, 0x05, 0xE0); - addToMapW(0x91, 0x01, 0x39); - addToMapW(0x91, 0x01, 0x3A); - addToMapW(0x91, 0x03, 0xA3); - addToMapW(0x91, 0x03, 0xC2); - addToMapW(0x91, 0x03, 0xC3); - addToMapW(0x91, 0x04, 0x09); - addToMapW(0x91, 0x04, 0x21); - addToMapW(0x91, 0x04, 0x41); - addToMapW(0x91, 0x04, 0x59); - addToMapW(0x91, 0x05, 0xE1); - addToMapW(0x91, 0x06, 0x51); - addToMapW(0x91, 0x20, 0x18); - addToMapW(0x91, 0xFE, 0x7C); - addToMapW(0x91, 0xFE, 0x7D); - addToMapW(0x92, 0x00, 0xC6); - addToMapW(0x92, 0x00, 0xE6); - addToMapW(0x92, 0x03, 0xA4); - addToMapW(0x92, 0x03, 0xC4); - addToMapW(0x92, 0x04, 0x22); - addToMapW(0x92, 0x04, 0x42); - addToMapW(0x92, 0x05, 0xE2); - addToMapW(0x92, 0x06, 0x52); - addToMapW(0x92, 0x20, 0x19); - addToMapW(0x92, 0xFE, 0x7E); - addToMapW(0x92, 0xFE, 0x7F); - addToMapW(0x93, 0x03, 0xA5); - addToMapW(0x93, 0x03, 0xC5); - addToMapW(0x93, 0x04, 0x0A); - addToMapW(0x93, 0x04, 0x23); - addToMapW(0x93, 0x04, 0x43); - addToMapW(0x93, 0x04, 0x5A); - addToMapW(0x93, 0x05, 0xE3); - addToMapW(0x93, 0x20, 0x1C); - addToMapW(0x94, 0x00, 0xA4); - addToMapW(0x94, 0x03, 0xA6); - addToMapW(0x94, 0x03, 0xC6); - addToMapW(0x94, 0x04, 0x24); - addToMapW(0x94, 0x04, 0x44); - addToMapW(0x94, 0x05, 0xE4); - addToMapW(0x94, 0x20, 0x1D); - addToMapW(0x95, 0x01, 0x22); - addToMapW(0x95, 0x01, 0x23); - addToMapW(0x95, 0x01, 0x3D); - addToMapW(0x95, 0x01, 0x3E); - addToMapW(0x95, 0x03, 0xA7); - addToMapW(0x95, 0x03, 0xC7); - addToMapW(0x95, 0x04, 0x0B); - addToMapW(0x95, 0x04, 0x25); - addToMapW(0x95, 0x04, 0x45); - addToMapW(0x95, 0x04, 0x5B); - addToMapW(0x95, 0x05, 0xE5); - addToMapW(0x95, 0x06, 0x40); - addToMapW(0x95, 0x20, 0x22); - addToMapW(0x96, 0x00, 0xA2); - addToMapW(0x96, 0x03, 0xA8); - addToMapW(0x96, 0x03, 0xC8); - addToMapW(0x96, 0x04, 0x26); - addToMapW(0x96, 0x04, 0x46); - addToMapW(0x96, 0x05, 0xE6); - addToMapW(0x96, 0x20, 0x13); - addToMapW(0x97, 0x00, 0xB5); - addToMapW(0x97, 0x01, 0x5A); - addToMapW(0x97, 0x01, 0x5B); - addToMapW(0x97, 0x03, 0xA9); - addToMapW(0x97, 0x03, 0xC9); - addToMapW(0x97, 0x04, 0x0C); - addToMapW(0x97, 0x04, 0x27); - addToMapW(0x97, 0x04, 0x47); - addToMapW(0x97, 0x04, 0x5C); - addToMapW(0x97, 0x05, 0xE7); - addToMapW(0x97, 0x20, 0x14); - addToMapW(0x98, 0x00, 0x98); - addToMapW(0x98, 0x01, 0x30); - addToMapW(0x98, 0x02, 0xDC); - addToMapW(0x98, 0x04, 0x28); - addToMapW(0x98, 0x04, 0x48); - addToMapW(0x98, 0x05, 0xE8); - addToMapW(0x98, 0x06, 0x21); - addToMapW(0x98, 0xFE, 0x80); - addToMapW(0x99, 0x00, 0x99); - addToMapW(0x99, 0x00, 0xD6); - addToMapW(0x99, 0x00, 0xF6); - addToMapW(0x99, 0x04, 0x0E); - addToMapW(0x99, 0x04, 0x29); - addToMapW(0x99, 0x04, 0x49); - addToMapW(0x99, 0x04, 0x5E); - addToMapW(0x99, 0x05, 0xE9); - addToMapW(0x99, 0x06, 0x22); - addToMapW(0x99, 0x21, 0x22); - addToMapW(0x99, 0xFE, 0x81); - addToMapW(0x99, 0xFE, 0x82); - addToMapW(0x9a, 0x00, 0x9A); - addToMapW(0x9a, 0x00, 0xDC); - addToMapW(0x9a, 0x00, 0xFC); - addToMapW(0x9a, 0x04, 0x2A); - addToMapW(0x9a, 0x04, 0x4A); - addToMapW(0x9a, 0x05, 0xEA); - addToMapW(0x9a, 0x06, 0x23); - addToMapW(0x9a, 0xFE, 0x83); - addToMapW(0x9a, 0xFE, 0x84); - addToMapW(0x9b, 0x00, 0x9B); - addToMapW(0x9b, 0x00, 0xA2); - addToMapW(0x9b, 0x01, 0x64); - addToMapW(0x9b, 0x01, 0x65); - addToMapW(0x9b, 0x04, 0x0F); - addToMapW(0x9b, 0x04, 0x2B); - addToMapW(0x9b, 0x04, 0x4B); - addToMapW(0x9b, 0x04, 0x5F); - addToMapW(0x9b, 0x06, 0x24); - addToMapW(0x9b, 0x20, 0x3A); - addToMapW(0x9b, 0xFE, 0x85); - addToMapW(0x9b, 0xFE, 0x86); - addToMapW(0x9c, 0x00, 0x9C); - addToMapW(0x9c, 0x00, 0xA3); - addToMapW(0x9c, 0x04, 0x2C); - addToMapW(0x9c, 0x04, 0x4C); - addToMapW(0x9c, 0x20, 0xA4); - addToMapW(0x9d, 0x00, 0x9D); - addToMapW(0x9d, 0x00, 0xA5); - addToMapW(0x9d, 0x00, 0xD8); - addToMapW(0x9d, 0x00, 0xF8); - addToMapW(0x9d, 0x01, 0x41); - addToMapW(0x9d, 0x01, 0x42); - addToMapW(0x9d, 0x02, 0x78); - addToMapW(0x9d, 0x03, 0x98); - addToMapW(0x9d, 0x04, 0x2D); - addToMapW(0x9d, 0x04, 0x2E); - addToMapW(0x9d, 0x04, 0x4D); - addToMapW(0x9d, 0x04, 0x4E); - addToMapW(0x9d, 0x06, 0x25); - addToMapW(0x9d, 0x22, 0x05); - addToMapW(0x9d, 0xFE, 0x87); - addToMapW(0x9d, 0xFE, 0x88); - addToMapW(0x9e, 0x00, 0x9E); - addToMapW(0x9e, 0x00, 0xD7); - addToMapW(0x9e, 0x01, 0x5E); - addToMapW(0x9e, 0x01, 0x5F); - addToMapW(0x9e, 0x04, 0x2E); - addToMapW(0x9e, 0x04, 0x4E); - addToMapW(0x9e, 0x06, 0x26); - addToMapW(0x9e, 0x20, 0xA7); - addToMapW(0x9e, 0xFE, 0x89); - addToMapW(0x9e, 0xFE, 0x8A); - addToMapW(0x9e, 0xFE, 0x8B); - addToMapW(0x9e, 0xFE, 0x8C); - addToMapW(0x9f, 0x00, 0x9F); - addToMapW(0x9f, 0x00, 0xA4); - addToMapW(0x9f, 0x00, 0xFF); - addToMapW(0x9f, 0x01, 0x78); - addToMapW(0x9f, 0x01, 0x91); - addToMapW(0x9f, 0x01, 0x92); - addToMapW(0x9f, 0x04, 0x2A); - addToMapW(0x9f, 0x04, 0x2F); - addToMapW(0x9f, 0x04, 0x4A); - addToMapW(0x9f, 0x04, 0x4F); - addToMapW(0x9f, 0x06, 0x27); - addToMapW(0x9f, 0xFE, 0x8D); - addToMapW(0x9f, 0xFE, 0x8E); - addToMapW(0xa0, 0x00, 0xA0); - addToMapW(0xa0, 0x01, 0x00); - addToMapW(0xa0, 0x01, 0x01); - addToMapW(0xa0, 0x06, 0x28); - addToMapW(0xa0, 0xF8, 0xF0); - addToMapW(0xa0, 0xFE, 0x8F); - addToMapW(0xa0, 0xFE, 0x90); - addToMapW(0xa0, 0xFE, 0x91); - addToMapW(0xa0, 0xFE, 0x92); - addToMapW(0xa1, 0x00, 0xA1); - addToMapW(0xa1, 0x01, 0x2A); - addToMapW(0xa1, 0x01, 0x2B); - addToMapW(0xa1, 0x04, 0x10); - addToMapW(0xa1, 0x04, 0x30); - addToMapW(0xa1, 0x06, 0x29); - addToMapW(0xa1, 0x0E, 0x01); - addToMapW(0xa1, 0xFE, 0x93); - addToMapW(0xa1, 0xFE, 0x94); - addToMapW(0xa1, 0xFF, 0x61); - addToMapW(0xa2, 0x00, 0xA2); - addToMapW(0xa2, 0x06, 0x2A); - addToMapW(0xa2, 0x0E, 0x02); - addToMapW(0xa2, 0xFE, 0x95); - addToMapW(0xa2, 0xFE, 0x96); - addToMapW(0xa2, 0xFE, 0x97); - addToMapW(0xa2, 0xFE, 0x98); - addToMapW(0xa2, 0xFF, 0x62); - addToMapW(0xa3, 0x00, 0xA3); - addToMapW(0xa3, 0x01, 0x7B); - addToMapW(0xa3, 0x01, 0x7C); - addToMapW(0xa3, 0x04, 0x11); - addToMapW(0xa3, 0x04, 0x31); - addToMapW(0xa3, 0x06, 0x2B); - addToMapW(0xa3, 0x0E, 0x03); - addToMapW(0xa3, 0xFE, 0x99); - addToMapW(0xa3, 0xFE, 0x9A); - addToMapW(0xa3, 0xFE, 0x9B); - addToMapW(0xa3, 0xFE, 0x9C); - addToMapW(0xa3, 0xFF, 0x63); - addToMapW(0xa4, 0x00, 0xA4); - addToMapW(0xa4, 0x01, 0x04); - addToMapW(0xa4, 0x01, 0x05); - addToMapW(0xa4, 0x06, 0x2C); - addToMapW(0xa4, 0x0E, 0x04); - addToMapW(0xa4, 0xFE, 0x9D); - addToMapW(0xa4, 0xFE, 0x9E); - addToMapW(0xa4, 0xFE, 0x9F); - addToMapW(0xa4, 0xFE, 0xA0); - addToMapW(0xa4, 0xFF, 0x64); - addToMapW(0xa5, 0x00, 0xA5); - addToMapW(0xa5, 0x00, 0xD1); - addToMapW(0xa5, 0x00, 0xF1); - addToMapW(0xa5, 0x04, 0x26); - addToMapW(0xa5, 0x04, 0x46); - addToMapW(0xa5, 0x06, 0x2D); - addToMapW(0xa5, 0x0E, 0x05); - addToMapW(0xa5, 0xFE, 0xA1); - addToMapW(0xa5, 0xFE, 0xA2); - addToMapW(0xa5, 0xFE, 0xA3); - addToMapW(0xa5, 0xFE, 0xA4); - addToMapW(0xa5, 0xFF, 0x65); - addToMapW(0xa6, 0x00, 0xA6); - addToMapW(0xa6, 0x00, 0xAA); - addToMapW(0xa6, 0x01, 0x1E); - addToMapW(0xa6, 0x01, 0x1F); - addToMapW(0xa6, 0x01, 0x7D); - addToMapW(0xa6, 0x01, 0x7E); - addToMapW(0xa6, 0x06, 0x2E); - addToMapW(0xa6, 0x0E, 0x06); - addToMapW(0xa6, 0x20, 0x1D); - addToMapW(0xa6, 0xFE, 0xA5); - addToMapW(0xa6, 0xFE, 0xA6); - addToMapW(0xa6, 0xFE, 0xA7); - addToMapW(0xa6, 0xFE, 0xA8); - addToMapW(0xa6, 0xFF, 0x66); - addToMapW(0xa7, 0x00, 0xA6); - addToMapW(0xa7, 0x00, 0xA7); - addToMapW(0xa7, 0x00, 0xBA); - addToMapW(0xa7, 0x04, 0x14); - addToMapW(0xa7, 0x04, 0x34); - addToMapW(0xa7, 0x06, 0x2F); - addToMapW(0xa7, 0x0E, 0x07); - addToMapW(0xa7, 0xFE, 0xA9); - addToMapW(0xa7, 0xFE, 0xAA); - addToMapW(0xa7, 0xFF, 0x67); - addToMapW(0xa8, 0x00, 0xA8); - addToMapW(0xa8, 0x00, 0xA9); - addToMapW(0xa8, 0x00, 0xBF); - addToMapW(0xa8, 0x01, 0x18); - addToMapW(0xa8, 0x01, 0x19); - addToMapW(0xa8, 0x06, 0x30); - addToMapW(0xa8, 0x0E, 0x08); - addToMapW(0xa8, 0xFE, 0xAB); - addToMapW(0xa8, 0xFE, 0xAC); - addToMapW(0xa8, 0xFF, 0x68); - addToMapW(0xa9, 0x00, 0xA9); - addToMapW(0xa9, 0x00, 0xAE); - addToMapW(0xa9, 0x04, 0x15); - addToMapW(0xa9, 0x04, 0x35); - addToMapW(0xa9, 0x06, 0x31); - addToMapW(0xa9, 0x0E, 0x09); - addToMapW(0xa9, 0x23, 0x10); - addToMapW(0xa9, 0xFE, 0xAD); - addToMapW(0xa9, 0xFE, 0xAE); - addToMapW(0xa9, 0xFF, 0x69); - addToMapW(0xaa, 0x00, 0xAA); - addToMapW(0xaa, 0x00, 0xAC); - addToMapW(0xaa, 0x06, 0x32); - addToMapW(0xaa, 0x0E, 0x0A); - addToMapW(0xaa, 0x23, 0x10); - addToMapW(0xaa, 0xFE, 0xAF); - addToMapW(0xaa, 0xFE, 0xB0); - addToMapW(0xaa, 0xFF, 0x6A); - addToMapW(0xab, 0x00, 0xAB); - addToMapW(0xab, 0x00, 0xBD); - addToMapW(0xab, 0x04, 0x24); - addToMapW(0xab, 0x04, 0x44); - addToMapW(0xab, 0x06, 0x33); - addToMapW(0xab, 0x0E, 0x0B); - addToMapW(0xab, 0xFE, 0xB1); - addToMapW(0xab, 0xFE, 0xB2); - addToMapW(0xab, 0xFE, 0xB3); - addToMapW(0xab, 0xFE, 0xB4); - addToMapW(0xab, 0xFF, 0x6B); - addToMapW(0xac, 0x00, 0xAC); - addToMapW(0xac, 0x00, 0xBC); - addToMapW(0xac, 0x01, 0x0C); - addToMapW(0xac, 0x01, 0x0D); - addToMapW(0xac, 0x06, 0x34); - addToMapW(0xac, 0x0E, 0x0C); - addToMapW(0xac, 0xFE, 0xB5); - addToMapW(0xac, 0xFE, 0xB6); - addToMapW(0xac, 0xFE, 0xB7); - addToMapW(0xac, 0xFE, 0xB8); - addToMapW(0xac, 0xFF, 0x6C); - addToMapW(0xad, 0x00, 0xA1); - addToMapW(0xad, 0x00, 0xAD); - addToMapW(0xad, 0x01, 0x41); - addToMapW(0xad, 0x01, 0x42); - addToMapW(0xad, 0x04, 0x13); - addToMapW(0xad, 0x04, 0x33); - addToMapW(0xad, 0x06, 0x35); - addToMapW(0xad, 0x0E, 0x0D); - addToMapW(0xad, 0xFE, 0xB9); - addToMapW(0xad, 0xFE, 0xBA); - addToMapW(0xad, 0xFE, 0xBB); - addToMapW(0xad, 0xFE, 0xBC); - addToMapW(0xad, 0xFF, 0x6D); - addToMapW(0xae, 0x00, 0xAB); - addToMapW(0xae, 0x00, 0xAE); - addToMapW(0xae, 0x0E, 0x0E); - addToMapW(0xae, 0x22, 0x6A); - addToMapW(0xae, 0x30, 0x0A); - addToMapW(0xae, 0xFF, 0x6E); - addToMapW(0xaf, 0x00, 0xAF); - addToMapW(0xaf, 0x00, 0xBB); - addToMapW(0xaf, 0x0E, 0x0F); - addToMapW(0xaf, 0x22, 0x6B); - addToMapW(0xaf, 0x30, 0x0B); - addToMapW(0xaf, 0xFF, 0x6F); - addToMapW(0xb0, 0x00, 0xB0); - addToMapW(0xb0, 0x0E, 0x10); - addToMapW(0xb0, 0x25, 0x91); - addToMapW(0xb0, 0xFF, 0x70); - addToMapW(0xb1, 0x00, 0xB1); - addToMapW(0xb1, 0x0E, 0x11); - addToMapW(0xb1, 0x25, 0x92); - addToMapW(0xb1, 0xFF, 0x71); - addToMapW(0xb2, 0x00, 0xB2); - addToMapW(0xb2, 0x0E, 0x12); - addToMapW(0xb2, 0x25, 0x93); - addToMapW(0xb2, 0xFF, 0x72); - addToMapW(0xb3, 0x00, 0xA6); - addToMapW(0xb3, 0x00, 0xB3); - addToMapW(0xb3, 0x01, 0xC0); - addToMapW(0xb3, 0x0E, 0x13); - addToMapW(0xb3, 0x22, 0x23); - addToMapW(0xb3, 0x25, 0x02); - addToMapW(0xb3, 0x27, 0x58); - addToMapW(0xb3, 0xFF, 0x73); - addToMapW(0xb4, 0x00, 0xB4); - addToMapW(0xb4, 0x0E, 0x14); - addToMapW(0xb4, 0x25, 0x24); - addToMapW(0xb4, 0xFF, 0x74); - addToMapW(0xb5, 0x00, 0xB5); - addToMapW(0xb5, 0x00, 0xC1); - addToMapW(0xb5, 0x00, 0xE1); - addToMapW(0xb5, 0x01, 0x04); - addToMapW(0xb5, 0x01, 0x05); - addToMapW(0xb5, 0x0E, 0x15); - addToMapW(0xb5, 0x25, 0x61); - addToMapW(0xb5, 0xFF, 0x75); - addToMapW(0xb6, 0x00, 0xB6); - addToMapW(0xb6, 0x00, 0xC2); - addToMapW(0xb6, 0x00, 0xE2); - addToMapW(0xb6, 0x01, 0x0C); - addToMapW(0xb6, 0x01, 0x0D); - addToMapW(0xb6, 0x04, 0x25); - addToMapW(0xb6, 0x04, 0x45); - addToMapW(0xb6, 0x0E, 0x16); - addToMapW(0xb6, 0x25, 0x62); - addToMapW(0xb6, 0xFF, 0x76); - addToMapW(0xb7, 0x00, 0xB7); - addToMapW(0xb7, 0x00, 0xC0); - addToMapW(0xb7, 0x00, 0xE0); - addToMapW(0xb7, 0x01, 0x18); - addToMapW(0xb7, 0x01, 0x19); - addToMapW(0xb7, 0x01, 0x1A); - addToMapW(0xb7, 0x01, 0x1B); - addToMapW(0xb7, 0x0E, 0x17); - addToMapW(0xb7, 0x25, 0x56); - addToMapW(0xb7, 0xFF, 0x77); - addToMapW(0xb8, 0x00, 0xA9); - addToMapW(0xb8, 0x00, 0xB8); - addToMapW(0xb8, 0x01, 0x16); - addToMapW(0xb8, 0x01, 0x17); - addToMapW(0xb8, 0x01, 0x5E); - addToMapW(0xb8, 0x01, 0x5F); - addToMapW(0xb8, 0x04, 0x18); - addToMapW(0xb8, 0x04, 0x38); - addToMapW(0xb8, 0x0E, 0x18); - addToMapW(0xb8, 0x25, 0x55); - addToMapW(0xb8, 0xFF, 0x78); - addToMapW(0xb9, 0x00, 0xB9); - addToMapW(0xb9, 0x0E, 0x19); - addToMapW(0xb9, 0x25, 0x61); - addToMapW(0xb9, 0x25, 0x62); - addToMapW(0xb9, 0x25, 0x63); - addToMapW(0xb9, 0xFF, 0x79); - addToMapW(0xba, 0x00, 0xBA); - addToMapW(0xba, 0x0E, 0x1A); - addToMapW(0xba, 0x25, 0x51); - addToMapW(0xba, 0xFF, 0x7A); - addToMapW(0xbb, 0x00, 0xBB); - addToMapW(0xbb, 0x0E, 0x1B); - addToMapW(0xbb, 0x25, 0x55); - addToMapW(0xbb, 0x25, 0x56); - addToMapW(0xbb, 0x25, 0x57); - addToMapW(0xbb, 0xFF, 0x7B); - addToMapW(0xbc, 0x00, 0xBC); - addToMapW(0xbc, 0x0E, 0x1C); - addToMapW(0xbc, 0x25, 0x5B); - addToMapW(0xbc, 0x25, 0x5C); - addToMapW(0xbc, 0x25, 0x5D); - addToMapW(0xbc, 0xFF, 0x7C); - addToMapW(0xbd, 0x00, 0xA2); - addToMapW(0xbd, 0x00, 0xBD); - addToMapW(0xbd, 0x01, 0x2E); - addToMapW(0xbd, 0x01, 0x2F); - addToMapW(0xbd, 0x01, 0x7B); - addToMapW(0xbd, 0x01, 0x7C); - addToMapW(0xbd, 0x0E, 0x1D); - addToMapW(0xbd, 0x25, 0x5C); - addToMapW(0xbd, 0xFF, 0x7D); - addToMapW(0xbe, 0x00, 0xA5); - addToMapW(0xbe, 0x00, 0xBE); - addToMapW(0xbe, 0x01, 0x60); - addToMapW(0xbe, 0x01, 0x61); - addToMapW(0xbe, 0x04, 0x19); - addToMapW(0xbe, 0x04, 0x39); - addToMapW(0xbe, 0x0E, 0x1E); - addToMapW(0xbe, 0x25, 0x5B); - addToMapW(0xbe, 0xFF, 0x7E); - addToMapW(0xbf, 0x00, 0xAC); - addToMapW(0xbf, 0x00, 0xBF); - addToMapW(0xbf, 0x0E, 0x1F); - addToMapW(0xbf, 0x25, 0x10); - addToMapW(0xbf, 0xFF, 0x7F); - addToMapW(0xc0, 0x00, 0xC0); - addToMapW(0xc0, 0x00, 0xE0); - addToMapW(0xc0, 0x0E, 0x20); - addToMapW(0xc0, 0x25, 0x14); - addToMapW(0xc0, 0xFF, 0x80); - addToMapW(0xc1, 0x00, 0xC1); - addToMapW(0xc1, 0x00, 0xE1); - addToMapW(0xc1, 0x0E, 0x21); - addToMapW(0xc1, 0x25, 0x34); - addToMapW(0xc1, 0xFF, 0x81); - addToMapW(0xc2, 0x00, 0xC2); - addToMapW(0xc2, 0x00, 0xE2); - addToMapW(0xc2, 0x0E, 0x22); - addToMapW(0xc2, 0x25, 0x2C); - addToMapW(0xc2, 0xFF, 0x82); - addToMapW(0xc3, 0x01, 0x02); - addToMapW(0xc3, 0x01, 0x03); - addToMapW(0xc3, 0x0E, 0x23); - addToMapW(0xc3, 0x25, 0x1C); - addToMapW(0xc3, 0xFF, 0x83); - addToMapW(0xc4, 0x00, 0xAF); - addToMapW(0xc4, 0x00, 0xC4); - addToMapW(0xc4, 0x00, 0xE4); - addToMapW(0xc4, 0x02, 0xC9); - addToMapW(0xc4, 0x03, 0x04); - addToMapW(0xc4, 0x03, 0x05); - addToMapW(0xc4, 0x0E, 0x24); - addToMapW(0xc4, 0x25, 0x00); - addToMapW(0xc4, 0xFF, 0x84); - addToMapW(0xc5, 0x00, 0xC5); - addToMapW(0xc5, 0x00, 0xE5); - addToMapW(0xc5, 0x0E, 0x25); - addToMapW(0xc5, 0x20, 0x20); - addToMapW(0xc5, 0x20, 0x21); - addToMapW(0xc5, 0x25, 0x3C); - addToMapW(0xc5, 0xFF, 0x85); - addToMapW(0xc6, 0x00, 0xC6); - addToMapW(0xc6, 0x00, 0xE6); - addToMapW(0xc6, 0x01, 0x02); - addToMapW(0xc6, 0x01, 0x03); - addToMapW(0xc6, 0x01, 0x72); - addToMapW(0xc6, 0x01, 0x73); - addToMapW(0xc6, 0x0E, 0x26); - addToMapW(0xc6, 0x25, 0x5E); - addToMapW(0xc6, 0xFF, 0x86); - addToMapW(0xc7, 0x00, 0xC3); - addToMapW(0xc7, 0x00, 0xC7); - addToMapW(0xc7, 0x00, 0xE3); - addToMapW(0xc7, 0x00, 0xE7); - addToMapW(0xc7, 0x01, 0x6A); - addToMapW(0xc7, 0x01, 0x6B); - addToMapW(0xc7, 0x04, 0x1A); - addToMapW(0xc7, 0x04, 0x3A); - addToMapW(0xc7, 0x0E, 0x27); - addToMapW(0xc7, 0x25, 0x5F); - addToMapW(0xc7, 0xFF, 0x87); - addToMapW(0xc8, 0x00, 0xC8); - addToMapW(0xc8, 0x00, 0xE8); - addToMapW(0xc8, 0x0E, 0x28); - addToMapW(0xc8, 0x25, 0x58); - addToMapW(0xc8, 0x25, 0x59); - addToMapW(0xc8, 0x25, 0x5A); - addToMapW(0xc8, 0xFF, 0x88); - addToMapW(0xc9, 0x00, 0xC9); - addToMapW(0xc9, 0x00, 0xE9); - addToMapW(0xc9, 0x0E, 0x29); - addToMapW(0xc9, 0x25, 0x52); - addToMapW(0xc9, 0x25, 0x53); - addToMapW(0xc9, 0x25, 0x54); - addToMapW(0xc9, 0xFF, 0x89); - addToMapW(0xca, 0x00, 0xCA); - addToMapW(0xca, 0x00, 0xEA); - addToMapW(0xca, 0x0E, 0x2A); - addToMapW(0xca, 0x25, 0x67); - addToMapW(0xca, 0x25, 0x68); - addToMapW(0xca, 0x25, 0x69); - addToMapW(0xca, 0xFF, 0x8A); - addToMapW(0xcb, 0x00, 0xCB); - addToMapW(0xcb, 0x00, 0xEB); - addToMapW(0xcb, 0x0E, 0x2B); - addToMapW(0xcb, 0x25, 0x64); - addToMapW(0xcb, 0x25, 0x65); - addToMapW(0xcb, 0x25, 0x66); - addToMapW(0xcb, 0xFF, 0x8B); - addToMapW(0xcc, 0x03, 0x00); - addToMapW(0xcc, 0x0E, 0x2C); - addToMapW(0xcc, 0x25, 0x5E); - addToMapW(0xcc, 0x25, 0x5F); - addToMapW(0xcc, 0x25, 0x60); - addToMapW(0xcc, 0xFF, 0x8C); - addToMapW(0xcd, 0x00, 0xCD); - addToMapW(0xcd, 0x00, 0xED); - addToMapW(0xcd, 0x0E, 0x2D); - addToMapW(0xcd, 0x25, 0x50); - addToMapW(0xcd, 0xFF, 0x8D); - addToMapW(0xce, 0x00, 0xCE); - addToMapW(0xce, 0x00, 0xEE); - addToMapW(0xce, 0x0E, 0x2E); - addToMapW(0xce, 0x20, 0x21); - addToMapW(0xce, 0x25, 0x6A); - addToMapW(0xce, 0x25, 0x6B); - addToMapW(0xce, 0x25, 0x6C); - addToMapW(0xce, 0xFF, 0x8E); - addToMapW(0xcf, 0x00, 0xA4); - addToMapW(0xcf, 0x00, 0xCF); - addToMapW(0xcf, 0x00, 0xEF); - addToMapW(0xcf, 0x01, 0x7D); - addToMapW(0xcf, 0x01, 0x7E); - addToMapW(0xcf, 0x0E, 0x2F); - addToMapW(0xcf, 0x25, 0x67); - addToMapW(0xcf, 0xFF, 0x8F); - addToMapW(0xd0, 0x00, 0xBA); - addToMapW(0xd0, 0x01, 0x10); - addToMapW(0xd0, 0x01, 0x11); - addToMapW(0xd0, 0x0E, 0x30); - addToMapW(0xd0, 0x25, 0x68); - addToMapW(0xd0, 0xFF, 0x90); - addToMapW(0xd1, 0x00, 0xAA); - addToMapW(0xd1, 0x00, 0xD0); - addToMapW(0xd1, 0x00, 0xD1); - addToMapW(0xd1, 0x00, 0xF0); - addToMapW(0xd1, 0x00, 0xF1); - addToMapW(0xd1, 0x01, 0x10); - addToMapW(0xd1, 0x01, 0x11); - addToMapW(0xd1, 0x01, 0x89); - addToMapW(0xd1, 0x04, 0x1B); - addToMapW(0xd1, 0x04, 0x3B); - addToMapW(0xd1, 0x0E, 0x31); - addToMapW(0xd1, 0x25, 0x64); - addToMapW(0xd1, 0xFF, 0x91); - addToMapW(0xd2, 0x00, 0xCA); - addToMapW(0xd2, 0x00, 0xEA); - addToMapW(0xd2, 0x01, 0x0E); - addToMapW(0xd2, 0x01, 0x0F); - addToMapW(0xd2, 0x03, 0x09); - addToMapW(0xd2, 0x0E, 0x32); - addToMapW(0xd2, 0x25, 0x65); - addToMapW(0xd2, 0xFF, 0x92); - addToMapW(0xd3, 0x00, 0xCB); - addToMapW(0xd3, 0x00, 0xD3); - addToMapW(0xd3, 0x00, 0xEB); - addToMapW(0xd3, 0x00, 0xF3); - addToMapW(0xd3, 0x04, 0x1C); - addToMapW(0xd3, 0x04, 0x3C); - addToMapW(0xd3, 0x0E, 0x33); - addToMapW(0xd3, 0x25, 0x59); - addToMapW(0xd3, 0xFF, 0x93); - addToMapW(0xd4, 0x00, 0xC8); - addToMapW(0xd4, 0x00, 0xD4); - addToMapW(0xd4, 0x00, 0xE8); - addToMapW(0xd4, 0x00, 0xF4); - addToMapW(0xd4, 0x0E, 0x34); - addToMapW(0xd4, 0x25, 0x58); - addToMapW(0xd4, 0xFF, 0x94); - addToMapW(0xd5, 0x01, 0x31); - addToMapW(0xd5, 0x01, 0x47); - addToMapW(0xd5, 0x01, 0x48); - addToMapW(0xd5, 0x01, 0xA0); - addToMapW(0xd5, 0x01, 0xA1); - addToMapW(0xd5, 0x04, 0x1D); - addToMapW(0xd5, 0x04, 0x3D); - addToMapW(0xd5, 0x0E, 0x35); - addToMapW(0xd5, 0x25, 0x52); - addToMapW(0xd5, 0xF8, 0xBB); - addToMapW(0xd5, 0xFF, 0x95); - addToMapW(0xd6, 0x00, 0xCD); - addToMapW(0xd6, 0x00, 0xD6); - addToMapW(0xd6, 0x00, 0xED); - addToMapW(0xd6, 0x00, 0xF6); - addToMapW(0xd6, 0x0E, 0x36); - addToMapW(0xd6, 0x25, 0x53); - addToMapW(0xd6, 0xFF, 0x96); - addToMapW(0xd7, 0x00, 0xCE); - addToMapW(0xd7, 0x00, 0xD7); - addToMapW(0xd7, 0x00, 0xEE); - addToMapW(0xd7, 0x04, 0x1E); - addToMapW(0xd7, 0x04, 0x3E); - addToMapW(0xd7, 0x0E, 0x37); - addToMapW(0xd7, 0x25, 0x6B); - addToMapW(0xd7, 0xFF, 0x97); - addToMapW(0xd8, 0x00, 0xCF); - addToMapW(0xd8, 0x00, 0xD8); - addToMapW(0xd8, 0x00, 0xEF); - addToMapW(0xd8, 0x00, 0xF8); - addToMapW(0xd8, 0x0E, 0x38); - addToMapW(0xd8, 0x20, 0x21); - addToMapW(0xd8, 0x25, 0x6A); - addToMapW(0xd8, 0xFF, 0x98); - addToMapW(0xd9, 0x00, 0xD9); - addToMapW(0xd9, 0x00, 0xF9); - addToMapW(0xd9, 0x0E, 0x39); - addToMapW(0xd9, 0x25, 0x18); - addToMapW(0xd9, 0xFF, 0x99); - addToMapW(0xda, 0x00, 0xDA); - addToMapW(0xda, 0x00, 0xFA); - addToMapW(0xda, 0x0E, 0x3A); - addToMapW(0xda, 0x25, 0x0C); - addToMapW(0xda, 0xFF, 0x9A); - addToMapW(0xdb, 0x00, 0xDB); - addToMapW(0xdb, 0x00, 0xFB); - addToMapW(0xdb, 0x25, 0x88); - addToMapW(0xdb, 0x25, 0x8C); - addToMapW(0xdb, 0x25, 0x90); - addToMapW(0xdb, 0xF8, 0xC1); - addToMapW(0xdb, 0xFF, 0x9B); - addToMapW(0xdc, 0x00, 0xDC); - addToMapW(0xdc, 0x00, 0xFC); - addToMapW(0xdc, 0x25, 0x84); - addToMapW(0xdc, 0xF8, 0xC2); - addToMapW(0xdc, 0xFF, 0x9C); - addToMapW(0xdd, 0x00, 0xA6); - addToMapW(0xdd, 0x01, 0x62); - addToMapW(0xdd, 0x01, 0x63); - addToMapW(0xdd, 0x01, 0xAF); - addToMapW(0xdd, 0x01, 0xB0); - addToMapW(0xdd, 0x04, 0x1F); - addToMapW(0xdd, 0x04, 0x3F); - addToMapW(0xdd, 0x25, 0x8C); - addToMapW(0xdd, 0xF8, 0xC3); - addToMapW(0xdd, 0xFF, 0x9D); - addToMapW(0xde, 0x00, 0xCC); - addToMapW(0xde, 0x00, 0xEC); - addToMapW(0xde, 0x01, 0x6E); - addToMapW(0xde, 0x01, 0x6F); - addToMapW(0xde, 0x03, 0x03); - addToMapW(0xde, 0x25, 0x90); - addToMapW(0xde, 0xF8, 0xC4); - addToMapW(0xde, 0xFF, 0x9E); - addToMapW(0xdf, 0x00, 0xDF); - addToMapW(0xdf, 0x0E, 0x3F); - addToMapW(0xdf, 0x25, 0x80); - addToMapW(0xdf, 0xFF, 0x9F); - addToMapW(0xe0, 0x00, 0xD3); - addToMapW(0xe0, 0x00, 0xF3); - addToMapW(0xe0, 0x03, 0x91); - addToMapW(0xe0, 0x03, 0xB1); - addToMapW(0xe0, 0x04, 0x2F); - addToMapW(0xe0, 0x04, 0x4F); - addToMapW(0xe0, 0x06, 0x36); - addToMapW(0xe0, 0x0E, 0x40); - addToMapW(0xe0, 0xFE, 0xBD); - addToMapW(0xe0, 0xFE, 0xBE); - addToMapW(0xe0, 0xFE, 0xBF); - addToMapW(0xe0, 0xFE, 0xC0); - addToMapW(0xe1, 0x00, 0xDF); - addToMapW(0xe1, 0x03, 0xB2); - addToMapW(0xe1, 0x06, 0x37); - addToMapW(0xe1, 0x0E, 0x41); - addToMapW(0xe1, 0xFE, 0xC1); - addToMapW(0xe1, 0xFE, 0xC2); - addToMapW(0xe1, 0xFE, 0xC3); - addToMapW(0xe1, 0xFE, 0xC4); - addToMapW(0xe2, 0x00, 0xD4); - addToMapW(0xe2, 0x00, 0xF4); - addToMapW(0xe2, 0x01, 0x4C); - addToMapW(0xe2, 0x01, 0x4D); - addToMapW(0xe2, 0x03, 0x93); - addToMapW(0xe2, 0x04, 0x20); - addToMapW(0xe2, 0x04, 0x40); - addToMapW(0xe2, 0x06, 0x38); - addToMapW(0xe2, 0x0E, 0x42); - addToMapW(0xe2, 0xFE, 0xC5); - addToMapW(0xe2, 0xFE, 0xC6); - addToMapW(0xe2, 0xFE, 0xC7); - addToMapW(0xe2, 0xFE, 0xC8); - addToMapW(0xe3, 0x00, 0xD2); - addToMapW(0xe3, 0x00, 0xF2); - addToMapW(0xe3, 0x01, 0x43); - addToMapW(0xe3, 0x01, 0x44); - addToMapW(0xe3, 0x03, 0xA0); - addToMapW(0xe3, 0x03, 0xC0); - addToMapW(0xe3, 0x06, 0x39); - addToMapW(0xe3, 0x0E, 0x43); - addToMapW(0xe3, 0xFE, 0xC9); - addToMapW(0xe3, 0xFE, 0xCA); - addToMapW(0xe3, 0xFE, 0xCB); - addToMapW(0xe3, 0xFE, 0xCC); - addToMapW(0xe4, 0x01, 0xA9); - addToMapW(0xe4, 0x03, 0xA3); - addToMapW(0xe4, 0x03, 0xC3); - addToMapW(0xe4, 0x04, 0x21); - addToMapW(0xe4, 0x04, 0x41); - addToMapW(0xe4, 0x06, 0x3A); - addToMapW(0xe4, 0x0E, 0x44); - addToMapW(0xe4, 0x22, 0x11); - addToMapW(0xe4, 0xFE, 0xCD); - addToMapW(0xe4, 0xFE, 0xCE); - addToMapW(0xe4, 0xFE, 0xCF); - addToMapW(0xe4, 0xFE, 0xD0); - addToMapW(0xe5, 0x00, 0xD5); - addToMapW(0xe5, 0x00, 0xF5); - addToMapW(0xe5, 0x06, 0x41); - addToMapW(0xe5, 0x0E, 0x45); - addToMapW(0xe5, 0xFE, 0xD1); - addToMapW(0xe5, 0xFE, 0xD2); - addToMapW(0xe5, 0xFE, 0xD3); - addToMapW(0xe5, 0xFE, 0xD4); - addToMapW(0xe6, 0x00, 0xB5); - addToMapW(0xe6, 0x01, 0x60); - addToMapW(0xe6, 0x01, 0x61); - addToMapW(0xe6, 0x03, 0xBC); - addToMapW(0xe6, 0x04, 0x22); - addToMapW(0xe6, 0x04, 0x42); - addToMapW(0xe6, 0x0E, 0x46); - addToMapW(0xe7, 0x03, 0xA4); - addToMapW(0xe7, 0x03, 0xC4); - addToMapW(0xe7, 0x06, 0x42); - addToMapW(0xe7, 0x0E, 0x47); - addToMapW(0xe7, 0xF8, 0xBC); - addToMapW(0xe7, 0xFE, 0xD5); - addToMapW(0xe7, 0xFE, 0xD6); - addToMapW(0xe7, 0xFE, 0xD7); - addToMapW(0xe7, 0xFE, 0xD8); - addToMapW(0xe8, 0x00, 0xD7); - addToMapW(0xe8, 0x00, 0xDE); - addToMapW(0xe8, 0x00, 0xFE); - addToMapW(0xe8, 0x01, 0x36); - addToMapW(0xe8, 0x01, 0x37); - addToMapW(0xe8, 0x01, 0x54); - addToMapW(0xe8, 0x01, 0x55); - addToMapW(0xe8, 0x02, 0x78); - addToMapW(0xe8, 0x03, 0xA6); - addToMapW(0xe8, 0x03, 0xC6); - addToMapW(0xe8, 0x04, 0x23); - addToMapW(0xe8, 0x04, 0x43); - addToMapW(0xe8, 0x06, 0x43); - addToMapW(0xe8, 0x0E, 0x48); - addToMapW(0xe8, 0x22, 0x05); - addToMapW(0xe8, 0xFE, 0xD9); - addToMapW(0xe8, 0xFE, 0xDA); - addToMapW(0xe8, 0xFE, 0xDB); - addToMapW(0xe8, 0xFE, 0xDC); - addToMapW(0xe9, 0x00, 0xDA); - addToMapW(0xe9, 0x00, 0xFA); - addToMapW(0xe9, 0x03, 0x98); - addToMapW(0xe9, 0x06, 0x44); - addToMapW(0xe9, 0x0E, 0x49); - addToMapW(0xe9, 0xFE, 0xDD); - addToMapW(0xe9, 0xFE, 0xDE); - addToMapW(0xe9, 0xFE, 0xDF); - addToMapW(0xe9, 0xFE, 0xE0); - addToMapW(0xea, 0x00, 0xDB); - addToMapW(0xea, 0x00, 0xFB); - addToMapW(0xea, 0x01, 0x3B); - addToMapW(0xea, 0x01, 0x3C); - addToMapW(0xea, 0x03, 0x86); - addToMapW(0xea, 0x03, 0xA9); - addToMapW(0xea, 0x03, 0xAC); - addToMapW(0xea, 0x04, 0x16); - addToMapW(0xea, 0x04, 0x36); - addToMapW(0xea, 0x06, 0x45); - addToMapW(0xea, 0x0E, 0x4A); - addToMapW(0xea, 0x21, 0x26); - addToMapW(0xea, 0xFE, 0xE1); - addToMapW(0xea, 0xFE, 0xE2); - addToMapW(0xea, 0xFE, 0xE3); - addToMapW(0xea, 0xFE, 0xE4); - addToMapW(0xeb, 0x00, 0xD9); - addToMapW(0xeb, 0x00, 0xF9); - addToMapW(0xeb, 0x01, 0x70); - addToMapW(0xeb, 0x01, 0x71); - addToMapW(0xeb, 0x03, 0x88); - addToMapW(0xeb, 0x03, 0x94); - addToMapW(0xeb, 0x03, 0xAD); - addToMapW(0xeb, 0x03, 0xB4); - addToMapW(0xeb, 0x06, 0x46); - addToMapW(0xeb, 0x0E, 0x4B); - addToMapW(0xeb, 0xFE, 0xE5); - addToMapW(0xeb, 0xFE, 0xE6); - addToMapW(0xeb, 0xFE, 0xE7); - addToMapW(0xeb, 0xFE, 0xE8); - addToMapW(0xec, 0x03, 0x01); - addToMapW(0xec, 0x03, 0x89); - addToMapW(0xec, 0x03, 0xAE); - addToMapW(0xec, 0x04, 0x12); - addToMapW(0xec, 0x04, 0x32); - addToMapW(0xec, 0x06, 0x47); - addToMapW(0xec, 0x0E, 0x4C); - addToMapW(0xec, 0x22, 0x1E); - addToMapW(0xec, 0xFE, 0xE9); - addToMapW(0xec, 0xFE, 0xEA); - addToMapW(0xec, 0xFE, 0xEB); - addToMapW(0xec, 0xFE, 0xEC); - addToMapW(0xed, 0x00, 0xDD); - addToMapW(0xed, 0x00, 0xFD); - addToMapW(0xed, 0x01, 0x12); - addToMapW(0xed, 0x01, 0x13); - addToMapW(0xed, 0x03, 0x8A); - addToMapW(0xed, 0x03, 0xAF); - addToMapW(0xed, 0x06, 0x48); - addToMapW(0xed, 0x0E, 0x4D); - addToMapW(0xed, 0xFE, 0xED); - addToMapW(0xed, 0xFE, 0xEE); - addToMapW(0xee, 0x00, 0xAF); - addToMapW(0xee, 0x01, 0x45); - addToMapW(0xee, 0x01, 0x46); - addToMapW(0xee, 0x03, 0x04); - addToMapW(0xee, 0x03, 0x05); - addToMapW(0xee, 0x03, 0x8C); - addToMapW(0xee, 0x03, 0x95); - addToMapW(0xee, 0x03, 0xB5); - addToMapW(0xee, 0x03, 0xCC); - addToMapW(0xee, 0x04, 0x2C); - addToMapW(0xee, 0x04, 0x4C); - addToMapW(0xee, 0x06, 0x49); - addToMapW(0xee, 0x0E, 0x4E); - addToMapW(0xee, 0xFE, 0xEF); - addToMapW(0xee, 0xFE, 0xF0); - addToMapW(0xef, 0x00, 0xB4); - addToMapW(0xef, 0x02, 0xB9); - addToMapW(0xef, 0x02, 0xCA); - addToMapW(0xef, 0x03, 0x01); - addToMapW(0xef, 0x03, 0x8E); - addToMapW(0xef, 0x03, 0xCD); - addToMapW(0xef, 0x06, 0x4A); - addToMapW(0xef, 0x0E, 0x4F); - addToMapW(0xef, 0x20, 0x19); - addToMapW(0xef, 0x20, 0x32); - addToMapW(0xef, 0x20, 0x35); - addToMapW(0xef, 0x21, 0x16); - addToMapW(0xef, 0x22, 0x29); - addToMapW(0xef, 0xFE, 0xF1); - addToMapW(0xef, 0xFE, 0xF2); - addToMapW(0xef, 0xFE, 0xF3); - addToMapW(0xef, 0xFE, 0xF4); - addToMapW(0xf0, 0x00, 0xAD); - addToMapW(0xf0, 0x03, 0x8F); - addToMapW(0xf0, 0x03, 0xCE); - addToMapW(0xf0, 0x04, 0x01); - addToMapW(0xf0, 0x04, 0x51); - addToMapW(0xf0, 0x0E, 0x50); - addToMapW(0xf0, 0x22, 0x61); - addToMapW(0xf1, 0x00, 0xB1); - addToMapW(0xf1, 0x02, 0xDD); - addToMapW(0xf1, 0x06, 0x4B); - addToMapW(0xf1, 0x0E, 0x51); - addToMapW(0xf1, 0x22, 0x13); - addToMapW(0xf1, 0xFE, 0x70); - addToMapW(0xf1, 0xFE, 0x71); - addToMapW(0xf2, 0x02, 0xDB); - addToMapW(0xf2, 0x03, 0x23); - addToMapW(0xf2, 0x04, 0x04); - addToMapW(0xf2, 0x04, 0x2B); - addToMapW(0xf2, 0x04, 0x4B); - addToMapW(0xf2, 0x04, 0x54); - addToMapW(0xf2, 0x06, 0x4C); - addToMapW(0xf2, 0x0E, 0x52); - addToMapW(0xf2, 0x20, 0x17); - addToMapW(0xf2, 0x20, 0x1C); - addToMapW(0xf2, 0x22, 0x65); - addToMapW(0xf2, 0xF8, 0xBD); - addToMapW(0xf2, 0xFE, 0x72); - addToMapW(0xf3, 0x00, 0xBE); - addToMapW(0xf3, 0x02, 0xC7); - addToMapW(0xf3, 0x03, 0x0C); - addToMapW(0xf3, 0x06, 0x4D); - addToMapW(0xf3, 0x0E, 0x53); - addToMapW(0xf3, 0x22, 0x64); - addToMapW(0xf3, 0xFE, 0x74); - addToMapW(0xf4, 0x00, 0xB6); - addToMapW(0xf4, 0x02, 0xD8); - addToMapW(0xf4, 0x03, 0x06); - addToMapW(0xf4, 0x03, 0xAA); - addToMapW(0xf4, 0x03, 0xCA); - addToMapW(0xf4, 0x04, 0x07); - addToMapW(0xf4, 0x04, 0x17); - addToMapW(0xf4, 0x04, 0x37); - addToMapW(0xf4, 0x04, 0x57); - addToMapW(0xf4, 0x06, 0x4E); - addToMapW(0xf4, 0x0E, 0x54); - addToMapW(0xf4, 0x23, 0x20); - addToMapW(0xf4, 0xFE, 0x76); - addToMapW(0xf4, 0xFE, 0x77); - addToMapW(0xf5, 0x00, 0xA7); - addToMapW(0xf5, 0x03, 0xAB); - addToMapW(0xf5, 0x03, 0xCB); - addToMapW(0xf5, 0x06, 0x4F); - addToMapW(0xf5, 0x0E, 0x55); - addToMapW(0xf5, 0x23, 0x21); - addToMapW(0xf5, 0xFE, 0x78); - addToMapW(0xf5, 0xFE, 0x79); - addToMapW(0xf6, 0x00, 0xF7); - addToMapW(0xf6, 0x04, 0x0E); - addToMapW(0xf6, 0x04, 0x28); - addToMapW(0xf6, 0x04, 0x48); - addToMapW(0xf6, 0x04, 0x5E); - addToMapW(0xf6, 0x06, 0x50); - addToMapW(0xf6, 0x0E, 0x56); - addToMapW(0xf6, 0xFE, 0x7A); - addToMapW(0xf6, 0xFE, 0x7B); - addToMapW(0xf7, 0x00, 0xB8); - addToMapW(0xf7, 0x00, 0xF7); - addToMapW(0xf7, 0x02, 0xDB); - addToMapW(0xf7, 0x03, 0x27); - addToMapW(0xf7, 0x0E, 0x57); - addToMapW(0xf7, 0x20, 0x1E); - addToMapW(0xf7, 0x22, 0x48); - addToMapW(0xf8, 0x00, 0xB0); - addToMapW(0xf8, 0x02, 0xDA); - addToMapW(0xf8, 0x03, 0x0A); - addToMapW(0xf8, 0x04, 0x2D); - addToMapW(0xf8, 0x04, 0x4D); - addToMapW(0xf8, 0x0E, 0x58); - addToMapW(0xf8, 0x20, 0x70); - addToMapW(0xf8, 0x22, 0x18); - addToMapW(0xf9, 0x00, 0xA8); - addToMapW(0xf9, 0x02, 0xDD); - addToMapW(0xf9, 0x03, 0x08); - addToMapW(0xf9, 0x0E, 0x59); - addToMapW(0xf9, 0x22, 0x19); - addToMapW(0xfa, 0x00, 0xB7); - addToMapW(0xfa, 0x02, 0xD9); - addToMapW(0xfa, 0x03, 0x07); - addToMapW(0xfa, 0x04, 0x29); - addToMapW(0xfa, 0x04, 0x49); - addToMapW(0xfa, 0x0E, 0x5A); - addToMapW(0xfa, 0x20, 0x24); - addToMapW(0xfa, 0x22, 0xC5); - addToMapW(0xfa, 0x30, 0xFB); - addToMapW(0xfb, 0x00, 0xB9); - addToMapW(0xfb, 0x0E, 0x5B); - addToMapW(0xfb, 0x20, 0x81); - addToMapW(0xfb, 0x22, 0x1A); - addToMapW(0xfb, 0x27, 0x13); - addToMapW(0xfc, 0x00, 0xB3); - addToMapW(0xfc, 0x01, 0x58); - addToMapW(0xfc, 0x01, 0x59); - addToMapW(0xfc, 0x04, 0x27); - addToMapW(0xfc, 0x04, 0x47); - addToMapW(0xfc, 0x20, 0x7F); - addToMapW(0xfc, 0x20, 0x83); - addToMapW(0xfc, 0x21, 0x16); - addToMapW(0xfc, 0xF8, 0xC5); - addToMapW(0xfd, 0x00, 0xA4); - addToMapW(0xfd, 0x00, 0xA7); - addToMapW(0xfd, 0x00, 0xB2); - addToMapW(0xfd, 0x20, 0x82); - addToMapW(0xfd, 0xF8, 0xC6); - addToMapW(0xfd, 0xF8, 0xF1); - addToMapW(0xfe, 0x20, 0xAB); - addToMapW(0xfe, 0x25, 0xA0); - addToMapW(0xfe, 0xF8, 0xC7); - addToMapW(0xfe, 0xF8, 0xF2); - addToMapW(0xff, 0x00, 0xA0); - addToMapW(0xff, 0xF8, 0xC8); - addToMapW(0xff, 0xF8, 0xF3); -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "lm2ntlm.h" + +LM2NTLMcorrector::LM2NTLMcorrector() +{ + progressCurrentCombination = 0; + totalCurrentCombination = 1; + counterOverall = 0; + countCombinations = 0; + countTotalCombinations = 0; + counter = 0; + fillMapW(); + aborting = false; + sBinary = ""; + +} + +string LM2NTLMcorrector::getBinary() +{ + return sBinary; +} + +bool LM2NTLMcorrector::LMPasswordCorrectUnicode(string hexPassword, unsigned char* pNTLMHash, string& sNTLMPassword) //, unsigned char* pLMPassword +{ + string sPlain = ""; + + UINT4 i; + for (i = 0; i < hexPassword.size() / 2; i++) + { + string sSub = hexPassword.substr(i * 2, 2); + int nValue; + sscanf(sSub.c_str(), "%02x", &nValue); + sPlain += (unsigned char)nValue; + } + + memcpy(NTLMHash, pNTLMHash, MD4_DIGEST_LENGTH); + + + unsigned long int tmpLength = sPlain.size() * 2; + unsigned char* pLMPassword = new unsigned char[tmpLength]; + + //printf("Searching for unicode password.\n"); + printf("Failed case correction, trying unicode correction for: %s\n", sPlain.c_str()); + //printf("NTLM hash: %s\n\n", sNTLMHash.c_str()); + + setvbuf(stdout, NULL, _IONBF,0); + + startClock = clock(); + previousClock = clock(); + +#ifndef _WIN32 + tty_init(); +#endif + + if (startCorrecting(sPlain, sNTLMPassword, pLMPassword)) + { + sBinary = ByteToStr(pLMPassword, tmpLength).c_str(); + //printf("\nFound unicode password: %s\n", sNTLMPassword.c_str()); + //printf("Password in hex: %s\n", sBinary.c_str()); + writeEndStats(); +#ifndef _WIN32 + tty_done(); +#endif + return true; + } + else + { + //printf("\ncase correction for password %s fail!\n", sPlain.c_str()); + writeEndStats(); +#ifndef _WIN32 + tty_done(); +#endif + return false; + } +} + +bool LM2NTLMcorrector::startCorrecting(string sLMPassword, string& sNTLMPassword, unsigned char* pLMPassword) +{ + if (sLMPassword.size() == 0) + { + sNTLMPassword = ""; + return true; + } + + string muteMe = sLMPassword; + int length = muteMe.size(); + + unsigned char* pMuteMe = new unsigned char[length]; + unsigned char* pTempMute = new unsigned char[length * 2]; + + int i; + for (i = 0; i < length; i++) + { + pMuteMe[i] = muteMe[i]; + pTempMute[i * 2 ] = muteMe[i]; + pTempMute[i * 2 + 1] = 0x00; + unsigned char muteChar = pMuteMe[i]; + int sizeMapForChar = m_mapChar[muteChar].size(); + int j; + for (j = 0; j < sizeMapForChar; j++) + { + currentCharmap[i][j] = m_mapChar[muteChar][j]; + } + } + + int* jAtPos = new int[length]; + int* sizeAtPos = new int[length]; + bool* fullAtPos = new bool[length]; + + int setSize; + for (setSize = 0; setSize <= length; setSize++) + { + int cntFull = 0; + + // clear all 'fullatpos' before new setSize + int i; + for (i=0; i < length; i++) + { + fullAtPos[i] = false; + } + + //printf("Trying full unicode map for %d/%d characters...\t\t\n", setSize, length); + printf("Trying full unicode map for %d/%d characters...%-20s\n", setSize, length, ""); + + bool notFirst = true; + + // start at end and set 'full' combination + countCombinations = 0; + countTotalCombinations = calculateTotalCombinations(length, setSize); + + int sPos = length - 1; + while (sPos >= 0 && notFirst) // finding combinations for current 'setSize' + { + if (aborting) + return false; + + if (cntFull < setSize) + { + if (fullAtPos[sPos] == false) + { + fullAtPos[sPos] = true; + cntFull++; + } + sPos--; + } + else + { + if (fullAtPos[sPos] == false && setSize > 0) + { + fullAtPos[sPos] = true; + cntFull++; + + // reset positions after sPos + int k; + for (k = sPos+1; k < length; k++) + { + if (fullAtPos[k] == true) + { + fullAtPos[k] = false; + cntFull--; + } + } + // start at end again + sPos = length - 1; + } + else + { + sPos--; + } + } + // we have a combination + if (cntFull == setSize) + { + countCombinations++; + + setupCombinationAtPositions(length, pMuteMe, pTempMute, jAtPos, fullAtPos, sizeAtPos); + + if (checkPermutations(length, pTempMute, jAtPos, sizeAtPos, pLMPassword, sNTLMPassword)) + { + return true; + } + } + + if (setSize == 0) + notFirst = false; + } + } + return false; +} + +// set up combination at positions +void LM2NTLMcorrector::setupCombinationAtPositions(int length, unsigned char* pMuteMe, unsigned char* pTempMute, int* jAtPos, bool* fullAtPos, int* sizeAtPos) +{ + progressCurrentCombination = 0; + totalCurrentCombination = 1; + + int i; + for (i=0; i < length; i++) + { + pTempMute[i*2] = currentCharmap[i][0]; + pTempMute[i*2+1] = currentCharmap[i][1]; // reset to first char in map + + jAtPos[i] = 0; // reset charcounter for this char (that is all chars) + + // based on combination, set full map or only upper/lowercase + if (fullAtPos[i] == true) + { + unsigned char muteChar = pMuteMe[i]; + long unsigned int sizeMapForChar = m_mapChar[muteChar].size()/2; // 2 bytes per char + sizeAtPos[i] = sizeMapForChar; + } + else + { + sizeAtPos[i] = 2; + } + + totalCurrentCombination *= sizeAtPos[i]; + } + //printf("Trying %I64u passwords for current combination\t\t\r", totalCurrentCombination); +} + +// go check all permutations for this combination +bool LM2NTLMcorrector::checkPermutations(int length, unsigned char* pTempMute, int* jAtPos, int* sizeAtPos, unsigned char* pLMPassword, string& sNTLMPassword) +{ + int pos = length - 1; + + while (pos >= 0) + { + counter++; + + pos = length - 1; + + int jAtCurPos = jAtPos[pos]; + int sizeMapForCharPos = sizeAtPos[pos]; + // move to start of string and find character with permutations left + while (jAtCurPos >= sizeMapForCharPos-1 && pos >= -1) + { + pos--; + if (pos >= 0 ) + { + jAtCurPos = jAtPos[pos]; + sizeMapForCharPos = sizeAtPos[pos]; + } + } + if (pos < 0) + continue; + + // next permutation for character + jAtCurPos++; + jAtPos[pos] = jAtCurPos; + + pTempMute[pos*2] = currentCharmap[pos][jAtCurPos*2]; + pTempMute[pos*2+1] = currentCharmap[pos][jAtCurPos*2+1]; + + // reset positions after pos + int k; + for (k = pos+1; k < length; k++) + { + jAtPos[k] = 0; + pTempMute[k*2] = currentCharmap[k][0]; // reset to first char in map + pTempMute[k*2+1] = currentCharmap[k][1]; + } + + if (checkNTLMPassword(pTempMute, length, sNTLMPassword) == true) + { + int i; + for (i = 0; i < length*2; i++) + pLMPassword[i] = pTempMute[i]; + return true; + } + + if (counter > 10000) // don't check clocks too often + { + clock_t currentClock = clock(); + float fTime = 1.0f * (currentClock - previousClock); + if (fTime > 1.0f * CLOCKS_PER_SEC) + { + float progressPercentageCurrentCombination = progressCurrentCombination * 100.0f / totalCurrentCombination; + float fTime = 1.0f * (currentClock - startClock) / CLOCKS_PER_SEC; + float currentSpeed = (counterOverall + progressCurrentCombination) / fTime / 1000000; + + //printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)\t\t\t\t\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed); + printf("%.2f%% of combination %d/%d (%.2f Mhashes/s)%-30s\r", progressPercentageCurrentCombination, countCombinations, countTotalCombinations, currentSpeed, ""); + + previousClock = clock(); + #ifdef _WIN32 + if (_kbhit()) + { + int ch = _getch(); + ch = toupper(ch); + if (ch == 'S') + { + aborting = true; + printf( "\nAborting unicode correction for this hash...\n"); + } + else + { + printf( "\nPress 'S' to skip unicode correction for this hash...\n"); + } + } + #else + int c = tty_getchar(); + if (c >= 0) { + tty_flush(); + if (c==115) { // = s + aborting = true; + printf( "\nAborting unicode correction for this hash...\n"); + } + else { + printf( "\nPress 's' to skip unicode correction for this hash...\n"); + } + } + #endif + if (aborting) + return false; + } + counter = 0; + } + + progressCurrentCombination++; + counterOverall++; + } + return false; +} + +// check password, maybe integrate this function in checkPermutations() for performance reasons. +bool LM2NTLMcorrector::checkNTLMPassword(unsigned char* pLMPassword, int nLMPasswordLen, string& sNTLMPassword) +{ + unsigned char md[MD4_DIGEST_LENGTH]; + + //MD4(pLMPassword, nLMPasswordLen * 2, md); + /* + MD4_CTX ctx; + MD4_Init(&ctx); + MD4_Update(&ctx, pLMPassword, nLMPasswordLen * 2); + MD4_Final(md, &ctx);*/ + + MD4_NEW( pLMPassword, nLMPasswordLen * 2, md ); + + if (memcmp(md, NTLMHash, MD4_DIGEST_LENGTH) == 0) + { + sNTLMPassword = ""; + int i; + for (i = 0; i < nLMPasswordLen; i++) { + sNTLMPassword += char(pLMPassword[i * 2]); + } + return true; + } + else + return false; +} + +void LM2NTLMcorrector::checkAbort() +{ +#ifdef _WIN32 + if (_kbhit()) + { + int ch = _getch(); + ch = toupper(ch); + if (ch == 'S') + { + aborting = true; + printf( "\nAborting unicode correction for this hash...\n"); + } + else + { + printf( "\nPress 'S' to skip unicode correction for this hash...\n"); + } + } +#endif +} + +void LM2NTLMcorrector::writeEndStats() +{ + clock_t endClock = clock(); + if (endClock - startClock > 0) + { + float fTime = 1.0f * (endClock - startClock) / CLOCKS_PER_SEC; + float speedOverall = counterOverall / fTime / 1000000; + printf("\nTried %s passwords in %.2f s (%.2f Mhashes/s)\n", uint64tostr(counterOverall).c_str(), fTime, speedOverall); + } + + printf("\n"); +} + +int LM2NTLMcorrector::calculateTotalCombinations(int length, int setSize) +{ + return factorial(length) / (factorial(setSize) * factorial(length-setSize)); +} + +int LM2NTLMcorrector::factorial (int num) +{ + int result = 1; + int i; + for (i = 1; i <= num; ++i) + result *= i; + return result; +} + +// convert some bytes into a string +string LM2NTLMcorrector::ByteToStr(const unsigned char* pData, int nLen) +{ + string sRet = ""; + int i; + for (i = 0; i < nLen/2; i++) + { + char szByte[3]; + sprintf(szByte, "%02x", pData[i*2+1]); // swap 2-byte characters again + sRet += szByte; + sprintf(szByte, "%02x", pData[i*2]); + sRet += szByte; + } + + return sRet; +} + +void LM2NTLMcorrector::addToMapW(unsigned char key, unsigned char value1, unsigned char value2) +{ + unsigned long int cnt = m_mapChar[key].size(); + m_mapChar[key][cnt] = value2; + m_mapChar[key][cnt+1] = value1; //reverse for endiannes +} + +// construct the mappings, would be nicer in a separate (importable) file +void LM2NTLMcorrector::fillMapW() +{ + addToMapW(0x01, 0x00, 0x01); + addToMapW(0x01, 0x26, 0x3A); + addToMapW(0x02, 0x00, 0x02); + addToMapW(0x02, 0x26, 0x3B); + addToMapW(0x03, 0x00, 0x03); + addToMapW(0x03, 0x26, 0x65); + addToMapW(0x04, 0x00, 0x04); + addToMapW(0x04, 0x26, 0x66); + addToMapW(0x05, 0x00, 0x05); + addToMapW(0x05, 0x26, 0x63); + addToMapW(0x06, 0x00, 0x06); + addToMapW(0x06, 0x26, 0x60); + addToMapW(0x07, 0x00, 0x07); + addToMapW(0x07, 0x00, 0xB7); + addToMapW(0x07, 0x20, 0x22); + addToMapW(0x07, 0x20, 0x24); + addToMapW(0x07, 0x20, 0x26); + addToMapW(0x07, 0x22, 0x19); + addToMapW(0x07, 0x22, 0xC5); + addToMapW(0x07, 0x30, 0xFB); + addToMapW(0x08, 0x00, 0x08); + addToMapW(0x08, 0x25, 0xD8); + addToMapW(0x09, 0x00, 0x09); + addToMapW(0x09, 0x20, 0xDD); + addToMapW(0x09, 0x25, 0xCB); + addToMapW(0x09, 0x30, 0x07); + addToMapW(0x0a, 0x00, 0x0A); + addToMapW(0x0a, 0x25, 0xD9); + addToMapW(0x0b, 0x00, 0x0B); + addToMapW(0x0b, 0x26, 0x42); + addToMapW(0x0c, 0x00, 0x0C); + addToMapW(0x0c, 0x26, 0x40); + addToMapW(0x0d, 0x00, 0x0D); + addToMapW(0x0d, 0x26, 0x6A); + addToMapW(0x0e, 0x00, 0x0E); + addToMapW(0x0e, 0x26, 0x6B); + addToMapW(0x0f, 0x00, 0x0F); + addToMapW(0x0f, 0x00, 0xA4); + addToMapW(0x0f, 0x26, 0x3C); + addToMapW(0x10, 0x00, 0x10); + addToMapW(0x10, 0x25, 0xBA); + addToMapW(0x11, 0x00, 0x11); + addToMapW(0x11, 0x25, 0xC4); + addToMapW(0x12, 0x00, 0x12); + addToMapW(0x12, 0x21, 0x95); + addToMapW(0x13, 0x00, 0x13); + addToMapW(0x13, 0x20, 0x3C); + addToMapW(0x14, 0x00, 0x14); + addToMapW(0x14, 0x00, 0xB6); + addToMapW(0x15, 0x00, 0x15); + addToMapW(0x15, 0x00, 0xA7); + addToMapW(0x16, 0x00, 0x16); + addToMapW(0x16, 0x02, 0xC9); + addToMapW(0x16, 0x25, 0xAC); + addToMapW(0x17, 0x00, 0x17); + addToMapW(0x17, 0x21, 0xA8); + addToMapW(0x18, 0x00, 0x18); + addToMapW(0x18, 0x21, 0x91); + addToMapW(0x19, 0x00, 0x19); + addToMapW(0x19, 0x21, 0x93); + addToMapW(0x1a, 0x00, 0x1A); + addToMapW(0x1a, 0x21, 0x92); + addToMapW(0x1b, 0x00, 0x1B); + addToMapW(0x1b, 0x21, 0x90); + addToMapW(0x1c, 0x00, 0x1C); + addToMapW(0x1c, 0x22, 0x1F); + addToMapW(0x1d, 0x00, 0x1D); + addToMapW(0x1d, 0x21, 0x94); + addToMapW(0x1e, 0x00, 0x1E); + addToMapW(0x1e, 0x25, 0xB2); + addToMapW(0x1f, 0x00, 0x1F); + addToMapW(0x1f, 0x25, 0xBC); + addToMapW(0x20, 0x00, 0x20); + addToMapW(0x20, 0x20, 0x00); + addToMapW(0x20, 0x20, 0x01); + addToMapW(0x20, 0x20, 0x02); + addToMapW(0x20, 0x20, 0x03); + addToMapW(0x20, 0x20, 0x04); + addToMapW(0x20, 0x20, 0x05); + addToMapW(0x20, 0x20, 0x06); + addToMapW(0x20, 0x30, 0x00); + addToMapW(0x21, 0x00, 0x21); + addToMapW(0x21, 0x00, 0xA1); + addToMapW(0x21, 0x01, 0xC3); + addToMapW(0x21, 0xFF, 0x01); + addToMapW(0x22, 0x00, 0x22); + addToMapW(0x22, 0x00, 0xA8); + addToMapW(0x22, 0x02, 0xBA); + addToMapW(0x22, 0x03, 0x08); + addToMapW(0x22, 0x03, 0x0E); + addToMapW(0x22, 0x20, 0x1C); + addToMapW(0x22, 0x20, 0x1D); + addToMapW(0x22, 0x20, 0x1E); + addToMapW(0x22, 0x20, 0x33); + addToMapW(0x22, 0x20, 0x35); + addToMapW(0x22, 0x27, 0x5D); + addToMapW(0x22, 0x27, 0x5E); + addToMapW(0x22, 0x30, 0x1D); + addToMapW(0x22, 0x30, 0x1E); + addToMapW(0x22, 0x30, 0x1F); + addToMapW(0x22, 0xFF, 0x02); + addToMapW(0x23, 0x00, 0x23); + addToMapW(0x23, 0xFF, 0x03); + addToMapW(0x24, 0x00, 0x24); + addToMapW(0x24, 0xFF, 0x04); + addToMapW(0x25, 0x00, 0x25); + addToMapW(0x25, 0x06, 0x6A); + addToMapW(0x25, 0x20, 0x30); + addToMapW(0x25, 0xFF, 0x05); + addToMapW(0x26, 0x00, 0x26); + addToMapW(0x26, 0xFF, 0x06); + addToMapW(0x27, 0x00, 0x27); + addToMapW(0x27, 0x00, 0xB4); + addToMapW(0x27, 0x02, 0xB9); + addToMapW(0x27, 0x02, 0xBB); + addToMapW(0x27, 0x02, 0xBC); + addToMapW(0x27, 0x02, 0xC8); + addToMapW(0x27, 0x02, 0xCA); + addToMapW(0x27, 0x02, 0xCB); + addToMapW(0x27, 0x03, 0x00); + addToMapW(0x27, 0x03, 0x01); + addToMapW(0x27, 0x20, 0x18); + addToMapW(0x27, 0x20, 0x19); + addToMapW(0x27, 0x20, 0x1A); + addToMapW(0x27, 0x20, 0x32); + addToMapW(0x27, 0x27, 0x5B); + addToMapW(0x27, 0x27, 0x5C); + addToMapW(0x27, 0xFF, 0x07); + addToMapW(0x28, 0x00, 0x28); + addToMapW(0x28, 0x23, 0x20); + addToMapW(0x28, 0xFF, 0x08); + addToMapW(0x29, 0x00, 0x29); + addToMapW(0x29, 0x23, 0x21); + addToMapW(0x29, 0xFF, 0x09); + addToMapW(0x2a, 0x00, 0x2A); + addToMapW(0x2a, 0x22, 0x17); + addToMapW(0x2a, 0xFF, 0x0A); + addToMapW(0x2b, 0x00, 0x2B); + addToMapW(0x2b, 0x00, 0xB1); + addToMapW(0x2b, 0x20, 0x20); + addToMapW(0x2b, 0x20, 0x21); + addToMapW(0x2b, 0xFF, 0x0B); + addToMapW(0x2c, 0x00, 0x2C); + addToMapW(0x2c, 0x00, 0xB8); + addToMapW(0x2c, 0x03, 0x27); + addToMapW(0x2c, 0x20, 0x1A); + addToMapW(0x2c, 0x20, 0x1E); + addToMapW(0x2c, 0xFF, 0x0C); + addToMapW(0x2d, 0x00, 0x2D); + addToMapW(0x2d, 0x00, 0xAC); + addToMapW(0x2d, 0x00, 0xAD); + addToMapW(0x2d, 0x20, 0x10); + addToMapW(0x2d, 0x20, 0x11); + addToMapW(0x2d, 0x20, 0x13); + addToMapW(0x2d, 0x20, 0x14); + addToMapW(0x2d, 0x22, 0x12); + addToMapW(0x2d, 0x22, 0x13); + addToMapW(0x2d, 0xFF, 0x0D); + addToMapW(0x2e, 0x00, 0x2E); + addToMapW(0x2e, 0x20, 0x26); + addToMapW(0x2e, 0xFF, 0x0E); + addToMapW(0x2f, 0x00, 0x2F); + addToMapW(0x2f, 0x20, 0x44); + addToMapW(0x2f, 0x22, 0x15); + addToMapW(0x2f, 0x22, 0x16); + addToMapW(0x2f, 0xFF, 0x0F); + addToMapW(0x30, 0x00, 0x30); + addToMapW(0x30, 0x20, 0x70); + addToMapW(0x30, 0x20, 0x80); + addToMapW(0x30, 0xFF, 0x10); + addToMapW(0x31, 0x00, 0x31); + addToMapW(0x31, 0x00, 0xB9); + addToMapW(0x31, 0x00, 0xBC); + addToMapW(0x31, 0x00, 0xBD); + addToMapW(0x31, 0x20, 0x81); + addToMapW(0x31, 0xFF, 0x11); + addToMapW(0x32, 0x00, 0x32); + addToMapW(0x32, 0x00, 0xB2); + addToMapW(0x32, 0x20, 0x82); + addToMapW(0x32, 0xFF, 0x12); + addToMapW(0x33, 0x00, 0x33); + addToMapW(0x33, 0x00, 0xB3); + addToMapW(0x33, 0x00, 0xBE); + addToMapW(0x33, 0x20, 0x83); + addToMapW(0x33, 0xFF, 0x13); + addToMapW(0x34, 0x00, 0x34); + addToMapW(0x34, 0x20, 0x74); + addToMapW(0x34, 0x20, 0x84); + addToMapW(0x34, 0xFF, 0x14); + addToMapW(0x35, 0x00, 0x35); + addToMapW(0x35, 0x20, 0x75); + addToMapW(0x35, 0x20, 0x85); + addToMapW(0x35, 0xFF, 0x15); + addToMapW(0x36, 0x00, 0x36); + addToMapW(0x36, 0x20, 0x76); + addToMapW(0x36, 0x20, 0x86); + addToMapW(0x36, 0xFF, 0x16); + addToMapW(0x37, 0x00, 0x37); + addToMapW(0x37, 0x20, 0x77); + addToMapW(0x37, 0x20, 0x87); + addToMapW(0x37, 0xFF, 0x17); + addToMapW(0x38, 0x00, 0x38); + addToMapW(0x38, 0x20, 0x78); + addToMapW(0x38, 0x20, 0x88); + addToMapW(0x38, 0x22, 0x1E); + addToMapW(0x38, 0xFF, 0x18); + addToMapW(0x39, 0x00, 0x39); + addToMapW(0x39, 0x20, 0x78); + addToMapW(0x39, 0x20, 0x89); + addToMapW(0x39, 0xFF, 0x19); + addToMapW(0x3a, 0x00, 0x3A); + addToMapW(0x3a, 0x05, 0x89); + addToMapW(0x3a, 0x20, 0x26); + addToMapW(0x3a, 0x22, 0x36); + addToMapW(0x3a, 0xFF, 0x1A); + addToMapW(0x3b, 0x00, 0x3B); + addToMapW(0x3b, 0x03, 0x7E); + addToMapW(0x3b, 0xFF, 0x1B); + addToMapW(0x3c, 0x00, 0x3C); + addToMapW(0x3c, 0x00, 0xAB); + addToMapW(0x3c, 0x20, 0x39); + addToMapW(0x3c, 0x23, 0x29); + addToMapW(0x3c, 0x30, 0x08); + addToMapW(0x3c, 0xFF, 0x1C); + addToMapW(0x3d, 0x00, 0x3D); + addToMapW(0x3d, 0x22, 0x61); + addToMapW(0x3d, 0x22, 0x64); + addToMapW(0x3d, 0x22, 0x65); + addToMapW(0x3d, 0xFF, 0x1D); + addToMapW(0x3e, 0x00, 0x3E); + addToMapW(0x3e, 0x00, 0xBB); + addToMapW(0x3e, 0x20, 0x3A); + addToMapW(0x3e, 0x23, 0x2A); + addToMapW(0x3e, 0x30, 0x09); + addToMapW(0x3e, 0xFF, 0x1E); + addToMapW(0x3f, 0x00, 0x3F); + addToMapW(0x40, 0x00, 0x40); + addToMapW(0x40, 0xFF, 0x20); + addToMapW(0x41, 0x00, 0x41); + addToMapW(0x41, 0x00, 0x61); + addToMapW(0x41, 0x00, 0xAA); + addToMapW(0x41, 0x00, 0xC0); + addToMapW(0x41, 0x00, 0xC1); + addToMapW(0x41, 0x00, 0xC2); + addToMapW(0x41, 0x00, 0xC3); + addToMapW(0x41, 0x00, 0xC4); + addToMapW(0x41, 0x00, 0xC5); + addToMapW(0x41, 0x00, 0xC6); + addToMapW(0x41, 0x00, 0xE0); + addToMapW(0x41, 0x00, 0xE1); + addToMapW(0x41, 0x00, 0xE2); + addToMapW(0x41, 0x00, 0xE3); + addToMapW(0x41, 0x00, 0xE4); + addToMapW(0x41, 0x00, 0xE5); + addToMapW(0x41, 0x00, 0xE6); + addToMapW(0x41, 0x01, 0x00); + addToMapW(0x41, 0x01, 0x01); + addToMapW(0x41, 0x01, 0x02); + addToMapW(0x41, 0x01, 0x03); + addToMapW(0x41, 0x01, 0x04); + addToMapW(0x41, 0x01, 0x05); + addToMapW(0x41, 0x01, 0xCD); + addToMapW(0x41, 0x01, 0xCE); + addToMapW(0x41, 0x01, 0xDE); + addToMapW(0x41, 0x01, 0xDF); + addToMapW(0x41, 0x03, 0xB1); + addToMapW(0x41, 0x21, 0x2B); + addToMapW(0x41, 0xFF, 0x21); + addToMapW(0x41, 0xFF, 0x41); + addToMapW(0x42, 0x00, 0x42); + addToMapW(0x42, 0x00, 0x62); + addToMapW(0x42, 0x01, 0x80); + addToMapW(0x42, 0x21, 0x2C); + addToMapW(0x42, 0xFF, 0x22); + addToMapW(0x42, 0xFF, 0x42); + addToMapW(0x43, 0x00, 0x43); + addToMapW(0x43, 0x00, 0x63); + addToMapW(0x43, 0x00, 0xA2); + addToMapW(0x43, 0x00, 0xA9); + addToMapW(0x43, 0x00, 0xC7); + addToMapW(0x43, 0x00, 0xE7); + addToMapW(0x43, 0x00, 0xE8); + addToMapW(0x43, 0x01, 0x06); + addToMapW(0x43, 0x01, 0x07); + addToMapW(0x43, 0x01, 0x08); + addToMapW(0x43, 0x01, 0x09); + addToMapW(0x43, 0x01, 0x0A); + addToMapW(0x43, 0x01, 0x0B); + addToMapW(0x43, 0x01, 0x0C); + addToMapW(0x43, 0x01, 0x0D); + addToMapW(0x43, 0x21, 0x02); + addToMapW(0x43, 0x21, 0x2D); + addToMapW(0x43, 0xFF, 0x23); + addToMapW(0x43, 0xFF, 0x43); + addToMapW(0x44, 0x00, 0x44); + addToMapW(0x44, 0x00, 0x64); + addToMapW(0x44, 0x00, 0xD0); + addToMapW(0x44, 0x00, 0xF0); + addToMapW(0x44, 0x01, 0x0E); + addToMapW(0x44, 0x01, 0x0F); + addToMapW(0x44, 0x01, 0x10); + addToMapW(0x44, 0x01, 0x11); + addToMapW(0x44, 0x01, 0x89); + addToMapW(0x44, 0x03, 0xB4); + addToMapW(0x44, 0x26, 0x6A); + addToMapW(0x44, 0x26, 0x6B); + addToMapW(0x44, 0xFF, 0x24); + addToMapW(0x44, 0xFF, 0x44); + addToMapW(0x45, 0x00, 0x45); + addToMapW(0x45, 0x00, 0x65); + addToMapW(0x45, 0x00, 0xC8); + addToMapW(0x45, 0x00, 0xC9); + addToMapW(0x45, 0x00, 0xCA); + addToMapW(0x45, 0x00, 0xCB); + addToMapW(0x45, 0x00, 0xE8); + addToMapW(0x45, 0x00, 0xE9); + addToMapW(0x45, 0x00, 0xEA); + addToMapW(0x45, 0x00, 0xEB); + addToMapW(0x45, 0x01, 0x12); + addToMapW(0x45, 0x01, 0x13); + addToMapW(0x45, 0x01, 0x14); + addToMapW(0x45, 0x01, 0x15); + addToMapW(0x45, 0x01, 0x16); + addToMapW(0x45, 0x01, 0x17); + addToMapW(0x45, 0x01, 0x18); + addToMapW(0x45, 0x01, 0x19); + addToMapW(0x45, 0x01, 0x1A); + addToMapW(0x45, 0x01, 0x1B); + addToMapW(0x45, 0x03, 0xB5); + addToMapW(0x45, 0x21, 0x07); + addToMapW(0x45, 0x21, 0x2E); + addToMapW(0x45, 0x21, 0x2F); + addToMapW(0x45, 0x21, 0x30); + addToMapW(0x45, 0xFF, 0x25); + addToMapW(0x45, 0xFF, 0x45); + addToMapW(0x46, 0x00, 0x46); + addToMapW(0x46, 0x00, 0x66); + addToMapW(0x46, 0x01, 0x91); + addToMapW(0x46, 0x01, 0x92); + addToMapW(0x46, 0x03, 0xA6); + addToMapW(0x46, 0x03, 0xC6); + addToMapW(0x46, 0x21, 0x31); + addToMapW(0x46, 0xFF, 0x26); + addToMapW(0x46, 0xFF, 0x46); + addToMapW(0x47, 0x00, 0x47); + addToMapW(0x47, 0x00, 0x67); + addToMapW(0x47, 0x01, 0x1C); + addToMapW(0x47, 0x01, 0x1D); + addToMapW(0x47, 0x01, 0x1E); + addToMapW(0x47, 0x01, 0x1F); + addToMapW(0x47, 0x01, 0x20); + addToMapW(0x47, 0x01, 0x21); + addToMapW(0x47, 0x01, 0x22); + addToMapW(0x47, 0x01, 0x23); + addToMapW(0x47, 0x01, 0xE4); + addToMapW(0x47, 0x01, 0xE5); + addToMapW(0x47, 0x01, 0xE6); + addToMapW(0x47, 0x01, 0xE7); + addToMapW(0x47, 0x02, 0x61); + addToMapW(0x47, 0x03, 0x93); + addToMapW(0x47, 0x21, 0x0A); + addToMapW(0x47, 0xFF, 0x27); + addToMapW(0x47, 0xFF, 0x47); + addToMapW(0x48, 0x00, 0x48); + addToMapW(0x48, 0x00, 0x68); + addToMapW(0x48, 0x01, 0x24); + addToMapW(0x48, 0x01, 0x25); + addToMapW(0x48, 0x01, 0x26); + addToMapW(0x48, 0x01, 0x27); + addToMapW(0x48, 0x04, 0xBB); + addToMapW(0x48, 0x21, 0x0B); + addToMapW(0x48, 0x21, 0x0C); + addToMapW(0x48, 0x21, 0x0D); + addToMapW(0x48, 0x21, 0x0E); + addToMapW(0x48, 0xFF, 0x28); + addToMapW(0x48, 0xFF, 0x48); + addToMapW(0x49, 0x00, 0x49); + addToMapW(0x49, 0x00, 0x69); + addToMapW(0x49, 0x00, 0xCC); + addToMapW(0x49, 0x00, 0xCD); + addToMapW(0x49, 0x00, 0xCE); + addToMapW(0x49, 0x00, 0xCF); + addToMapW(0x49, 0x00, 0xEC); + addToMapW(0x49, 0x00, 0xED); + addToMapW(0x49, 0x00, 0xEE); + addToMapW(0x49, 0x00, 0xEF); + addToMapW(0x49, 0x01, 0x28); + addToMapW(0x49, 0x01, 0x29); + addToMapW(0x49, 0x01, 0x2A); + addToMapW(0x49, 0x01, 0x2B); + addToMapW(0x49, 0x01, 0x2C); + addToMapW(0x49, 0x01, 0x2D); + addToMapW(0x49, 0x01, 0x2E); + addToMapW(0x49, 0x01, 0x2F); + addToMapW(0x49, 0x01, 0x30); + addToMapW(0x49, 0x01, 0x31); + addToMapW(0x49, 0x01, 0x97); + addToMapW(0x49, 0x01, 0xCF); + addToMapW(0x49, 0x01, 0xD0); + addToMapW(0x49, 0x21, 0x10); + addToMapW(0x49, 0x21, 0x11); + addToMapW(0x49, 0xFF, 0x29); + addToMapW(0x49, 0xFF, 0x49); + addToMapW(0x4a, 0x00, 0x4A); + addToMapW(0x4a, 0x00, 0x6A); + addToMapW(0x4a, 0x01, 0x34); + addToMapW(0x4a, 0x01, 0x35); + addToMapW(0x4a, 0x01, 0xF0); + addToMapW(0x4a, 0xFF, 0x2A); + addToMapW(0x4a, 0xFF, 0x4A); + addToMapW(0x4b, 0x00, 0x4B); + addToMapW(0x4b, 0x00, 0x6B); + addToMapW(0x4b, 0x01, 0x36); + addToMapW(0x4b, 0x01, 0x37); + addToMapW(0x4b, 0x01, 0xE8); + addToMapW(0x4b, 0x01, 0xE9); + addToMapW(0x4b, 0x21, 0x2A); + addToMapW(0x4b, 0xFF, 0x2B); + addToMapW(0x4b, 0xFF, 0x4B); + addToMapW(0x4c, 0x00, 0x4C); + addToMapW(0x4c, 0x00, 0x6C); + addToMapW(0x4c, 0x00, 0xA3); + addToMapW(0x4c, 0x01, 0x39); + addToMapW(0x4c, 0x01, 0x3A); + addToMapW(0x4c, 0x01, 0x3B); + addToMapW(0x4c, 0x01, 0x3C); + addToMapW(0x4c, 0x01, 0x3D); + addToMapW(0x4c, 0x01, 0x3E); + addToMapW(0x4c, 0x01, 0x41); + addToMapW(0x4c, 0x01, 0x42); + addToMapW(0x4c, 0x01, 0x9A); + addToMapW(0x4c, 0x20, 0xA4); + addToMapW(0x4c, 0x21, 0x12); + addToMapW(0x4c, 0x21, 0x13); + addToMapW(0x4c, 0xFF, 0x2C); + addToMapW(0x4c, 0xFF, 0x4C); + addToMapW(0x4d, 0x00, 0x4D); + addToMapW(0x4d, 0x00, 0x6D); + addToMapW(0x4d, 0x21, 0x33); + addToMapW(0x4d, 0xFF, 0x2D); + addToMapW(0x4d, 0xFF, 0x4D); + addToMapW(0x4e, 0x00, 0x4E); + addToMapW(0x4e, 0x00, 0x6E); + addToMapW(0x4e, 0x00, 0xD1); + addToMapW(0x4e, 0x00, 0xF1); + addToMapW(0x4e, 0x01, 0x43); + addToMapW(0x4e, 0x01, 0x44); + addToMapW(0x4e, 0x01, 0x45); + addToMapW(0x4e, 0x01, 0x46); + addToMapW(0x4e, 0x01, 0x47); + addToMapW(0x4e, 0x01, 0x48); + addToMapW(0x4e, 0x20, 0x7F); + addToMapW(0x4e, 0x21, 0x15); + addToMapW(0x4e, 0x22, 0x29); + addToMapW(0x4e, 0xFF, 0x2E); + addToMapW(0x4e, 0xFF, 0x4E); + addToMapW(0x4f, 0x00, 0x4F); + addToMapW(0x4f, 0x00, 0x6F); + addToMapW(0x4f, 0x00, 0xB0); + addToMapW(0x4f, 0x00, 0xBA); + addToMapW(0x4f, 0x00, 0xD2); + addToMapW(0x4f, 0x00, 0xD3); + addToMapW(0x4f, 0x00, 0xD4); + addToMapW(0x4f, 0x00, 0xD5); + addToMapW(0x4f, 0x00, 0xD6); + addToMapW(0x4f, 0x00, 0xD8); + addToMapW(0x4f, 0x00, 0xF2); + addToMapW(0x4f, 0x00, 0xF3); + addToMapW(0x4f, 0x00, 0xF4); + addToMapW(0x4f, 0x00, 0xF5); + addToMapW(0x4f, 0x00, 0xF6); + addToMapW(0x4f, 0x00, 0xF8); + addToMapW(0x4f, 0x01, 0x4C); + addToMapW(0x4f, 0x01, 0x4D); + addToMapW(0x4f, 0x01, 0x4E); + addToMapW(0x4f, 0x01, 0x4F); + addToMapW(0x4f, 0x01, 0x50); + addToMapW(0x4f, 0x01, 0x51); + addToMapW(0x4f, 0x01, 0x52); + addToMapW(0x4f, 0x01, 0x53); + addToMapW(0x4f, 0x01, 0x9F); + addToMapW(0x4f, 0x01, 0xA0); + addToMapW(0x4f, 0x01, 0xA1); + addToMapW(0x4f, 0x01, 0xD1); + addToMapW(0x4f, 0x01, 0xD2); + addToMapW(0x4f, 0x01, 0xEA); + addToMapW(0x4f, 0x01, 0xEB); + addToMapW(0x4f, 0x01, 0xEC); + addToMapW(0x4f, 0x01, 0xED); + addToMapW(0x4f, 0x03, 0xA9); + addToMapW(0x4f, 0x20, 0xDD); + addToMapW(0x4f, 0x21, 0x26); + addToMapW(0x4f, 0x21, 0x34); + addToMapW(0x4f, 0x22, 0x05); + addToMapW(0x4f, 0x30, 0x07); + addToMapW(0x4f, 0xFF, 0x2F); + addToMapW(0x4f, 0xFF, 0x4F); + addToMapW(0x50, 0x00, 0x50); + addToMapW(0x50, 0x00, 0x70); + addToMapW(0x50, 0x03, 0xC0); + addToMapW(0x50, 0x20, 0xA7); + addToMapW(0x50, 0x21, 0x18); + addToMapW(0x50, 0x21, 0x19); + addToMapW(0x50, 0xFF, 0x30); + addToMapW(0x50, 0xFF, 0x50); + addToMapW(0x51, 0x00, 0x51); + addToMapW(0x51, 0x00, 0x71); + addToMapW(0x51, 0x21, 0x1A); + addToMapW(0x51, 0xFF, 0x31); + addToMapW(0x51, 0xFF, 0x51); + addToMapW(0x52, 0x00, 0x52); + addToMapW(0x52, 0x00, 0x72); + addToMapW(0x52, 0x00, 0xAE); + addToMapW(0x52, 0x01, 0x54); + addToMapW(0x52, 0x01, 0x55); + addToMapW(0x52, 0x01, 0x56); + addToMapW(0x52, 0x01, 0x57); + addToMapW(0x52, 0x01, 0x58); + addToMapW(0x52, 0x01, 0x59); + addToMapW(0x52, 0x21, 0x1B); + addToMapW(0x52, 0x21, 0x1C); + addToMapW(0x52, 0x21, 0x1D); + addToMapW(0x52, 0xFF, 0x32); + addToMapW(0x52, 0xFF, 0x52); + addToMapW(0x53, 0x00, 0x53); + addToMapW(0x53, 0x00, 0x73); + addToMapW(0x53, 0x00, 0xDF); + addToMapW(0x53, 0x01, 0x5A); + addToMapW(0x53, 0x01, 0x5B); + addToMapW(0x53, 0x01, 0x5C); + addToMapW(0x53, 0x01, 0x5D); + addToMapW(0x53, 0x01, 0x5E); + addToMapW(0x53, 0x01, 0x5F); + addToMapW(0x53, 0x01, 0x60); + addToMapW(0x53, 0x01, 0x61); + addToMapW(0x53, 0x01, 0xA9); + addToMapW(0x53, 0x03, 0xA3); + addToMapW(0x53, 0x03, 0xC3); + addToMapW(0x53, 0x22, 0x11); + addToMapW(0x53, 0xFF, 0x33); + addToMapW(0x53, 0xFF, 0x53); + addToMapW(0x54, 0x00, 0x54); + addToMapW(0x54, 0x00, 0x74); + addToMapW(0x54, 0x00, 0xDE); + addToMapW(0x54, 0x00, 0xFE); + addToMapW(0x54, 0x01, 0x62); + addToMapW(0x54, 0x01, 0x63); + addToMapW(0x54, 0x01, 0x64); + addToMapW(0x54, 0x01, 0x65); + addToMapW(0x54, 0x01, 0x66); + addToMapW(0x54, 0x01, 0x67); + addToMapW(0x54, 0x01, 0xAB); + addToMapW(0x54, 0x01, 0xAE); + addToMapW(0x54, 0x03, 0xC4); + addToMapW(0x54, 0x21, 0x22); + addToMapW(0x54, 0xFF, 0x34); + addToMapW(0x54, 0xFF, 0x54); + addToMapW(0x55, 0x00, 0x55); + addToMapW(0x55, 0x00, 0x75); + addToMapW(0x55, 0x00, 0xB5); + addToMapW(0x55, 0x00, 0xD9); + addToMapW(0x55, 0x00, 0xDA); + addToMapW(0x55, 0x00, 0xDB); + addToMapW(0x55, 0x00, 0xDC); + addToMapW(0x55, 0x00, 0xF9); + addToMapW(0x55, 0x00, 0xFA); + addToMapW(0x55, 0x00, 0xFB); + addToMapW(0x55, 0x00, 0xFC); + addToMapW(0x55, 0x01, 0x68); + addToMapW(0x55, 0x01, 0x69); + addToMapW(0x55, 0x01, 0x6A); + addToMapW(0x55, 0x01, 0x6B); + addToMapW(0x55, 0x01, 0x6C); + addToMapW(0x55, 0x01, 0x6D); + addToMapW(0x55, 0x01, 0x6E); + addToMapW(0x55, 0x01, 0x6F); + addToMapW(0x55, 0x01, 0x70); + addToMapW(0x55, 0x01, 0x71); + addToMapW(0x55, 0x01, 0x72); + addToMapW(0x55, 0x01, 0x73); + addToMapW(0x55, 0x01, 0xAF); + addToMapW(0x55, 0x01, 0xB0); + addToMapW(0x55, 0x01, 0xD3); + addToMapW(0x55, 0x01, 0xD4); + addToMapW(0x55, 0x01, 0xD5); + addToMapW(0x55, 0x01, 0xD6); + addToMapW(0x55, 0x01, 0xD7); + addToMapW(0x55, 0x01, 0xD8); + addToMapW(0x55, 0x01, 0xD9); + addToMapW(0x55, 0x01, 0xDA); + addToMapW(0x55, 0x01, 0xDB); + addToMapW(0x55, 0x01, 0xDC); + addToMapW(0x55, 0x03, 0xBC); + addToMapW(0x55, 0xFF, 0x35); + addToMapW(0x55, 0xFF, 0x55); + addToMapW(0x56, 0x00, 0x56); + addToMapW(0x56, 0x00, 0x76); + addToMapW(0x56, 0x22, 0x1A); + addToMapW(0x56, 0x27, 0x13); + addToMapW(0x56, 0xFF, 0x36); + addToMapW(0x56, 0xFF, 0x56); + addToMapW(0x57, 0x00, 0x57); + addToMapW(0x57, 0x00, 0x77); + addToMapW(0x57, 0x01, 0x74); + addToMapW(0x57, 0x01, 0x75); + addToMapW(0x57, 0xFF, 0x37); + addToMapW(0x57, 0xFF, 0x57); + addToMapW(0x58, 0x00, 0x58); + addToMapW(0x58, 0x00, 0x78); + addToMapW(0x58, 0x00, 0xD7); + addToMapW(0x58, 0xFF, 0x38); + addToMapW(0x58, 0xFF, 0x58); + addToMapW(0x59, 0x00, 0x59); + addToMapW(0x59, 0x00, 0x79); + addToMapW(0x59, 0x00, 0xA5); + addToMapW(0x59, 0x00, 0xDD); + addToMapW(0x59, 0x00, 0xFD); + addToMapW(0x59, 0x00, 0xFF); + addToMapW(0x59, 0x01, 0x76); + addToMapW(0x59, 0x01, 0x77); + addToMapW(0x59, 0x01, 0x78); + addToMapW(0x59, 0xFF, 0x39); + addToMapW(0x59, 0xFF, 0x59); + addToMapW(0x5a, 0x00, 0x5A); + addToMapW(0x5a, 0x00, 0x7A); + addToMapW(0x5a, 0x01, 0x79); + addToMapW(0x5a, 0x01, 0x7A); + addToMapW(0x5a, 0x01, 0x7B); + addToMapW(0x5a, 0x01, 0x7C); + addToMapW(0x5a, 0x01, 0x7D); + addToMapW(0x5a, 0x01, 0x7E); + addToMapW(0x5a, 0x01, 0xB6); + addToMapW(0x5a, 0x21, 0x24); + addToMapW(0x5a, 0x21, 0x28); + addToMapW(0x5a, 0xFF, 0x3A); + addToMapW(0x5a, 0xFF, 0x5A); + addToMapW(0x5b, 0x00, 0x5B); + addToMapW(0x5b, 0x30, 0x1A); + addToMapW(0x5b, 0xFF, 0x3B); + addToMapW(0x5c, 0x00, 0x5C); + addToMapW(0x5c, 0x00, 0xA5); + addToMapW(0x5c, 0x22, 0x16); + addToMapW(0x5c, 0xFF, 0x3C); + addToMapW(0x5d, 0x00, 0x5D); + addToMapW(0x5d, 0x30, 0x1B); + addToMapW(0x5d, 0xFF, 0x3D); + addToMapW(0x5e, 0x00, 0x5E); + addToMapW(0x5e, 0x02, 0xC4); + addToMapW(0x5e, 0x02, 0xC6); + addToMapW(0x5e, 0x02, 0xC7); + addToMapW(0x5e, 0x02, 0xD8); + addToMapW(0x5e, 0x03, 0x02); + addToMapW(0x5e, 0x03, 0x06); + addToMapW(0x5e, 0x03, 0x0C); + addToMapW(0x5e, 0x23, 0x03); + addToMapW(0x5e, 0xFF, 0x3E); + addToMapW(0x5f, 0x00, 0x5F); + addToMapW(0x5f, 0x00, 0xAF); + addToMapW(0x5f, 0x00, 0xBE); + addToMapW(0x5f, 0x00, 0xDE); + addToMapW(0x5f, 0x00, 0xFE); + addToMapW(0x5f, 0x02, 0xCD); + addToMapW(0x5f, 0x03, 0x31); + addToMapW(0x5f, 0x03, 0x32); + addToMapW(0x5f, 0x20, 0x17); + addToMapW(0x5f, 0x30, 0xFC); + addToMapW(0x5f, 0xFF, 0x3F); + addToMapW(0x60, 0x00, 0x60); + addToMapW(0x60, 0x02, 0xCB); + addToMapW(0x60, 0x03, 0x00); + addToMapW(0x60, 0x20, 0x18); + addToMapW(0x60, 0x20, 0x35); + addToMapW(0x60, 0xFF, 0x40); + addToMapW(0x7b, 0x00, 0x7B); + addToMapW(0x7b, 0xFF, 0x5B); + addToMapW(0x7c, 0x00, 0x7C); + addToMapW(0x7c, 0x00, 0xA6); + addToMapW(0x7c, 0x01, 0xC0); + addToMapW(0x7c, 0x22, 0x23); + addToMapW(0x7c, 0x27, 0x58); + addToMapW(0x7c, 0xFF, 0x5C); + addToMapW(0x7d, 0x00, 0x7D); + addToMapW(0x7d, 0x30, 0x1B); + addToMapW(0x7d, 0xFF, 0x5D); + addToMapW(0x7e, 0x00, 0x7E); + addToMapW(0x7e, 0x02, 0xDC); + addToMapW(0x7e, 0x03, 0x03); + addToMapW(0x7e, 0x22, 0x3C); + addToMapW(0x7e, 0x22, 0x48); + addToMapW(0x7e, 0xFF, 0x5E); + addToMapW(0x7f, 0x00, 0x7F); + addToMapW(0x7f, 0x23, 0x02); + addToMapW(0x7f, 0x26, 0x60); + addToMapW(0x7f, 0x26, 0x63); + addToMapW(0x7f, 0x26, 0x65); + addToMapW(0x7f, 0x26, 0x66); + addToMapW(0x80, 0x00, 0x80); + addToMapW(0x80, 0x00, 0xC7); + addToMapW(0x80, 0x00, 0xE7); + addToMapW(0x80, 0x01, 0x06); + addToMapW(0x80, 0x01, 0x07); + addToMapW(0x80, 0x03, 0x91); + addToMapW(0x80, 0x03, 0xB1); + addToMapW(0x80, 0x04, 0x10); + addToMapW(0x80, 0x04, 0x30); + addToMapW(0x80, 0x05, 0xD0); + addToMapW(0x80, 0x20, 0xAC); + addToMapW(0x81, 0x00, 0x81); + addToMapW(0x81, 0x03, 0x92); + addToMapW(0x81, 0x03, 0xB2); + addToMapW(0x81, 0x04, 0x02); + addToMapW(0x81, 0x04, 0x11); + addToMapW(0x81, 0x04, 0x31); + addToMapW(0x81, 0x04, 0x52); + addToMapW(0x81, 0x05, 0xD1); + addToMapW(0x82, 0x00, 0x82); + addToMapW(0x82, 0x03, 0x93); + addToMapW(0x82, 0x03, 0xB3); + addToMapW(0x82, 0x04, 0x12); + addToMapW(0x82, 0x04, 0x32); + addToMapW(0x82, 0x05, 0xD2); + addToMapW(0x82, 0x20, 0x1A); + addToMapW(0x83, 0x00, 0x83); + addToMapW(0x83, 0x03, 0x94); + addToMapW(0x83, 0x03, 0xB4); + addToMapW(0x83, 0x04, 0x03); + addToMapW(0x83, 0x04, 0x13); + addToMapW(0x83, 0x04, 0x33); + addToMapW(0x83, 0x04, 0x53); + addToMapW(0x83, 0x05, 0xD3); + addToMapW(0x84, 0x00, 0x84); + addToMapW(0x84, 0x03, 0x95); + addToMapW(0x84, 0x03, 0xB5); + addToMapW(0x84, 0x04, 0x14); + addToMapW(0x84, 0x04, 0x34); + addToMapW(0x84, 0x05, 0xD4); + addToMapW(0x84, 0x20, 0x1E); + addToMapW(0x85, 0x03, 0x96); + addToMapW(0x85, 0x03, 0xB6); + addToMapW(0x85, 0x04, 0x01); + addToMapW(0x85, 0x04, 0x15); + addToMapW(0x85, 0x04, 0x35); + addToMapW(0x85, 0x04, 0x51); + addToMapW(0x85, 0x05, 0xD5); + addToMapW(0x85, 0x20, 0x26); + addToMapW(0x86, 0x00, 0x86); + addToMapW(0x86, 0x03, 0x97); + addToMapW(0x86, 0x03, 0xB7); + addToMapW(0x86, 0x04, 0x16); + addToMapW(0x86, 0x04, 0x36); + addToMapW(0x86, 0x05, 0xD6); + addToMapW(0x86, 0x20, 0x20); + addToMapW(0x87, 0x00, 0x87); + addToMapW(0x87, 0x03, 0x98); + addToMapW(0x87, 0x03, 0xB8); + addToMapW(0x87, 0x04, 0x04); + addToMapW(0x87, 0x04, 0x17); + addToMapW(0x87, 0x04, 0x37); + addToMapW(0x87, 0x04, 0x54); + addToMapW(0x87, 0x05, 0xD7); + addToMapW(0x87, 0x20, 0x21); + addToMapW(0x88, 0x00, 0x88); + addToMapW(0x88, 0x02, 0xC6); + addToMapW(0x88, 0x03, 0x99); + addToMapW(0x88, 0x03, 0xB9); + addToMapW(0x88, 0x04, 0x18); + addToMapW(0x88, 0x04, 0x38); + addToMapW(0x88, 0x05, 0xD8); + addToMapW(0x89, 0x00, 0x89); + addToMapW(0x89, 0x03, 0x9A); + addToMapW(0x89, 0x03, 0xBA); + addToMapW(0x89, 0x04, 0x05); + addToMapW(0x89, 0x04, 0x19); + addToMapW(0x89, 0x04, 0x39); + addToMapW(0x89, 0x04, 0x55); + addToMapW(0x89, 0x05, 0xD9); + addToMapW(0x89, 0x20, 0x30); + addToMapW(0x8a, 0x00, 0x8A); + addToMapW(0x8a, 0x01, 0x50); + addToMapW(0x8a, 0x01, 0x51); + addToMapW(0x8a, 0x01, 0x56); + addToMapW(0x8a, 0x01, 0x57); + addToMapW(0x8a, 0x03, 0x9B); + addToMapW(0x8a, 0x03, 0xBB); + addToMapW(0x8a, 0x04, 0x1A); + addToMapW(0x8a, 0x04, 0x3A); + addToMapW(0x8a, 0x05, 0xDA); + addToMapW(0x8b, 0x00, 0x8B); + addToMapW(0x8b, 0x03, 0x9C); + addToMapW(0x8b, 0x03, 0xBC); + addToMapW(0x8b, 0x04, 0x06); + addToMapW(0x8b, 0x04, 0x1B); + addToMapW(0x8b, 0x04, 0x3B); + addToMapW(0x8b, 0x04, 0x56); + addToMapW(0x8b, 0x05, 0xDB); + addToMapW(0x8b, 0x20, 0x39); + addToMapW(0x8c, 0x00, 0x8C); + addToMapW(0x8c, 0x01, 0x52); + addToMapW(0x8c, 0x01, 0x53); + addToMapW(0x8c, 0x03, 0x9D); + addToMapW(0x8c, 0x03, 0xBD); + addToMapW(0x8c, 0x04, 0x1C); + addToMapW(0x8c, 0x04, 0x3C); + addToMapW(0x8c, 0x05, 0xDC); + addToMapW(0x8d, 0x00, 0x8D); + addToMapW(0x8d, 0x01, 0x31); + addToMapW(0x8d, 0x01, 0x79); + addToMapW(0x8d, 0x01, 0x7A); + addToMapW(0x8d, 0x03, 0x9E); + addToMapW(0x8d, 0x03, 0xBE); + addToMapW(0x8d, 0x04, 0x07); + addToMapW(0x8d, 0x04, 0x1D); + addToMapW(0x8d, 0x04, 0x3D); + addToMapW(0x8d, 0x04, 0x57); + addToMapW(0x8d, 0x05, 0xDD); + addToMapW(0x8e, 0x00, 0x8E); + addToMapW(0x8e, 0x00, 0xC4); + addToMapW(0x8e, 0x00, 0xE4); + addToMapW(0x8e, 0x03, 0x9F); + addToMapW(0x8e, 0x03, 0xBF); + addToMapW(0x8e, 0x04, 0x1E); + addToMapW(0x8e, 0x04, 0x3E); + addToMapW(0x8e, 0x05, 0xDE); + addToMapW(0x8f, 0x00, 0x8F); + addToMapW(0x8f, 0x00, 0xC5); + addToMapW(0x8f, 0x00, 0xE5); + addToMapW(0x8f, 0x01, 0x06); + addToMapW(0x8f, 0x01, 0x07); + addToMapW(0x8f, 0x03, 0xA0); + addToMapW(0x8f, 0x03, 0xC0); + addToMapW(0x8f, 0x04, 0x08); + addToMapW(0x8f, 0x04, 0x1F); + addToMapW(0x8f, 0x04, 0x3F); + addToMapW(0x8f, 0x04, 0x58); + addToMapW(0x8f, 0x05, 0xDF); + addToMapW(0x8f, 0x21, 0x2B); + addToMapW(0x90, 0x00, 0x90); + addToMapW(0x90, 0x00, 0xC9); + addToMapW(0x90, 0x00, 0xE9); + addToMapW(0x90, 0x03, 0xA1); + addToMapW(0x90, 0x03, 0xC1); + addToMapW(0x90, 0x04, 0x20); + addToMapW(0x90, 0x04, 0x40); + addToMapW(0x90, 0x05, 0xE0); + addToMapW(0x91, 0x01, 0x39); + addToMapW(0x91, 0x01, 0x3A); + addToMapW(0x91, 0x03, 0xA3); + addToMapW(0x91, 0x03, 0xC2); + addToMapW(0x91, 0x03, 0xC3); + addToMapW(0x91, 0x04, 0x09); + addToMapW(0x91, 0x04, 0x21); + addToMapW(0x91, 0x04, 0x41); + addToMapW(0x91, 0x04, 0x59); + addToMapW(0x91, 0x05, 0xE1); + addToMapW(0x91, 0x06, 0x51); + addToMapW(0x91, 0x20, 0x18); + addToMapW(0x91, 0xFE, 0x7C); + addToMapW(0x91, 0xFE, 0x7D); + addToMapW(0x92, 0x00, 0xC6); + addToMapW(0x92, 0x00, 0xE6); + addToMapW(0x92, 0x03, 0xA4); + addToMapW(0x92, 0x03, 0xC4); + addToMapW(0x92, 0x04, 0x22); + addToMapW(0x92, 0x04, 0x42); + addToMapW(0x92, 0x05, 0xE2); + addToMapW(0x92, 0x06, 0x52); + addToMapW(0x92, 0x20, 0x19); + addToMapW(0x92, 0xFE, 0x7E); + addToMapW(0x92, 0xFE, 0x7F); + addToMapW(0x93, 0x03, 0xA5); + addToMapW(0x93, 0x03, 0xC5); + addToMapW(0x93, 0x04, 0x0A); + addToMapW(0x93, 0x04, 0x23); + addToMapW(0x93, 0x04, 0x43); + addToMapW(0x93, 0x04, 0x5A); + addToMapW(0x93, 0x05, 0xE3); + addToMapW(0x93, 0x20, 0x1C); + addToMapW(0x94, 0x00, 0xA4); + addToMapW(0x94, 0x03, 0xA6); + addToMapW(0x94, 0x03, 0xC6); + addToMapW(0x94, 0x04, 0x24); + addToMapW(0x94, 0x04, 0x44); + addToMapW(0x94, 0x05, 0xE4); + addToMapW(0x94, 0x20, 0x1D); + addToMapW(0x95, 0x01, 0x22); + addToMapW(0x95, 0x01, 0x23); + addToMapW(0x95, 0x01, 0x3D); + addToMapW(0x95, 0x01, 0x3E); + addToMapW(0x95, 0x03, 0xA7); + addToMapW(0x95, 0x03, 0xC7); + addToMapW(0x95, 0x04, 0x0B); + addToMapW(0x95, 0x04, 0x25); + addToMapW(0x95, 0x04, 0x45); + addToMapW(0x95, 0x04, 0x5B); + addToMapW(0x95, 0x05, 0xE5); + addToMapW(0x95, 0x06, 0x40); + addToMapW(0x95, 0x20, 0x22); + addToMapW(0x96, 0x00, 0xA2); + addToMapW(0x96, 0x03, 0xA8); + addToMapW(0x96, 0x03, 0xC8); + addToMapW(0x96, 0x04, 0x26); + addToMapW(0x96, 0x04, 0x46); + addToMapW(0x96, 0x05, 0xE6); + addToMapW(0x96, 0x20, 0x13); + addToMapW(0x97, 0x00, 0xB5); + addToMapW(0x97, 0x01, 0x5A); + addToMapW(0x97, 0x01, 0x5B); + addToMapW(0x97, 0x03, 0xA9); + addToMapW(0x97, 0x03, 0xC9); + addToMapW(0x97, 0x04, 0x0C); + addToMapW(0x97, 0x04, 0x27); + addToMapW(0x97, 0x04, 0x47); + addToMapW(0x97, 0x04, 0x5C); + addToMapW(0x97, 0x05, 0xE7); + addToMapW(0x97, 0x20, 0x14); + addToMapW(0x98, 0x00, 0x98); + addToMapW(0x98, 0x01, 0x30); + addToMapW(0x98, 0x02, 0xDC); + addToMapW(0x98, 0x04, 0x28); + addToMapW(0x98, 0x04, 0x48); + addToMapW(0x98, 0x05, 0xE8); + addToMapW(0x98, 0x06, 0x21); + addToMapW(0x98, 0xFE, 0x80); + addToMapW(0x99, 0x00, 0x99); + addToMapW(0x99, 0x00, 0xD6); + addToMapW(0x99, 0x00, 0xF6); + addToMapW(0x99, 0x04, 0x0E); + addToMapW(0x99, 0x04, 0x29); + addToMapW(0x99, 0x04, 0x49); + addToMapW(0x99, 0x04, 0x5E); + addToMapW(0x99, 0x05, 0xE9); + addToMapW(0x99, 0x06, 0x22); + addToMapW(0x99, 0x21, 0x22); + addToMapW(0x99, 0xFE, 0x81); + addToMapW(0x99, 0xFE, 0x82); + addToMapW(0x9a, 0x00, 0x9A); + addToMapW(0x9a, 0x00, 0xDC); + addToMapW(0x9a, 0x00, 0xFC); + addToMapW(0x9a, 0x04, 0x2A); + addToMapW(0x9a, 0x04, 0x4A); + addToMapW(0x9a, 0x05, 0xEA); + addToMapW(0x9a, 0x06, 0x23); + addToMapW(0x9a, 0xFE, 0x83); + addToMapW(0x9a, 0xFE, 0x84); + addToMapW(0x9b, 0x00, 0x9B); + addToMapW(0x9b, 0x00, 0xA2); + addToMapW(0x9b, 0x01, 0x64); + addToMapW(0x9b, 0x01, 0x65); + addToMapW(0x9b, 0x04, 0x0F); + addToMapW(0x9b, 0x04, 0x2B); + addToMapW(0x9b, 0x04, 0x4B); + addToMapW(0x9b, 0x04, 0x5F); + addToMapW(0x9b, 0x06, 0x24); + addToMapW(0x9b, 0x20, 0x3A); + addToMapW(0x9b, 0xFE, 0x85); + addToMapW(0x9b, 0xFE, 0x86); + addToMapW(0x9c, 0x00, 0x9C); + addToMapW(0x9c, 0x00, 0xA3); + addToMapW(0x9c, 0x04, 0x2C); + addToMapW(0x9c, 0x04, 0x4C); + addToMapW(0x9c, 0x20, 0xA4); + addToMapW(0x9d, 0x00, 0x9D); + addToMapW(0x9d, 0x00, 0xA5); + addToMapW(0x9d, 0x00, 0xD8); + addToMapW(0x9d, 0x00, 0xF8); + addToMapW(0x9d, 0x01, 0x41); + addToMapW(0x9d, 0x01, 0x42); + addToMapW(0x9d, 0x02, 0x78); + addToMapW(0x9d, 0x03, 0x98); + addToMapW(0x9d, 0x04, 0x2D); + addToMapW(0x9d, 0x04, 0x2E); + addToMapW(0x9d, 0x04, 0x4D); + addToMapW(0x9d, 0x04, 0x4E); + addToMapW(0x9d, 0x06, 0x25); + addToMapW(0x9d, 0x22, 0x05); + addToMapW(0x9d, 0xFE, 0x87); + addToMapW(0x9d, 0xFE, 0x88); + addToMapW(0x9e, 0x00, 0x9E); + addToMapW(0x9e, 0x00, 0xD7); + addToMapW(0x9e, 0x01, 0x5E); + addToMapW(0x9e, 0x01, 0x5F); + addToMapW(0x9e, 0x04, 0x2E); + addToMapW(0x9e, 0x04, 0x4E); + addToMapW(0x9e, 0x06, 0x26); + addToMapW(0x9e, 0x20, 0xA7); + addToMapW(0x9e, 0xFE, 0x89); + addToMapW(0x9e, 0xFE, 0x8A); + addToMapW(0x9e, 0xFE, 0x8B); + addToMapW(0x9e, 0xFE, 0x8C); + addToMapW(0x9f, 0x00, 0x9F); + addToMapW(0x9f, 0x00, 0xA4); + addToMapW(0x9f, 0x00, 0xFF); + addToMapW(0x9f, 0x01, 0x78); + addToMapW(0x9f, 0x01, 0x91); + addToMapW(0x9f, 0x01, 0x92); + addToMapW(0x9f, 0x04, 0x2A); + addToMapW(0x9f, 0x04, 0x2F); + addToMapW(0x9f, 0x04, 0x4A); + addToMapW(0x9f, 0x04, 0x4F); + addToMapW(0x9f, 0x06, 0x27); + addToMapW(0x9f, 0xFE, 0x8D); + addToMapW(0x9f, 0xFE, 0x8E); + addToMapW(0xa0, 0x00, 0xA0); + addToMapW(0xa0, 0x01, 0x00); + addToMapW(0xa0, 0x01, 0x01); + addToMapW(0xa0, 0x06, 0x28); + addToMapW(0xa0, 0xF8, 0xF0); + addToMapW(0xa0, 0xFE, 0x8F); + addToMapW(0xa0, 0xFE, 0x90); + addToMapW(0xa0, 0xFE, 0x91); + addToMapW(0xa0, 0xFE, 0x92); + addToMapW(0xa1, 0x00, 0xA1); + addToMapW(0xa1, 0x01, 0x2A); + addToMapW(0xa1, 0x01, 0x2B); + addToMapW(0xa1, 0x04, 0x10); + addToMapW(0xa1, 0x04, 0x30); + addToMapW(0xa1, 0x06, 0x29); + addToMapW(0xa1, 0x0E, 0x01); + addToMapW(0xa1, 0xFE, 0x93); + addToMapW(0xa1, 0xFE, 0x94); + addToMapW(0xa1, 0xFF, 0x61); + addToMapW(0xa2, 0x00, 0xA2); + addToMapW(0xa2, 0x06, 0x2A); + addToMapW(0xa2, 0x0E, 0x02); + addToMapW(0xa2, 0xFE, 0x95); + addToMapW(0xa2, 0xFE, 0x96); + addToMapW(0xa2, 0xFE, 0x97); + addToMapW(0xa2, 0xFE, 0x98); + addToMapW(0xa2, 0xFF, 0x62); + addToMapW(0xa3, 0x00, 0xA3); + addToMapW(0xa3, 0x01, 0x7B); + addToMapW(0xa3, 0x01, 0x7C); + addToMapW(0xa3, 0x04, 0x11); + addToMapW(0xa3, 0x04, 0x31); + addToMapW(0xa3, 0x06, 0x2B); + addToMapW(0xa3, 0x0E, 0x03); + addToMapW(0xa3, 0xFE, 0x99); + addToMapW(0xa3, 0xFE, 0x9A); + addToMapW(0xa3, 0xFE, 0x9B); + addToMapW(0xa3, 0xFE, 0x9C); + addToMapW(0xa3, 0xFF, 0x63); + addToMapW(0xa4, 0x00, 0xA4); + addToMapW(0xa4, 0x01, 0x04); + addToMapW(0xa4, 0x01, 0x05); + addToMapW(0xa4, 0x06, 0x2C); + addToMapW(0xa4, 0x0E, 0x04); + addToMapW(0xa4, 0xFE, 0x9D); + addToMapW(0xa4, 0xFE, 0x9E); + addToMapW(0xa4, 0xFE, 0x9F); + addToMapW(0xa4, 0xFE, 0xA0); + addToMapW(0xa4, 0xFF, 0x64); + addToMapW(0xa5, 0x00, 0xA5); + addToMapW(0xa5, 0x00, 0xD1); + addToMapW(0xa5, 0x00, 0xF1); + addToMapW(0xa5, 0x04, 0x26); + addToMapW(0xa5, 0x04, 0x46); + addToMapW(0xa5, 0x06, 0x2D); + addToMapW(0xa5, 0x0E, 0x05); + addToMapW(0xa5, 0xFE, 0xA1); + addToMapW(0xa5, 0xFE, 0xA2); + addToMapW(0xa5, 0xFE, 0xA3); + addToMapW(0xa5, 0xFE, 0xA4); + addToMapW(0xa5, 0xFF, 0x65); + addToMapW(0xa6, 0x00, 0xA6); + addToMapW(0xa6, 0x00, 0xAA); + addToMapW(0xa6, 0x01, 0x1E); + addToMapW(0xa6, 0x01, 0x1F); + addToMapW(0xa6, 0x01, 0x7D); + addToMapW(0xa6, 0x01, 0x7E); + addToMapW(0xa6, 0x06, 0x2E); + addToMapW(0xa6, 0x0E, 0x06); + addToMapW(0xa6, 0x20, 0x1D); + addToMapW(0xa6, 0xFE, 0xA5); + addToMapW(0xa6, 0xFE, 0xA6); + addToMapW(0xa6, 0xFE, 0xA7); + addToMapW(0xa6, 0xFE, 0xA8); + addToMapW(0xa6, 0xFF, 0x66); + addToMapW(0xa7, 0x00, 0xA6); + addToMapW(0xa7, 0x00, 0xA7); + addToMapW(0xa7, 0x00, 0xBA); + addToMapW(0xa7, 0x04, 0x14); + addToMapW(0xa7, 0x04, 0x34); + addToMapW(0xa7, 0x06, 0x2F); + addToMapW(0xa7, 0x0E, 0x07); + addToMapW(0xa7, 0xFE, 0xA9); + addToMapW(0xa7, 0xFE, 0xAA); + addToMapW(0xa7, 0xFF, 0x67); + addToMapW(0xa8, 0x00, 0xA8); + addToMapW(0xa8, 0x00, 0xA9); + addToMapW(0xa8, 0x00, 0xBF); + addToMapW(0xa8, 0x01, 0x18); + addToMapW(0xa8, 0x01, 0x19); + addToMapW(0xa8, 0x06, 0x30); + addToMapW(0xa8, 0x0E, 0x08); + addToMapW(0xa8, 0xFE, 0xAB); + addToMapW(0xa8, 0xFE, 0xAC); + addToMapW(0xa8, 0xFF, 0x68); + addToMapW(0xa9, 0x00, 0xA9); + addToMapW(0xa9, 0x00, 0xAE); + addToMapW(0xa9, 0x04, 0x15); + addToMapW(0xa9, 0x04, 0x35); + addToMapW(0xa9, 0x06, 0x31); + addToMapW(0xa9, 0x0E, 0x09); + addToMapW(0xa9, 0x23, 0x10); + addToMapW(0xa9, 0xFE, 0xAD); + addToMapW(0xa9, 0xFE, 0xAE); + addToMapW(0xa9, 0xFF, 0x69); + addToMapW(0xaa, 0x00, 0xAA); + addToMapW(0xaa, 0x00, 0xAC); + addToMapW(0xaa, 0x06, 0x32); + addToMapW(0xaa, 0x0E, 0x0A); + addToMapW(0xaa, 0x23, 0x10); + addToMapW(0xaa, 0xFE, 0xAF); + addToMapW(0xaa, 0xFE, 0xB0); + addToMapW(0xaa, 0xFF, 0x6A); + addToMapW(0xab, 0x00, 0xAB); + addToMapW(0xab, 0x00, 0xBD); + addToMapW(0xab, 0x04, 0x24); + addToMapW(0xab, 0x04, 0x44); + addToMapW(0xab, 0x06, 0x33); + addToMapW(0xab, 0x0E, 0x0B); + addToMapW(0xab, 0xFE, 0xB1); + addToMapW(0xab, 0xFE, 0xB2); + addToMapW(0xab, 0xFE, 0xB3); + addToMapW(0xab, 0xFE, 0xB4); + addToMapW(0xab, 0xFF, 0x6B); + addToMapW(0xac, 0x00, 0xAC); + addToMapW(0xac, 0x00, 0xBC); + addToMapW(0xac, 0x01, 0x0C); + addToMapW(0xac, 0x01, 0x0D); + addToMapW(0xac, 0x06, 0x34); + addToMapW(0xac, 0x0E, 0x0C); + addToMapW(0xac, 0xFE, 0xB5); + addToMapW(0xac, 0xFE, 0xB6); + addToMapW(0xac, 0xFE, 0xB7); + addToMapW(0xac, 0xFE, 0xB8); + addToMapW(0xac, 0xFF, 0x6C); + addToMapW(0xad, 0x00, 0xA1); + addToMapW(0xad, 0x00, 0xAD); + addToMapW(0xad, 0x01, 0x41); + addToMapW(0xad, 0x01, 0x42); + addToMapW(0xad, 0x04, 0x13); + addToMapW(0xad, 0x04, 0x33); + addToMapW(0xad, 0x06, 0x35); + addToMapW(0xad, 0x0E, 0x0D); + addToMapW(0xad, 0xFE, 0xB9); + addToMapW(0xad, 0xFE, 0xBA); + addToMapW(0xad, 0xFE, 0xBB); + addToMapW(0xad, 0xFE, 0xBC); + addToMapW(0xad, 0xFF, 0x6D); + addToMapW(0xae, 0x00, 0xAB); + addToMapW(0xae, 0x00, 0xAE); + addToMapW(0xae, 0x0E, 0x0E); + addToMapW(0xae, 0x22, 0x6A); + addToMapW(0xae, 0x30, 0x0A); + addToMapW(0xae, 0xFF, 0x6E); + addToMapW(0xaf, 0x00, 0xAF); + addToMapW(0xaf, 0x00, 0xBB); + addToMapW(0xaf, 0x0E, 0x0F); + addToMapW(0xaf, 0x22, 0x6B); + addToMapW(0xaf, 0x30, 0x0B); + addToMapW(0xaf, 0xFF, 0x6F); + addToMapW(0xb0, 0x00, 0xB0); + addToMapW(0xb0, 0x0E, 0x10); + addToMapW(0xb0, 0x25, 0x91); + addToMapW(0xb0, 0xFF, 0x70); + addToMapW(0xb1, 0x00, 0xB1); + addToMapW(0xb1, 0x0E, 0x11); + addToMapW(0xb1, 0x25, 0x92); + addToMapW(0xb1, 0xFF, 0x71); + addToMapW(0xb2, 0x00, 0xB2); + addToMapW(0xb2, 0x0E, 0x12); + addToMapW(0xb2, 0x25, 0x93); + addToMapW(0xb2, 0xFF, 0x72); + addToMapW(0xb3, 0x00, 0xA6); + addToMapW(0xb3, 0x00, 0xB3); + addToMapW(0xb3, 0x01, 0xC0); + addToMapW(0xb3, 0x0E, 0x13); + addToMapW(0xb3, 0x22, 0x23); + addToMapW(0xb3, 0x25, 0x02); + addToMapW(0xb3, 0x27, 0x58); + addToMapW(0xb3, 0xFF, 0x73); + addToMapW(0xb4, 0x00, 0xB4); + addToMapW(0xb4, 0x0E, 0x14); + addToMapW(0xb4, 0x25, 0x24); + addToMapW(0xb4, 0xFF, 0x74); + addToMapW(0xb5, 0x00, 0xB5); + addToMapW(0xb5, 0x00, 0xC1); + addToMapW(0xb5, 0x00, 0xE1); + addToMapW(0xb5, 0x01, 0x04); + addToMapW(0xb5, 0x01, 0x05); + addToMapW(0xb5, 0x0E, 0x15); + addToMapW(0xb5, 0x25, 0x61); + addToMapW(0xb5, 0xFF, 0x75); + addToMapW(0xb6, 0x00, 0xB6); + addToMapW(0xb6, 0x00, 0xC2); + addToMapW(0xb6, 0x00, 0xE2); + addToMapW(0xb6, 0x01, 0x0C); + addToMapW(0xb6, 0x01, 0x0D); + addToMapW(0xb6, 0x04, 0x25); + addToMapW(0xb6, 0x04, 0x45); + addToMapW(0xb6, 0x0E, 0x16); + addToMapW(0xb6, 0x25, 0x62); + addToMapW(0xb6, 0xFF, 0x76); + addToMapW(0xb7, 0x00, 0xB7); + addToMapW(0xb7, 0x00, 0xC0); + addToMapW(0xb7, 0x00, 0xE0); + addToMapW(0xb7, 0x01, 0x18); + addToMapW(0xb7, 0x01, 0x19); + addToMapW(0xb7, 0x01, 0x1A); + addToMapW(0xb7, 0x01, 0x1B); + addToMapW(0xb7, 0x0E, 0x17); + addToMapW(0xb7, 0x25, 0x56); + addToMapW(0xb7, 0xFF, 0x77); + addToMapW(0xb8, 0x00, 0xA9); + addToMapW(0xb8, 0x00, 0xB8); + addToMapW(0xb8, 0x01, 0x16); + addToMapW(0xb8, 0x01, 0x17); + addToMapW(0xb8, 0x01, 0x5E); + addToMapW(0xb8, 0x01, 0x5F); + addToMapW(0xb8, 0x04, 0x18); + addToMapW(0xb8, 0x04, 0x38); + addToMapW(0xb8, 0x0E, 0x18); + addToMapW(0xb8, 0x25, 0x55); + addToMapW(0xb8, 0xFF, 0x78); + addToMapW(0xb9, 0x00, 0xB9); + addToMapW(0xb9, 0x0E, 0x19); + addToMapW(0xb9, 0x25, 0x61); + addToMapW(0xb9, 0x25, 0x62); + addToMapW(0xb9, 0x25, 0x63); + addToMapW(0xb9, 0xFF, 0x79); + addToMapW(0xba, 0x00, 0xBA); + addToMapW(0xba, 0x0E, 0x1A); + addToMapW(0xba, 0x25, 0x51); + addToMapW(0xba, 0xFF, 0x7A); + addToMapW(0xbb, 0x00, 0xBB); + addToMapW(0xbb, 0x0E, 0x1B); + addToMapW(0xbb, 0x25, 0x55); + addToMapW(0xbb, 0x25, 0x56); + addToMapW(0xbb, 0x25, 0x57); + addToMapW(0xbb, 0xFF, 0x7B); + addToMapW(0xbc, 0x00, 0xBC); + addToMapW(0xbc, 0x0E, 0x1C); + addToMapW(0xbc, 0x25, 0x5B); + addToMapW(0xbc, 0x25, 0x5C); + addToMapW(0xbc, 0x25, 0x5D); + addToMapW(0xbc, 0xFF, 0x7C); + addToMapW(0xbd, 0x00, 0xA2); + addToMapW(0xbd, 0x00, 0xBD); + addToMapW(0xbd, 0x01, 0x2E); + addToMapW(0xbd, 0x01, 0x2F); + addToMapW(0xbd, 0x01, 0x7B); + addToMapW(0xbd, 0x01, 0x7C); + addToMapW(0xbd, 0x0E, 0x1D); + addToMapW(0xbd, 0x25, 0x5C); + addToMapW(0xbd, 0xFF, 0x7D); + addToMapW(0xbe, 0x00, 0xA5); + addToMapW(0xbe, 0x00, 0xBE); + addToMapW(0xbe, 0x01, 0x60); + addToMapW(0xbe, 0x01, 0x61); + addToMapW(0xbe, 0x04, 0x19); + addToMapW(0xbe, 0x04, 0x39); + addToMapW(0xbe, 0x0E, 0x1E); + addToMapW(0xbe, 0x25, 0x5B); + addToMapW(0xbe, 0xFF, 0x7E); + addToMapW(0xbf, 0x00, 0xAC); + addToMapW(0xbf, 0x00, 0xBF); + addToMapW(0xbf, 0x0E, 0x1F); + addToMapW(0xbf, 0x25, 0x10); + addToMapW(0xbf, 0xFF, 0x7F); + addToMapW(0xc0, 0x00, 0xC0); + addToMapW(0xc0, 0x00, 0xE0); + addToMapW(0xc0, 0x0E, 0x20); + addToMapW(0xc0, 0x25, 0x14); + addToMapW(0xc0, 0xFF, 0x80); + addToMapW(0xc1, 0x00, 0xC1); + addToMapW(0xc1, 0x00, 0xE1); + addToMapW(0xc1, 0x0E, 0x21); + addToMapW(0xc1, 0x25, 0x34); + addToMapW(0xc1, 0xFF, 0x81); + addToMapW(0xc2, 0x00, 0xC2); + addToMapW(0xc2, 0x00, 0xE2); + addToMapW(0xc2, 0x0E, 0x22); + addToMapW(0xc2, 0x25, 0x2C); + addToMapW(0xc2, 0xFF, 0x82); + addToMapW(0xc3, 0x01, 0x02); + addToMapW(0xc3, 0x01, 0x03); + addToMapW(0xc3, 0x0E, 0x23); + addToMapW(0xc3, 0x25, 0x1C); + addToMapW(0xc3, 0xFF, 0x83); + addToMapW(0xc4, 0x00, 0xAF); + addToMapW(0xc4, 0x00, 0xC4); + addToMapW(0xc4, 0x00, 0xE4); + addToMapW(0xc4, 0x02, 0xC9); + addToMapW(0xc4, 0x03, 0x04); + addToMapW(0xc4, 0x03, 0x05); + addToMapW(0xc4, 0x0E, 0x24); + addToMapW(0xc4, 0x25, 0x00); + addToMapW(0xc4, 0xFF, 0x84); + addToMapW(0xc5, 0x00, 0xC5); + addToMapW(0xc5, 0x00, 0xE5); + addToMapW(0xc5, 0x0E, 0x25); + addToMapW(0xc5, 0x20, 0x20); + addToMapW(0xc5, 0x20, 0x21); + addToMapW(0xc5, 0x25, 0x3C); + addToMapW(0xc5, 0xFF, 0x85); + addToMapW(0xc6, 0x00, 0xC6); + addToMapW(0xc6, 0x00, 0xE6); + addToMapW(0xc6, 0x01, 0x02); + addToMapW(0xc6, 0x01, 0x03); + addToMapW(0xc6, 0x01, 0x72); + addToMapW(0xc6, 0x01, 0x73); + addToMapW(0xc6, 0x0E, 0x26); + addToMapW(0xc6, 0x25, 0x5E); + addToMapW(0xc6, 0xFF, 0x86); + addToMapW(0xc7, 0x00, 0xC3); + addToMapW(0xc7, 0x00, 0xC7); + addToMapW(0xc7, 0x00, 0xE3); + addToMapW(0xc7, 0x00, 0xE7); + addToMapW(0xc7, 0x01, 0x6A); + addToMapW(0xc7, 0x01, 0x6B); + addToMapW(0xc7, 0x04, 0x1A); + addToMapW(0xc7, 0x04, 0x3A); + addToMapW(0xc7, 0x0E, 0x27); + addToMapW(0xc7, 0x25, 0x5F); + addToMapW(0xc7, 0xFF, 0x87); + addToMapW(0xc8, 0x00, 0xC8); + addToMapW(0xc8, 0x00, 0xE8); + addToMapW(0xc8, 0x0E, 0x28); + addToMapW(0xc8, 0x25, 0x58); + addToMapW(0xc8, 0x25, 0x59); + addToMapW(0xc8, 0x25, 0x5A); + addToMapW(0xc8, 0xFF, 0x88); + addToMapW(0xc9, 0x00, 0xC9); + addToMapW(0xc9, 0x00, 0xE9); + addToMapW(0xc9, 0x0E, 0x29); + addToMapW(0xc9, 0x25, 0x52); + addToMapW(0xc9, 0x25, 0x53); + addToMapW(0xc9, 0x25, 0x54); + addToMapW(0xc9, 0xFF, 0x89); + addToMapW(0xca, 0x00, 0xCA); + addToMapW(0xca, 0x00, 0xEA); + addToMapW(0xca, 0x0E, 0x2A); + addToMapW(0xca, 0x25, 0x67); + addToMapW(0xca, 0x25, 0x68); + addToMapW(0xca, 0x25, 0x69); + addToMapW(0xca, 0xFF, 0x8A); + addToMapW(0xcb, 0x00, 0xCB); + addToMapW(0xcb, 0x00, 0xEB); + addToMapW(0xcb, 0x0E, 0x2B); + addToMapW(0xcb, 0x25, 0x64); + addToMapW(0xcb, 0x25, 0x65); + addToMapW(0xcb, 0x25, 0x66); + addToMapW(0xcb, 0xFF, 0x8B); + addToMapW(0xcc, 0x03, 0x00); + addToMapW(0xcc, 0x0E, 0x2C); + addToMapW(0xcc, 0x25, 0x5E); + addToMapW(0xcc, 0x25, 0x5F); + addToMapW(0xcc, 0x25, 0x60); + addToMapW(0xcc, 0xFF, 0x8C); + addToMapW(0xcd, 0x00, 0xCD); + addToMapW(0xcd, 0x00, 0xED); + addToMapW(0xcd, 0x0E, 0x2D); + addToMapW(0xcd, 0x25, 0x50); + addToMapW(0xcd, 0xFF, 0x8D); + addToMapW(0xce, 0x00, 0xCE); + addToMapW(0xce, 0x00, 0xEE); + addToMapW(0xce, 0x0E, 0x2E); + addToMapW(0xce, 0x20, 0x21); + addToMapW(0xce, 0x25, 0x6A); + addToMapW(0xce, 0x25, 0x6B); + addToMapW(0xce, 0x25, 0x6C); + addToMapW(0xce, 0xFF, 0x8E); + addToMapW(0xcf, 0x00, 0xA4); + addToMapW(0xcf, 0x00, 0xCF); + addToMapW(0xcf, 0x00, 0xEF); + addToMapW(0xcf, 0x01, 0x7D); + addToMapW(0xcf, 0x01, 0x7E); + addToMapW(0xcf, 0x0E, 0x2F); + addToMapW(0xcf, 0x25, 0x67); + addToMapW(0xcf, 0xFF, 0x8F); + addToMapW(0xd0, 0x00, 0xBA); + addToMapW(0xd0, 0x01, 0x10); + addToMapW(0xd0, 0x01, 0x11); + addToMapW(0xd0, 0x0E, 0x30); + addToMapW(0xd0, 0x25, 0x68); + addToMapW(0xd0, 0xFF, 0x90); + addToMapW(0xd1, 0x00, 0xAA); + addToMapW(0xd1, 0x00, 0xD0); + addToMapW(0xd1, 0x00, 0xD1); + addToMapW(0xd1, 0x00, 0xF0); + addToMapW(0xd1, 0x00, 0xF1); + addToMapW(0xd1, 0x01, 0x10); + addToMapW(0xd1, 0x01, 0x11); + addToMapW(0xd1, 0x01, 0x89); + addToMapW(0xd1, 0x04, 0x1B); + addToMapW(0xd1, 0x04, 0x3B); + addToMapW(0xd1, 0x0E, 0x31); + addToMapW(0xd1, 0x25, 0x64); + addToMapW(0xd1, 0xFF, 0x91); + addToMapW(0xd2, 0x00, 0xCA); + addToMapW(0xd2, 0x00, 0xEA); + addToMapW(0xd2, 0x01, 0x0E); + addToMapW(0xd2, 0x01, 0x0F); + addToMapW(0xd2, 0x03, 0x09); + addToMapW(0xd2, 0x0E, 0x32); + addToMapW(0xd2, 0x25, 0x65); + addToMapW(0xd2, 0xFF, 0x92); + addToMapW(0xd3, 0x00, 0xCB); + addToMapW(0xd3, 0x00, 0xD3); + addToMapW(0xd3, 0x00, 0xEB); + addToMapW(0xd3, 0x00, 0xF3); + addToMapW(0xd3, 0x04, 0x1C); + addToMapW(0xd3, 0x04, 0x3C); + addToMapW(0xd3, 0x0E, 0x33); + addToMapW(0xd3, 0x25, 0x59); + addToMapW(0xd3, 0xFF, 0x93); + addToMapW(0xd4, 0x00, 0xC8); + addToMapW(0xd4, 0x00, 0xD4); + addToMapW(0xd4, 0x00, 0xE8); + addToMapW(0xd4, 0x00, 0xF4); + addToMapW(0xd4, 0x0E, 0x34); + addToMapW(0xd4, 0x25, 0x58); + addToMapW(0xd4, 0xFF, 0x94); + addToMapW(0xd5, 0x01, 0x31); + addToMapW(0xd5, 0x01, 0x47); + addToMapW(0xd5, 0x01, 0x48); + addToMapW(0xd5, 0x01, 0xA0); + addToMapW(0xd5, 0x01, 0xA1); + addToMapW(0xd5, 0x04, 0x1D); + addToMapW(0xd5, 0x04, 0x3D); + addToMapW(0xd5, 0x0E, 0x35); + addToMapW(0xd5, 0x25, 0x52); + addToMapW(0xd5, 0xF8, 0xBB); + addToMapW(0xd5, 0xFF, 0x95); + addToMapW(0xd6, 0x00, 0xCD); + addToMapW(0xd6, 0x00, 0xD6); + addToMapW(0xd6, 0x00, 0xED); + addToMapW(0xd6, 0x00, 0xF6); + addToMapW(0xd6, 0x0E, 0x36); + addToMapW(0xd6, 0x25, 0x53); + addToMapW(0xd6, 0xFF, 0x96); + addToMapW(0xd7, 0x00, 0xCE); + addToMapW(0xd7, 0x00, 0xD7); + addToMapW(0xd7, 0x00, 0xEE); + addToMapW(0xd7, 0x04, 0x1E); + addToMapW(0xd7, 0x04, 0x3E); + addToMapW(0xd7, 0x0E, 0x37); + addToMapW(0xd7, 0x25, 0x6B); + addToMapW(0xd7, 0xFF, 0x97); + addToMapW(0xd8, 0x00, 0xCF); + addToMapW(0xd8, 0x00, 0xD8); + addToMapW(0xd8, 0x00, 0xEF); + addToMapW(0xd8, 0x00, 0xF8); + addToMapW(0xd8, 0x0E, 0x38); + addToMapW(0xd8, 0x20, 0x21); + addToMapW(0xd8, 0x25, 0x6A); + addToMapW(0xd8, 0xFF, 0x98); + addToMapW(0xd9, 0x00, 0xD9); + addToMapW(0xd9, 0x00, 0xF9); + addToMapW(0xd9, 0x0E, 0x39); + addToMapW(0xd9, 0x25, 0x18); + addToMapW(0xd9, 0xFF, 0x99); + addToMapW(0xda, 0x00, 0xDA); + addToMapW(0xda, 0x00, 0xFA); + addToMapW(0xda, 0x0E, 0x3A); + addToMapW(0xda, 0x25, 0x0C); + addToMapW(0xda, 0xFF, 0x9A); + addToMapW(0xdb, 0x00, 0xDB); + addToMapW(0xdb, 0x00, 0xFB); + addToMapW(0xdb, 0x25, 0x88); + addToMapW(0xdb, 0x25, 0x8C); + addToMapW(0xdb, 0x25, 0x90); + addToMapW(0xdb, 0xF8, 0xC1); + addToMapW(0xdb, 0xFF, 0x9B); + addToMapW(0xdc, 0x00, 0xDC); + addToMapW(0xdc, 0x00, 0xFC); + addToMapW(0xdc, 0x25, 0x84); + addToMapW(0xdc, 0xF8, 0xC2); + addToMapW(0xdc, 0xFF, 0x9C); + addToMapW(0xdd, 0x00, 0xA6); + addToMapW(0xdd, 0x01, 0x62); + addToMapW(0xdd, 0x01, 0x63); + addToMapW(0xdd, 0x01, 0xAF); + addToMapW(0xdd, 0x01, 0xB0); + addToMapW(0xdd, 0x04, 0x1F); + addToMapW(0xdd, 0x04, 0x3F); + addToMapW(0xdd, 0x25, 0x8C); + addToMapW(0xdd, 0xF8, 0xC3); + addToMapW(0xdd, 0xFF, 0x9D); + addToMapW(0xde, 0x00, 0xCC); + addToMapW(0xde, 0x00, 0xEC); + addToMapW(0xde, 0x01, 0x6E); + addToMapW(0xde, 0x01, 0x6F); + addToMapW(0xde, 0x03, 0x03); + addToMapW(0xde, 0x25, 0x90); + addToMapW(0xde, 0xF8, 0xC4); + addToMapW(0xde, 0xFF, 0x9E); + addToMapW(0xdf, 0x00, 0xDF); + addToMapW(0xdf, 0x0E, 0x3F); + addToMapW(0xdf, 0x25, 0x80); + addToMapW(0xdf, 0xFF, 0x9F); + addToMapW(0xe0, 0x00, 0xD3); + addToMapW(0xe0, 0x00, 0xF3); + addToMapW(0xe0, 0x03, 0x91); + addToMapW(0xe0, 0x03, 0xB1); + addToMapW(0xe0, 0x04, 0x2F); + addToMapW(0xe0, 0x04, 0x4F); + addToMapW(0xe0, 0x06, 0x36); + addToMapW(0xe0, 0x0E, 0x40); + addToMapW(0xe0, 0xFE, 0xBD); + addToMapW(0xe0, 0xFE, 0xBE); + addToMapW(0xe0, 0xFE, 0xBF); + addToMapW(0xe0, 0xFE, 0xC0); + addToMapW(0xe1, 0x00, 0xDF); + addToMapW(0xe1, 0x03, 0xB2); + addToMapW(0xe1, 0x06, 0x37); + addToMapW(0xe1, 0x0E, 0x41); + addToMapW(0xe1, 0xFE, 0xC1); + addToMapW(0xe1, 0xFE, 0xC2); + addToMapW(0xe1, 0xFE, 0xC3); + addToMapW(0xe1, 0xFE, 0xC4); + addToMapW(0xe2, 0x00, 0xD4); + addToMapW(0xe2, 0x00, 0xF4); + addToMapW(0xe2, 0x01, 0x4C); + addToMapW(0xe2, 0x01, 0x4D); + addToMapW(0xe2, 0x03, 0x93); + addToMapW(0xe2, 0x04, 0x20); + addToMapW(0xe2, 0x04, 0x40); + addToMapW(0xe2, 0x06, 0x38); + addToMapW(0xe2, 0x0E, 0x42); + addToMapW(0xe2, 0xFE, 0xC5); + addToMapW(0xe2, 0xFE, 0xC6); + addToMapW(0xe2, 0xFE, 0xC7); + addToMapW(0xe2, 0xFE, 0xC8); + addToMapW(0xe3, 0x00, 0xD2); + addToMapW(0xe3, 0x00, 0xF2); + addToMapW(0xe3, 0x01, 0x43); + addToMapW(0xe3, 0x01, 0x44); + addToMapW(0xe3, 0x03, 0xA0); + addToMapW(0xe3, 0x03, 0xC0); + addToMapW(0xe3, 0x06, 0x39); + addToMapW(0xe3, 0x0E, 0x43); + addToMapW(0xe3, 0xFE, 0xC9); + addToMapW(0xe3, 0xFE, 0xCA); + addToMapW(0xe3, 0xFE, 0xCB); + addToMapW(0xe3, 0xFE, 0xCC); + addToMapW(0xe4, 0x01, 0xA9); + addToMapW(0xe4, 0x03, 0xA3); + addToMapW(0xe4, 0x03, 0xC3); + addToMapW(0xe4, 0x04, 0x21); + addToMapW(0xe4, 0x04, 0x41); + addToMapW(0xe4, 0x06, 0x3A); + addToMapW(0xe4, 0x0E, 0x44); + addToMapW(0xe4, 0x22, 0x11); + addToMapW(0xe4, 0xFE, 0xCD); + addToMapW(0xe4, 0xFE, 0xCE); + addToMapW(0xe4, 0xFE, 0xCF); + addToMapW(0xe4, 0xFE, 0xD0); + addToMapW(0xe5, 0x00, 0xD5); + addToMapW(0xe5, 0x00, 0xF5); + addToMapW(0xe5, 0x06, 0x41); + addToMapW(0xe5, 0x0E, 0x45); + addToMapW(0xe5, 0xFE, 0xD1); + addToMapW(0xe5, 0xFE, 0xD2); + addToMapW(0xe5, 0xFE, 0xD3); + addToMapW(0xe5, 0xFE, 0xD4); + addToMapW(0xe6, 0x00, 0xB5); + addToMapW(0xe6, 0x01, 0x60); + addToMapW(0xe6, 0x01, 0x61); + addToMapW(0xe6, 0x03, 0xBC); + addToMapW(0xe6, 0x04, 0x22); + addToMapW(0xe6, 0x04, 0x42); + addToMapW(0xe6, 0x0E, 0x46); + addToMapW(0xe7, 0x03, 0xA4); + addToMapW(0xe7, 0x03, 0xC4); + addToMapW(0xe7, 0x06, 0x42); + addToMapW(0xe7, 0x0E, 0x47); + addToMapW(0xe7, 0xF8, 0xBC); + addToMapW(0xe7, 0xFE, 0xD5); + addToMapW(0xe7, 0xFE, 0xD6); + addToMapW(0xe7, 0xFE, 0xD7); + addToMapW(0xe7, 0xFE, 0xD8); + addToMapW(0xe8, 0x00, 0xD7); + addToMapW(0xe8, 0x00, 0xDE); + addToMapW(0xe8, 0x00, 0xFE); + addToMapW(0xe8, 0x01, 0x36); + addToMapW(0xe8, 0x01, 0x37); + addToMapW(0xe8, 0x01, 0x54); + addToMapW(0xe8, 0x01, 0x55); + addToMapW(0xe8, 0x02, 0x78); + addToMapW(0xe8, 0x03, 0xA6); + addToMapW(0xe8, 0x03, 0xC6); + addToMapW(0xe8, 0x04, 0x23); + addToMapW(0xe8, 0x04, 0x43); + addToMapW(0xe8, 0x06, 0x43); + addToMapW(0xe8, 0x0E, 0x48); + addToMapW(0xe8, 0x22, 0x05); + addToMapW(0xe8, 0xFE, 0xD9); + addToMapW(0xe8, 0xFE, 0xDA); + addToMapW(0xe8, 0xFE, 0xDB); + addToMapW(0xe8, 0xFE, 0xDC); + addToMapW(0xe9, 0x00, 0xDA); + addToMapW(0xe9, 0x00, 0xFA); + addToMapW(0xe9, 0x03, 0x98); + addToMapW(0xe9, 0x06, 0x44); + addToMapW(0xe9, 0x0E, 0x49); + addToMapW(0xe9, 0xFE, 0xDD); + addToMapW(0xe9, 0xFE, 0xDE); + addToMapW(0xe9, 0xFE, 0xDF); + addToMapW(0xe9, 0xFE, 0xE0); + addToMapW(0xea, 0x00, 0xDB); + addToMapW(0xea, 0x00, 0xFB); + addToMapW(0xea, 0x01, 0x3B); + addToMapW(0xea, 0x01, 0x3C); + addToMapW(0xea, 0x03, 0x86); + addToMapW(0xea, 0x03, 0xA9); + addToMapW(0xea, 0x03, 0xAC); + addToMapW(0xea, 0x04, 0x16); + addToMapW(0xea, 0x04, 0x36); + addToMapW(0xea, 0x06, 0x45); + addToMapW(0xea, 0x0E, 0x4A); + addToMapW(0xea, 0x21, 0x26); + addToMapW(0xea, 0xFE, 0xE1); + addToMapW(0xea, 0xFE, 0xE2); + addToMapW(0xea, 0xFE, 0xE3); + addToMapW(0xea, 0xFE, 0xE4); + addToMapW(0xeb, 0x00, 0xD9); + addToMapW(0xeb, 0x00, 0xF9); + addToMapW(0xeb, 0x01, 0x70); + addToMapW(0xeb, 0x01, 0x71); + addToMapW(0xeb, 0x03, 0x88); + addToMapW(0xeb, 0x03, 0x94); + addToMapW(0xeb, 0x03, 0xAD); + addToMapW(0xeb, 0x03, 0xB4); + addToMapW(0xeb, 0x06, 0x46); + addToMapW(0xeb, 0x0E, 0x4B); + addToMapW(0xeb, 0xFE, 0xE5); + addToMapW(0xeb, 0xFE, 0xE6); + addToMapW(0xeb, 0xFE, 0xE7); + addToMapW(0xeb, 0xFE, 0xE8); + addToMapW(0xec, 0x03, 0x01); + addToMapW(0xec, 0x03, 0x89); + addToMapW(0xec, 0x03, 0xAE); + addToMapW(0xec, 0x04, 0x12); + addToMapW(0xec, 0x04, 0x32); + addToMapW(0xec, 0x06, 0x47); + addToMapW(0xec, 0x0E, 0x4C); + addToMapW(0xec, 0x22, 0x1E); + addToMapW(0xec, 0xFE, 0xE9); + addToMapW(0xec, 0xFE, 0xEA); + addToMapW(0xec, 0xFE, 0xEB); + addToMapW(0xec, 0xFE, 0xEC); + addToMapW(0xed, 0x00, 0xDD); + addToMapW(0xed, 0x00, 0xFD); + addToMapW(0xed, 0x01, 0x12); + addToMapW(0xed, 0x01, 0x13); + addToMapW(0xed, 0x03, 0x8A); + addToMapW(0xed, 0x03, 0xAF); + addToMapW(0xed, 0x06, 0x48); + addToMapW(0xed, 0x0E, 0x4D); + addToMapW(0xed, 0xFE, 0xED); + addToMapW(0xed, 0xFE, 0xEE); + addToMapW(0xee, 0x00, 0xAF); + addToMapW(0xee, 0x01, 0x45); + addToMapW(0xee, 0x01, 0x46); + addToMapW(0xee, 0x03, 0x04); + addToMapW(0xee, 0x03, 0x05); + addToMapW(0xee, 0x03, 0x8C); + addToMapW(0xee, 0x03, 0x95); + addToMapW(0xee, 0x03, 0xB5); + addToMapW(0xee, 0x03, 0xCC); + addToMapW(0xee, 0x04, 0x2C); + addToMapW(0xee, 0x04, 0x4C); + addToMapW(0xee, 0x06, 0x49); + addToMapW(0xee, 0x0E, 0x4E); + addToMapW(0xee, 0xFE, 0xEF); + addToMapW(0xee, 0xFE, 0xF0); + addToMapW(0xef, 0x00, 0xB4); + addToMapW(0xef, 0x02, 0xB9); + addToMapW(0xef, 0x02, 0xCA); + addToMapW(0xef, 0x03, 0x01); + addToMapW(0xef, 0x03, 0x8E); + addToMapW(0xef, 0x03, 0xCD); + addToMapW(0xef, 0x06, 0x4A); + addToMapW(0xef, 0x0E, 0x4F); + addToMapW(0xef, 0x20, 0x19); + addToMapW(0xef, 0x20, 0x32); + addToMapW(0xef, 0x20, 0x35); + addToMapW(0xef, 0x21, 0x16); + addToMapW(0xef, 0x22, 0x29); + addToMapW(0xef, 0xFE, 0xF1); + addToMapW(0xef, 0xFE, 0xF2); + addToMapW(0xef, 0xFE, 0xF3); + addToMapW(0xef, 0xFE, 0xF4); + addToMapW(0xf0, 0x00, 0xAD); + addToMapW(0xf0, 0x03, 0x8F); + addToMapW(0xf0, 0x03, 0xCE); + addToMapW(0xf0, 0x04, 0x01); + addToMapW(0xf0, 0x04, 0x51); + addToMapW(0xf0, 0x0E, 0x50); + addToMapW(0xf0, 0x22, 0x61); + addToMapW(0xf1, 0x00, 0xB1); + addToMapW(0xf1, 0x02, 0xDD); + addToMapW(0xf1, 0x06, 0x4B); + addToMapW(0xf1, 0x0E, 0x51); + addToMapW(0xf1, 0x22, 0x13); + addToMapW(0xf1, 0xFE, 0x70); + addToMapW(0xf1, 0xFE, 0x71); + addToMapW(0xf2, 0x02, 0xDB); + addToMapW(0xf2, 0x03, 0x23); + addToMapW(0xf2, 0x04, 0x04); + addToMapW(0xf2, 0x04, 0x2B); + addToMapW(0xf2, 0x04, 0x4B); + addToMapW(0xf2, 0x04, 0x54); + addToMapW(0xf2, 0x06, 0x4C); + addToMapW(0xf2, 0x0E, 0x52); + addToMapW(0xf2, 0x20, 0x17); + addToMapW(0xf2, 0x20, 0x1C); + addToMapW(0xf2, 0x22, 0x65); + addToMapW(0xf2, 0xF8, 0xBD); + addToMapW(0xf2, 0xFE, 0x72); + addToMapW(0xf3, 0x00, 0xBE); + addToMapW(0xf3, 0x02, 0xC7); + addToMapW(0xf3, 0x03, 0x0C); + addToMapW(0xf3, 0x06, 0x4D); + addToMapW(0xf3, 0x0E, 0x53); + addToMapW(0xf3, 0x22, 0x64); + addToMapW(0xf3, 0xFE, 0x74); + addToMapW(0xf4, 0x00, 0xB6); + addToMapW(0xf4, 0x02, 0xD8); + addToMapW(0xf4, 0x03, 0x06); + addToMapW(0xf4, 0x03, 0xAA); + addToMapW(0xf4, 0x03, 0xCA); + addToMapW(0xf4, 0x04, 0x07); + addToMapW(0xf4, 0x04, 0x17); + addToMapW(0xf4, 0x04, 0x37); + addToMapW(0xf4, 0x04, 0x57); + addToMapW(0xf4, 0x06, 0x4E); + addToMapW(0xf4, 0x0E, 0x54); + addToMapW(0xf4, 0x23, 0x20); + addToMapW(0xf4, 0xFE, 0x76); + addToMapW(0xf4, 0xFE, 0x77); + addToMapW(0xf5, 0x00, 0xA7); + addToMapW(0xf5, 0x03, 0xAB); + addToMapW(0xf5, 0x03, 0xCB); + addToMapW(0xf5, 0x06, 0x4F); + addToMapW(0xf5, 0x0E, 0x55); + addToMapW(0xf5, 0x23, 0x21); + addToMapW(0xf5, 0xFE, 0x78); + addToMapW(0xf5, 0xFE, 0x79); + addToMapW(0xf6, 0x00, 0xF7); + addToMapW(0xf6, 0x04, 0x0E); + addToMapW(0xf6, 0x04, 0x28); + addToMapW(0xf6, 0x04, 0x48); + addToMapW(0xf6, 0x04, 0x5E); + addToMapW(0xf6, 0x06, 0x50); + addToMapW(0xf6, 0x0E, 0x56); + addToMapW(0xf6, 0xFE, 0x7A); + addToMapW(0xf6, 0xFE, 0x7B); + addToMapW(0xf7, 0x00, 0xB8); + addToMapW(0xf7, 0x00, 0xF7); + addToMapW(0xf7, 0x02, 0xDB); + addToMapW(0xf7, 0x03, 0x27); + addToMapW(0xf7, 0x0E, 0x57); + addToMapW(0xf7, 0x20, 0x1E); + addToMapW(0xf7, 0x22, 0x48); + addToMapW(0xf8, 0x00, 0xB0); + addToMapW(0xf8, 0x02, 0xDA); + addToMapW(0xf8, 0x03, 0x0A); + addToMapW(0xf8, 0x04, 0x2D); + addToMapW(0xf8, 0x04, 0x4D); + addToMapW(0xf8, 0x0E, 0x58); + addToMapW(0xf8, 0x20, 0x70); + addToMapW(0xf8, 0x22, 0x18); + addToMapW(0xf9, 0x00, 0xA8); + addToMapW(0xf9, 0x02, 0xDD); + addToMapW(0xf9, 0x03, 0x08); + addToMapW(0xf9, 0x0E, 0x59); + addToMapW(0xf9, 0x22, 0x19); + addToMapW(0xfa, 0x00, 0xB7); + addToMapW(0xfa, 0x02, 0xD9); + addToMapW(0xfa, 0x03, 0x07); + addToMapW(0xfa, 0x04, 0x29); + addToMapW(0xfa, 0x04, 0x49); + addToMapW(0xfa, 0x0E, 0x5A); + addToMapW(0xfa, 0x20, 0x24); + addToMapW(0xfa, 0x22, 0xC5); + addToMapW(0xfa, 0x30, 0xFB); + addToMapW(0xfb, 0x00, 0xB9); + addToMapW(0xfb, 0x0E, 0x5B); + addToMapW(0xfb, 0x20, 0x81); + addToMapW(0xfb, 0x22, 0x1A); + addToMapW(0xfb, 0x27, 0x13); + addToMapW(0xfc, 0x00, 0xB3); + addToMapW(0xfc, 0x01, 0x58); + addToMapW(0xfc, 0x01, 0x59); + addToMapW(0xfc, 0x04, 0x27); + addToMapW(0xfc, 0x04, 0x47); + addToMapW(0xfc, 0x20, 0x7F); + addToMapW(0xfc, 0x20, 0x83); + addToMapW(0xfc, 0x21, 0x16); + addToMapW(0xfc, 0xF8, 0xC5); + addToMapW(0xfd, 0x00, 0xA4); + addToMapW(0xfd, 0x00, 0xA7); + addToMapW(0xfd, 0x00, 0xB2); + addToMapW(0xfd, 0x20, 0x82); + addToMapW(0xfd, 0xF8, 0xC6); + addToMapW(0xfd, 0xF8, 0xF1); + addToMapW(0xfe, 0x20, 0xAB); + addToMapW(0xfe, 0x25, 0xA0); + addToMapW(0xfe, 0xF8, 0xC7); + addToMapW(0xfe, 0xF8, 0xF2); + addToMapW(0xff, 0x00, 0xA0); + addToMapW(0xff, 0xF8, 0xC8); + addToMapW(0xff, 0xF8, 0xF3); +} diff --git a/Client Applications/rcracki_mt/lm2ntlm.h b/Client Applications/rcracki_mt/lm2ntlm.h index 6a423f5..3a44334 100644 --- a/Client Applications/rcracki_mt/lm2ntlm.h +++ b/Client Applications/rcracki_mt/lm2ntlm.h @@ -1,80 +1,80 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#include -#include -#include -#ifdef _WIN32 - #include -#endif -//#include "openssl/md4.h" -#include -#include "signal.h" -#include "Public.h" -#include "md4.h" - -using namespace std; - -class LM2NTLMcorrector -{ -public: - LM2NTLMcorrector(); - -private: - map > m_mapChar; - uint64 progressCurrentCombination; - uint64 totalCurrentCombination; - uint64 counterOverall; - unsigned char NTLMHash[16]; - clock_t startClock; - int countCombinations; - int countTotalCombinations; - int counter; - clock_t previousClock; - unsigned char currentCharmap[16][128]; - bool aborting; - string sBinary; - -private: - bool checkNTLMPassword(unsigned char* pLMPassword, int nLMPasswordLen, string& sNTLMPassword); - bool startCorrecting(string sLMPassword, string& sNTLMPassword, unsigned char* pLMPassword); - void printString(unsigned char* muteThis, int length); - void setupCombinationAtPositions(int length, unsigned char* pMuteMe, unsigned char* pTempMute, int* jAtPos, bool* fullAtPos, int* sizeAtPos); - bool checkPermutations(int length, unsigned char* pTempMute, int* jAtPos, int* sizeAtPos, unsigned char* pLMPassword, string& sNTLMPassword); - - int calculateTotalCombinations(int length, int setSize); - int factorial (int num); - - bool parseHexPassword(string hexPassword, string& sPlain); - bool NormalizeHexString(string& sHash); - void ParseHash(string sHash, unsigned char* pHash, int& nHashLen); - string ByteToStr(const unsigned char* pData, int nLen); - void addToMapW(unsigned char key, unsigned char value1, unsigned char value2); - void fillMapW(); - void checkAbort(); - void writeEndStats(); -public: - bool LMPasswordCorrectUnicode(string hexPassword, unsigned char* NTLMHash, string& sNTLMPassword); - string getBinary(); -}; - +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#include +#include +#include +#ifdef _WIN32 + #include +#endif +//#include "openssl/md4.h" +#include +#include "signal.h" +#include "Public.h" +#include "md4.h" + +using namespace std; + +class LM2NTLMcorrector +{ +public: + LM2NTLMcorrector(); + +private: + map > m_mapChar; + uint64 progressCurrentCombination; + uint64 totalCurrentCombination; + uint64 counterOverall; + unsigned char NTLMHash[16]; + clock_t startClock; + int countCombinations; + int countTotalCombinations; + int counter; + clock_t previousClock; + unsigned char currentCharmap[16][128]; + bool aborting; + string sBinary; + +private: + bool checkNTLMPassword(unsigned char* pLMPassword, int nLMPasswordLen, string& sNTLMPassword); + bool startCorrecting(string sLMPassword, string& sNTLMPassword, unsigned char* pLMPassword); + void printString(unsigned char* muteThis, int length); + void setupCombinationAtPositions(int length, unsigned char* pMuteMe, unsigned char* pTempMute, int* jAtPos, bool* fullAtPos, int* sizeAtPos); + bool checkPermutations(int length, unsigned char* pTempMute, int* jAtPos, int* sizeAtPos, unsigned char* pLMPassword, string& sNTLMPassword); + + int calculateTotalCombinations(int length, int setSize); + int factorial (int num); + + bool parseHexPassword(string hexPassword, string& sPlain); + bool NormalizeHexString(string& sHash); + void ParseHash(string sHash, unsigned char* pHash, int& nHashLen); + string ByteToStr(const unsigned char* pData, int nLen); + void addToMapW(unsigned char key, unsigned char value1, unsigned char value2); + void fillMapW(); + void checkAbort(); + void writeEndStats(); +public: + bool LMPasswordCorrectUnicode(string hexPassword, unsigned char* NTLMHash, string& sNTLMPassword); + string getBinary(); +}; + diff --git a/Client Applications/rcracki_mt/md4.cpp b/Client Applications/rcracki_mt/md4.cpp index e5d9c2f..cb11c7e 100644 --- a/Client Applications/rcracki_mt/md4.cpp +++ b/Client Applications/rcracki_mt/md4.cpp @@ -1,334 +1,334 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright Bitweasil - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - * - * This code implements the MD4 message-digest algorithm. - * "Just the reference implementation, single stage. Hardly "optimized." Though a good bit faster than libssl's MD4, as it isn't doing nearly the same amount of work." - Bitweasil - * - * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke - */ - - -//#include -//#include -#include "md4.h" - -/* MD4 Defines as per RFC reference implementation */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) -#define FF(a, b, c, d, x, s) { \ - (a) += F ((b), (c), (d)) + (x); \ - (a) = ROTATE_LEFT ((a), (s)); \ - } -#define GG(a, b, c, d, x, s) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \ - (a) = ROTATE_LEFT ((a), (s)); \ - } -#define HH(a, b, c, d, x, s) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \ - (a) = ROTATE_LEFT ((a), (s)); \ - } -#define S11 3 -#define S12 7 -#define S13 11 -#define S14 19 -#define S21 3 -#define S22 5 -#define S23 9 -#define S24 13 -#define S31 3 -#define S32 9 -#define S33 11 -#define S34 15 -/* End MD4 Defines */ - -void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest) -{ - // access data as 4-byte word - #define uData ((UINT4 *)pData) - #define uDigest ((UINT4 *)pDigest) - - // pad word and append bit at appropriate location - #define MD4_pad_w0() (0x00000080) - #define MD4_pad_w1(data) (((data) & 0x000000FF) | 0x00008000) - #define MD4_pad_w2(data) (((data) & 0x0000FFFF) | 0x00800000) - #define MD4_pad_w3(data) (((data) & 0x00FFFFFF) | 0x80000000) - - // For the hash working space - //__attribute__((aligned(16))) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - //__declspec(align(16)) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - UINT4 data[MD4_DIGEST_LENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; - - // For the output result - UINT4 a,b,c,d; - - switch (length) - { - case 0: - { - data[ 0] = MD4_pad_w0(); - - data[14] = 0; - } - break; - case 1: - { - data[ 0] = MD4_pad_w1(uData[0]); - - data[14] = 1 << 3; - } - break; - case 2: - { - data[ 0] = MD4_pad_w2(uData[0]); - - data[14] = 2 << 3; - } - break; - case 3: - { - data[ 0] = MD4_pad_w3(uData[0]); - - data[14] = 3 << 3; - } - break; - case 4: - { - data[ 0] = uData[0]; - data[ 1] = MD4_pad_w0(); - - data[14] = 4 << 3; - } - break; - case 5: - { - data[ 0] = uData[0]; - data[ 1] = MD4_pad_w1(uData[1]); - - data[14] = 5 << 3; - } - break; - case 6: - { - data[ 0] = uData[0]; - data[ 1] = MD4_pad_w2(uData[1]); - - data[14] = 6 << 3; - } - break; - case 7: - { - data[ 0] = uData[0]; - data[ 1] = MD4_pad_w3(uData[1]); - - data[14] = 7 << 3; - } - break; - case 8: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = MD4_pad_w0(); - - data[14] = 8 << 3; - } - break; - case 9: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = MD4_pad_w1(uData[2]); - - data[14] = 9 << 3; - } - break; - case 10: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = MD4_pad_w2(uData[2]); - - data[14] = 10 << 3; - } - break; - case 11: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = MD4_pad_w3(uData[2]); - - data[14] = 11 << 3; - } - break; - case 12: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = uData[2]; - data[ 3] = MD4_pad_w0(); - - data[14] = 12 << 3; - } - break; - case 13: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = uData[2]; - data[ 3] = MD4_pad_w1(uData[3]); - - data[14] = 13 << 3; - } - break; - case 14: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = uData[2]; - data[ 3] = MD4_pad_w2(uData[3]); - - data[14] = 14 << 3; - } - break; - case 15: - { - data[ 0] = uData[0]; - data[ 1] = uData[1]; - data[ 2] = uData[2]; - data[ 3] = MD4_pad_w3(uData[3]); - - data[14] = 15 << 3; - } - break; - - default: - { - length = length % 32; // lenght >= 32 not suported - - int word = length >> 2; - - int i = 0; - while (i < word) { - data[i] = uData[i]; - i++; - } - - switch (length & 0x3) { - case 0: - { - data[word] = MD4_pad_w0(); - } - break; - case 1: - { - data[word] = MD4_pad_w1(uData[word]); - } - break; - case 2: - { - data[word] = MD4_pad_w2(uData[word]); - } - break; - case 3: - { - data[word] = MD4_pad_w3(uData[word]); - } - break; - } - - data[14] = length << 3; - } - break; - } - - a = 0x67452301; - b = 0xefcdab89; - c = 0x98badcfe; - d = 0x10325476; - - /* Round 1 */ - FF (a, b, c, d, data[ 0], S11); /* 1 */ - FF (d, a, b, c, data[ 1], S12); /* 2 */ - FF (c, d, a, b, data[ 2], S13); /* 3 */ - FF (b, c, d, a, data[ 3], S14); /* 4 */ - FF (a, b, c, d, data[ 4], S11); /* 5 */ - FF (d, a, b, c, data[ 5], S12); /* 6 */ - FF (c, d, a, b, data[ 6], S13); /* 7 */ - FF (b, c, d, a, data[ 7], S14); /* 8 */ - FF (a, b, c, d, 0, S11); /* 9 */ - FF (d, a, b, c, 0, S12); /* 10 */ - FF (c, d, a, b, 0, S13); /* 11 */ - FF (b, c, d, a, 0, S14); /* 12 */ - FF (a, b, c, d, 0, S11); /* 13 */ - FF (d, a, b, c, 0, S12); /* 14 */ - FF (c, d, a, b, data[14], S13); /* 15 */ - FF (b, c, d, a, 0, S14); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, data[ 0], S21); /* 17 */ - GG (d, a, b, c, data[ 4], S22); /* 18 */ - GG (c, d, a, b, 0, S23); /* 19 */ - GG (b, c, d, a, 0, S24); /* 20 */ - GG (a, b, c, d, data[ 1], S21); /* 21 */ - GG (d, a, b, c, data[ 5], S22); /* 22 */ - GG (c, d, a, b, 0, S23); /* 23 */ - GG (b, c, d, a, 0, S24); /* 24 */ - GG (a, b, c, d, data[ 2], S21); /* 25 */ - GG (d, a, b, c, data[ 6], S22); /* 26 */ - GG (c, d, a, b, 0, S23); /* 27 */ - GG (b, c, d, a, data[14], S24); /* 28 */ - GG (a, b, c, d, data[ 3], S21); /* 29 */ - GG (d, a, b, c, data[ 7], S22); /* 30 */ - GG (c, d, a, b, 0, S23); /* 31 */ - GG (b, c, d, a, 0, S24); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, data[ 0], S31); /* 33 */ - HH (d, a, b, c, 0, S32); /* 34 */ - HH (c, d, a, b, data[ 4], S33); /* 35 */ - HH (b, c, d, a, 0, S34); /* 36 */ - HH (a, b, c, d, data[ 2], S31); /* 37 */ - HH (d, a, b, c, 0, S32); /* 38 */ - HH (c, d, a, b, data[ 6], S33); /* 39 */ - HH (b, c, d, a, data[14], S34); /* 40 */ - HH (a, b, c, d, data[ 1], S31); /* 41 */ - HH (d, a, b, c, 0, S32); /* 42 */ - HH (c, d, a, b, data[ 5], S33); /* 43 */ - HH (b, c, d, a, 0, S34); /* 44 */ - HH (a, b, c, d, data[ 3], S31); /* 45 */ - HH (d, a, b, c, 0, S32); /* 46 */ - HH (c, d, a, b, data[ 7], S33); /* 47 */ - HH (b, c, d, a, 0, S34); /* 48 */ - - // Finally, add initial values, as this is the only pass we make. - a += 0x67452301; - b += 0xefcdab89; - c += 0x98badcfe; - d += 0x10325476; - - uDigest[0] = a; - uDigest[1] = b; - uDigest[2] = c; - uDigest[3] = d; -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright Bitweasil + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + * + * This code implements the MD4 message-digest algorithm. + * "Just the reference implementation, single stage. Hardly "optimized." Though a good bit faster than libssl's MD4, as it isn't doing nearly the same amount of work." - Bitweasil + * + * little bit optimized (or at least attempted) for NTLM (unicode) by neinbrucke + */ + + +//#include +//#include +#include "md4.h" + +/* MD4 Defines as per RFC reference implementation */ +#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) +#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) +#define FF(a, b, c, d, x, s) { \ + (a) += F ((b), (c), (d)) + (x); \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define GG(a, b, c, d, x, s) { \ + (a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define HH(a, b, c, d, x, s) { \ + (a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; \ + (a) = ROTATE_LEFT ((a), (s)); \ + } +#define S11 3 +#define S12 7 +#define S13 11 +#define S14 19 +#define S21 3 +#define S22 5 +#define S23 9 +#define S24 13 +#define S31 3 +#define S32 9 +#define S33 11 +#define S34 15 +/* End MD4 Defines */ + +void MD4_NEW( unsigned char * pData, int length, unsigned char * pDigest) +{ + // access data as 4-byte word + #define uData ((UINT4 *)pData) + #define uDigest ((UINT4 *)pDigest) + + // pad word and append bit at appropriate location + #define MD4_pad_w0() (0x00000080) + #define MD4_pad_w1(data) (((data) & 0x000000FF) | 0x00008000) + #define MD4_pad_w2(data) (((data) & 0x0000FFFF) | 0x00800000) + #define MD4_pad_w3(data) (((data) & 0x00FFFFFF) | 0x80000000) + + // For the hash working space + //__attribute__((aligned(16))) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + //__declspec(align(16)) UINT4 data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + UINT4 data[MD4_DIGEST_LENGTH] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; + + // For the output result + UINT4 a,b,c,d; + + switch (length) + { + case 0: + { + data[ 0] = MD4_pad_w0(); + + data[14] = 0; + } + break; + case 1: + { + data[ 0] = MD4_pad_w1(uData[0]); + + data[14] = 1 << 3; + } + break; + case 2: + { + data[ 0] = MD4_pad_w2(uData[0]); + + data[14] = 2 << 3; + } + break; + case 3: + { + data[ 0] = MD4_pad_w3(uData[0]); + + data[14] = 3 << 3; + } + break; + case 4: + { + data[ 0] = uData[0]; + data[ 1] = MD4_pad_w0(); + + data[14] = 4 << 3; + } + break; + case 5: + { + data[ 0] = uData[0]; + data[ 1] = MD4_pad_w1(uData[1]); + + data[14] = 5 << 3; + } + break; + case 6: + { + data[ 0] = uData[0]; + data[ 1] = MD4_pad_w2(uData[1]); + + data[14] = 6 << 3; + } + break; + case 7: + { + data[ 0] = uData[0]; + data[ 1] = MD4_pad_w3(uData[1]); + + data[14] = 7 << 3; + } + break; + case 8: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = MD4_pad_w0(); + + data[14] = 8 << 3; + } + break; + case 9: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = MD4_pad_w1(uData[2]); + + data[14] = 9 << 3; + } + break; + case 10: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = MD4_pad_w2(uData[2]); + + data[14] = 10 << 3; + } + break; + case 11: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = MD4_pad_w3(uData[2]); + + data[14] = 11 << 3; + } + break; + case 12: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = uData[2]; + data[ 3] = MD4_pad_w0(); + + data[14] = 12 << 3; + } + break; + case 13: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = uData[2]; + data[ 3] = MD4_pad_w1(uData[3]); + + data[14] = 13 << 3; + } + break; + case 14: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = uData[2]; + data[ 3] = MD4_pad_w2(uData[3]); + + data[14] = 14 << 3; + } + break; + case 15: + { + data[ 0] = uData[0]; + data[ 1] = uData[1]; + data[ 2] = uData[2]; + data[ 3] = MD4_pad_w3(uData[3]); + + data[14] = 15 << 3; + } + break; + + default: + { + length = length % 32; // lenght >= 32 not suported + + int word = length >> 2; + + int i = 0; + while (i < word) { + data[i] = uData[i]; + i++; + } + + switch (length & 0x3) { + case 0: + { + data[word] = MD4_pad_w0(); + } + break; + case 1: + { + data[word] = MD4_pad_w1(uData[word]); + } + break; + case 2: + { + data[word] = MD4_pad_w2(uData[word]); + } + break; + case 3: + { + data[word] = MD4_pad_w3(uData[word]); + } + break; + } + + data[14] = length << 3; + } + break; + } + + a = 0x67452301; + b = 0xefcdab89; + c = 0x98badcfe; + d = 0x10325476; + + /* Round 1 */ + FF (a, b, c, d, data[ 0], S11); /* 1 */ + FF (d, a, b, c, data[ 1], S12); /* 2 */ + FF (c, d, a, b, data[ 2], S13); /* 3 */ + FF (b, c, d, a, data[ 3], S14); /* 4 */ + FF (a, b, c, d, data[ 4], S11); /* 5 */ + FF (d, a, b, c, data[ 5], S12); /* 6 */ + FF (c, d, a, b, data[ 6], S13); /* 7 */ + FF (b, c, d, a, data[ 7], S14); /* 8 */ + FF (a, b, c, d, 0, S11); /* 9 */ + FF (d, a, b, c, 0, S12); /* 10 */ + FF (c, d, a, b, 0, S13); /* 11 */ + FF (b, c, d, a, 0, S14); /* 12 */ + FF (a, b, c, d, 0, S11); /* 13 */ + FF (d, a, b, c, 0, S12); /* 14 */ + FF (c, d, a, b, data[14], S13); /* 15 */ + FF (b, c, d, a, 0, S14); /* 16 */ + + /* Round 2 */ + GG (a, b, c, d, data[ 0], S21); /* 17 */ + GG (d, a, b, c, data[ 4], S22); /* 18 */ + GG (c, d, a, b, 0, S23); /* 19 */ + GG (b, c, d, a, 0, S24); /* 20 */ + GG (a, b, c, d, data[ 1], S21); /* 21 */ + GG (d, a, b, c, data[ 5], S22); /* 22 */ + GG (c, d, a, b, 0, S23); /* 23 */ + GG (b, c, d, a, 0, S24); /* 24 */ + GG (a, b, c, d, data[ 2], S21); /* 25 */ + GG (d, a, b, c, data[ 6], S22); /* 26 */ + GG (c, d, a, b, 0, S23); /* 27 */ + GG (b, c, d, a, data[14], S24); /* 28 */ + GG (a, b, c, d, data[ 3], S21); /* 29 */ + GG (d, a, b, c, data[ 7], S22); /* 30 */ + GG (c, d, a, b, 0, S23); /* 31 */ + GG (b, c, d, a, 0, S24); /* 32 */ + + /* Round 3 */ + HH (a, b, c, d, data[ 0], S31); /* 33 */ + HH (d, a, b, c, 0, S32); /* 34 */ + HH (c, d, a, b, data[ 4], S33); /* 35 */ + HH (b, c, d, a, 0, S34); /* 36 */ + HH (a, b, c, d, data[ 2], S31); /* 37 */ + HH (d, a, b, c, 0, S32); /* 38 */ + HH (c, d, a, b, data[ 6], S33); /* 39 */ + HH (b, c, d, a, data[14], S34); /* 40 */ + HH (a, b, c, d, data[ 1], S31); /* 41 */ + HH (d, a, b, c, 0, S32); /* 42 */ + HH (c, d, a, b, data[ 5], S33); /* 43 */ + HH (b, c, d, a, 0, S34); /* 44 */ + HH (a, b, c, d, data[ 3], S31); /* 45 */ + HH (d, a, b, c, 0, S32); /* 46 */ + HH (c, d, a, b, data[ 7], S33); /* 47 */ + HH (b, c, d, a, 0, S34); /* 48 */ + + // Finally, add initial values, as this is the only pass we make. + a += 0x67452301; + b += 0xefcdab89; + c += 0x98badcfe; + d += 0x10325476; + + uDigest[0] = a; + uDigest[1] = b; + uDigest[2] = c; + uDigest[3] = d; +} diff --git a/Client Applications/rcracki_mt/md4.h b/Client Applications/rcracki_mt/md4.h index 91753cb..aeb3822 100644 --- a/Client Applications/rcracki_mt/md4.h +++ b/Client Applications/rcracki_mt/md4.h @@ -1,35 +1,35 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright Bitweasil - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef MD4_H -#define MD4_H - -#include "global.h" - -#define MD4_DIGEST_LENGTH 16 - -//Main function -void MD4_NEW( unsigned char * buf, int len, unsigned char * pDigest); - -#endif /* !MD4_H */ +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright Bitweasil + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef MD4_H +#define MD4_H + +#include "global.h" + +#define MD4_DIGEST_LENGTH 16 + +//Main function +void MD4_NEW( unsigned char * buf, int len, unsigned char * pDigest); + +#endif /* !MD4_H */ diff --git a/Client Applications/rcracki_mt/rcrackiThread.cpp b/Client Applications/rcracki_mt/rcrackiThread.cpp index 0b64a7a..e2d6f72 100644 --- a/Client Applications/rcracki_mt/rcrackiThread.cpp +++ b/Client Applications/rcracki_mt/rcrackiThread.cpp @@ -1,247 +1,247 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#if defined(_WIN32) && !defined(__GNUC__) - #pragma warning(disable : 4786 4267 4018) -#endif - -#include "rcrackiThread.h" - -// create job for pre-calculation -rcrackiThread::rcrackiThread(unsigned char* TargetHash, int thread_id, int nRainbowChainLen, int thread_count, uint64* pStartPosIndexE) -{ - t_TargetHash = TargetHash; - t_nRainbowChainLen = nRainbowChainLen; - t_ID = thread_id; - t_count = thread_count; - t_pStartPosIndexE = pStartPosIndexE; - t_nChainWalkStep = 0; - falseAlarmChecker = false; - falseAlarmCheckerO = false; -} - -// create job for false alarm checking -rcrackiThread::rcrackiThread(unsigned char* pHash, bool oldFormat) -{ - falseAlarmChecker = true; - falseAlarmCheckerO = oldFormat; - t_pChainsFound.clear(); - t_nGuessedPoss.clear(); - t_pHash = pHash; - t_nChainWalkStepDueToFalseAlarm = 0; - t_nFalseAlarm = 0; - foundHash = false; -} - -void rcrackiThread::AddAlarmCheck(RainbowChain* pChain, int nGuessedPos) -{ - t_pChainsFound.push_back(pChain); - t_nGuessedPoss.push_back(nGuessedPos); -} - -void rcrackiThread::AddAlarmCheckO(RainbowChainO* pChain, int nGuessedPos) -{ - t_pChainsFoundO.push_back(pChain); - t_nGuessedPoss.push_back(nGuessedPos); -} - -// Windows (beginthreadex) way of threads -//unsigned __stdcall rcrackiThread::rcrackiThreadStaticEntryPoint(void * pThis) -//{ -// rcrackiThread* pTT = (rcrackiThread*)pThis; -// pTT->rcrackiThreadEntryPoint(); -// _endthreadex( 2 ); -// return 2; -//} - -// entry point for the posix thread -void * rcrackiThread::rcrackiThreadStaticEntryPointPthread(void * pThis) -{ - rcrackiThread* pTT = (rcrackiThread*)pThis; - pTT->rcrackiThreadEntryPoint(); - pthread_exit(NULL); - return NULL; -} - -// start processing of jobs -void rcrackiThread::rcrackiThreadEntryPoint() -{ - if (falseAlarmChecker) { - if (falseAlarmCheckerO) { - CheckAlarmO(); - } - else { - CheckAlarm(); - } - } - else { - PreCalculate(); - } -} - -uint64 rcrackiThread::GetIndex(int nPos) -{ - uint64 t_index = t_vStartPosIndexE[nPos - t_ID]; - return t_index; -} - -int rcrackiThread::GetChainWalkStep() -{ - return t_nChainWalkStep; -} - -int rcrackiThread::GetIndexCount() -{ - return t_vStartPosIndexE.size(); -} - -rcrackiThread::~rcrackiThread(void) -{ -} - -void rcrackiThread::PreCalculate() -{ - for (t_nPos = t_nRainbowChainLen - 2 - t_ID; t_nPos >= 0; t_nPos -= t_count) - { - t_cwc.SetHash(t_TargetHash); - t_cwc.HashToIndex(t_nPos); - int i; - for (i = t_nPos + 1; i <= t_nRainbowChainLen - 2; i++) - { - t_cwc.IndexToPlain(); - t_cwc.PlainToHash(); - t_cwc.HashToIndex(i); - } - t_pStartPosIndexE[t_nPos] = t_cwc.GetIndex(); - t_nChainWalkStep += t_nRainbowChainLen - 2 - t_nPos; - } -} - -void rcrackiThread::CheckAlarm() -{ - UINT4 i; - for (i = 0; i < t_pChainsFound.size(); i++) - { - RainbowChain* t_pChain = t_pChainsFound[i]; - int t_nGuessedPos = t_nGuessedPoss[i]; - - CChainWalkContext cwc; - //uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFF; // for first 6 bytes - //uint64 nIndexS = t_pChain->nIndexS >> 16; - uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes - cwc.SetIndex(nIndexS); - //cwc.SetIndex(t_pChain->nIndexS); - int nPos; - for (nPos = 0; nPos < t_nGuessedPos; nPos++) - { - cwc.IndexToPlain(); - cwc.PlainToHash(); - cwc.HashToIndex(nPos); - } - cwc.IndexToPlain(); - cwc.PlainToHash(); - if (cwc.CheckHash(t_pHash)) - { - t_Hash = cwc.GetHash(); - t_Plain = cwc.GetPlain(); - t_Binary = cwc.GetBinary(); - - foundHash = true; - break; - } - else { - foundHash = false; - t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1; - t_nFalseAlarm++; - } - } -} - -void rcrackiThread::CheckAlarmO() -{ - UINT4 i; - for (i = 0; i < t_pChainsFoundO.size(); i++) - { - RainbowChainO* t_pChain = t_pChainsFoundO[i]; - int t_nGuessedPos = t_nGuessedPoss[i]; - - CChainWalkContext cwc; - - uint64 nIndexS = t_pChain->nIndexS; - cwc.SetIndex(nIndexS); - - int nPos; - for (nPos = 0; nPos < t_nGuessedPos; nPos++) - { - cwc.IndexToPlain(); - cwc.PlainToHash(); - cwc.HashToIndex(nPos); - } - cwc.IndexToPlain(); - cwc.PlainToHash(); - if (cwc.CheckHash(t_pHash)) - { - t_Hash = cwc.GetHash(); - t_Plain = cwc.GetPlain(); - t_Binary = cwc.GetBinary(); - - foundHash = true; - break; - } - else { - foundHash = false; - t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1; - t_nFalseAlarm++; - } - } -} - -bool rcrackiThread::FoundHash() -{ - return foundHash; -} - -int rcrackiThread::GetChainWalkStepDueToFalseAlarm() -{ - return t_nChainWalkStepDueToFalseAlarm; -} - -int rcrackiThread::GetnFalseAlarm() -{ - return t_nFalseAlarm; -} - -string rcrackiThread::GetHash() -{ - return t_Hash; -} - -string rcrackiThread::GetPlain() -{ - return t_Plain; -} - -string rcrackiThread::GetBinary() -{ - return t_Binary; -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#if defined(_WIN32) && !defined(__GNUC__) + #pragma warning(disable : 4786 4267 4018) +#endif + +#include "rcrackiThread.h" + +// create job for pre-calculation +rcrackiThread::rcrackiThread(unsigned char* TargetHash, int thread_id, int nRainbowChainLen, int thread_count, uint64* pStartPosIndexE) +{ + t_TargetHash = TargetHash; + t_nRainbowChainLen = nRainbowChainLen; + t_ID = thread_id; + t_count = thread_count; + t_pStartPosIndexE = pStartPosIndexE; + t_nChainWalkStep = 0; + falseAlarmChecker = false; + falseAlarmCheckerO = false; +} + +// create job for false alarm checking +rcrackiThread::rcrackiThread(unsigned char* pHash, bool oldFormat) +{ + falseAlarmChecker = true; + falseAlarmCheckerO = oldFormat; + t_pChainsFound.clear(); + t_nGuessedPoss.clear(); + t_pHash = pHash; + t_nChainWalkStepDueToFalseAlarm = 0; + t_nFalseAlarm = 0; + foundHash = false; +} + +void rcrackiThread::AddAlarmCheck(RainbowChain* pChain, int nGuessedPos) +{ + t_pChainsFound.push_back(pChain); + t_nGuessedPoss.push_back(nGuessedPos); +} + +void rcrackiThread::AddAlarmCheckO(RainbowChainO* pChain, int nGuessedPos) +{ + t_pChainsFoundO.push_back(pChain); + t_nGuessedPoss.push_back(nGuessedPos); +} + +// Windows (beginthreadex) way of threads +//unsigned __stdcall rcrackiThread::rcrackiThreadStaticEntryPoint(void * pThis) +//{ +// rcrackiThread* pTT = (rcrackiThread*)pThis; +// pTT->rcrackiThreadEntryPoint(); +// _endthreadex( 2 ); +// return 2; +//} + +// entry point for the posix thread +void * rcrackiThread::rcrackiThreadStaticEntryPointPthread(void * pThis) +{ + rcrackiThread* pTT = (rcrackiThread*)pThis; + pTT->rcrackiThreadEntryPoint(); + pthread_exit(NULL); + return NULL; +} + +// start processing of jobs +void rcrackiThread::rcrackiThreadEntryPoint() +{ + if (falseAlarmChecker) { + if (falseAlarmCheckerO) { + CheckAlarmO(); + } + else { + CheckAlarm(); + } + } + else { + PreCalculate(); + } +} + +uint64 rcrackiThread::GetIndex(int nPos) +{ + uint64 t_index = t_vStartPosIndexE[nPos - t_ID]; + return t_index; +} + +int rcrackiThread::GetChainWalkStep() +{ + return t_nChainWalkStep; +} + +int rcrackiThread::GetIndexCount() +{ + return t_vStartPosIndexE.size(); +} + +rcrackiThread::~rcrackiThread(void) +{ +} + +void rcrackiThread::PreCalculate() +{ + for (t_nPos = t_nRainbowChainLen - 2 - t_ID; t_nPos >= 0; t_nPos -= t_count) + { + t_cwc.SetHash(t_TargetHash); + t_cwc.HashToIndex(t_nPos); + int i; + for (i = t_nPos + 1; i <= t_nRainbowChainLen - 2; i++) + { + t_cwc.IndexToPlain(); + t_cwc.PlainToHash(); + t_cwc.HashToIndex(i); + } + t_pStartPosIndexE[t_nPos] = t_cwc.GetIndex(); + t_nChainWalkStep += t_nRainbowChainLen - 2 - t_nPos; + } +} + +void rcrackiThread::CheckAlarm() +{ + UINT4 i; + for (i = 0; i < t_pChainsFound.size(); i++) + { + RainbowChain* t_pChain = t_pChainsFound[i]; + int t_nGuessedPos = t_nGuessedPoss[i]; + + CChainWalkContext cwc; + //uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFF; // for first 6 bytes + //uint64 nIndexS = t_pChain->nIndexS >> 16; + uint64 nIndexS = t_pChain->nIndexS & 0x0000FFFFFFFFFFFFULL; // for first 6 bytes + cwc.SetIndex(nIndexS); + //cwc.SetIndex(t_pChain->nIndexS); + int nPos; + for (nPos = 0; nPos < t_nGuessedPos; nPos++) + { + cwc.IndexToPlain(); + cwc.PlainToHash(); + cwc.HashToIndex(nPos); + } + cwc.IndexToPlain(); + cwc.PlainToHash(); + if (cwc.CheckHash(t_pHash)) + { + t_Hash = cwc.GetHash(); + t_Plain = cwc.GetPlain(); + t_Binary = cwc.GetBinary(); + + foundHash = true; + break; + } + else { + foundHash = false; + t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1; + t_nFalseAlarm++; + } + } +} + +void rcrackiThread::CheckAlarmO() +{ + UINT4 i; + for (i = 0; i < t_pChainsFoundO.size(); i++) + { + RainbowChainO* t_pChain = t_pChainsFoundO[i]; + int t_nGuessedPos = t_nGuessedPoss[i]; + + CChainWalkContext cwc; + + uint64 nIndexS = t_pChain->nIndexS; + cwc.SetIndex(nIndexS); + + int nPos; + for (nPos = 0; nPos < t_nGuessedPos; nPos++) + { + cwc.IndexToPlain(); + cwc.PlainToHash(); + cwc.HashToIndex(nPos); + } + cwc.IndexToPlain(); + cwc.PlainToHash(); + if (cwc.CheckHash(t_pHash)) + { + t_Hash = cwc.GetHash(); + t_Plain = cwc.GetPlain(); + t_Binary = cwc.GetBinary(); + + foundHash = true; + break; + } + else { + foundHash = false; + t_nChainWalkStepDueToFalseAlarm += t_nGuessedPos + 1; + t_nFalseAlarm++; + } + } +} + +bool rcrackiThread::FoundHash() +{ + return foundHash; +} + +int rcrackiThread::GetChainWalkStepDueToFalseAlarm() +{ + return t_nChainWalkStepDueToFalseAlarm; +} + +int rcrackiThread::GetnFalseAlarm() +{ + return t_nFalseAlarm; +} + +string rcrackiThread::GetHash() +{ + return t_Hash; +} + +string rcrackiThread::GetPlain() +{ + return t_Plain; +} + +string rcrackiThread::GetBinary() +{ + return t_Binary; +} diff --git a/Client Applications/rcracki_mt/rcrackiThread.h b/Client Applications/rcracki_mt/rcrackiThread.h index 37fa289..a53cac2 100644 --- a/Client Applications/rcracki_mt/rcrackiThread.h +++ b/Client Applications/rcracki_mt/rcrackiThread.h @@ -1,85 +1,85 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifdef _WIN32 - #pragma once -#endif - -#include "ChainWalkContext.h" -#include "Public.h" -#include "HashSet.h" -//#include -#include - -class rcrackiThread -{ -private: - unsigned char* t_TargetHash; - int t_nPos; - int t_nRainbowChainLen; - CChainWalkContext t_cwc; - vector t_vStartPosIndexE; - int t_ID; - int t_count; - uint64* t_pStartPosIndexE; - int t_nChainWalkStep; - bool falseAlarmChecker; - bool falseAlarmCheckerO; - vector t_pChainsFound; - vector t_pChainsFoundO; - vector t_nGuessedPoss; - unsigned char* t_pHash; - bool foundHash; - int t_nChainWalkStepDueToFalseAlarm; - int t_nFalseAlarm; - string t_Hash; - string t_Plain; - string t_Binary; - -public: - rcrackiThread(unsigned char* TargetHash, int thread_id, int nRainbowChainLen, int thread_count, uint64* pStartPosIndexE); - rcrackiThread(unsigned char* pHash, bool oldFormat = false); - rcrackiThread(void); - ~rcrackiThread(void); - - //void SetWork(unsigned char* TargetHash, int nPos, int nRainbowChainLen); - //static unsigned __stdcall rcrackiThread::rcrackiThreadStaticEntryPoint(void * pThis); - static void * rcrackiThreadStaticEntryPointPthread(void * pThis); - int GetIndexCount(); - int GetChainWalkStep(); - uint64 GetIndex(int nPos); - bool FoundHash(); - void AddAlarmCheck(RainbowChain* pChain, int nGuessedPos); - void AddAlarmCheckO(RainbowChainO* pChain, int nGuessedPos); - int GetChainWalkStepDueToFalseAlarm(); - int GetnFalseAlarm(); - string GetHash(); - string GetPlain(); - string GetBinary(); - -private: - void rcrackiThreadEntryPoint(); - void PreCalculate(); - void CheckAlarm(); - void CheckAlarmO(); -}; +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifdef _WIN32 + #pragma once +#endif + +#include "ChainWalkContext.h" +#include "Public.h" +#include "HashSet.h" +//#include +#include + +class rcrackiThread +{ +private: + unsigned char* t_TargetHash; + int t_nPos; + int t_nRainbowChainLen; + CChainWalkContext t_cwc; + vector t_vStartPosIndexE; + int t_ID; + int t_count; + uint64* t_pStartPosIndexE; + int t_nChainWalkStep; + bool falseAlarmChecker; + bool falseAlarmCheckerO; + vector t_pChainsFound; + vector t_pChainsFoundO; + vector t_nGuessedPoss; + unsigned char* t_pHash; + bool foundHash; + int t_nChainWalkStepDueToFalseAlarm; + int t_nFalseAlarm; + string t_Hash; + string t_Plain; + string t_Binary; + +public: + rcrackiThread(unsigned char* TargetHash, int thread_id, int nRainbowChainLen, int thread_count, uint64* pStartPosIndexE); + rcrackiThread(unsigned char* pHash, bool oldFormat = false); + rcrackiThread(void); + ~rcrackiThread(void); + + //void SetWork(unsigned char* TargetHash, int nPos, int nRainbowChainLen); + //static unsigned __stdcall rcrackiThread::rcrackiThreadStaticEntryPoint(void * pThis); + static void * rcrackiThreadStaticEntryPointPthread(void * pThis); + int GetIndexCount(); + int GetChainWalkStep(); + uint64 GetIndex(int nPos); + bool FoundHash(); + void AddAlarmCheck(RainbowChain* pChain, int nGuessedPos); + void AddAlarmCheckO(RainbowChainO* pChain, int nGuessedPos); + int GetChainWalkStepDueToFalseAlarm(); + int GetnFalseAlarm(); + string GetHash(); + string GetPlain(); + string GetBinary(); + +private: + void rcrackiThreadEntryPoint(); + void PreCalculate(); + void CheckAlarm(); + void CheckAlarmO(); +}; diff --git a/Client Applications/rcracki_mt/rcracki_mt.ini b/Client Applications/rcracki_mt/rcracki_mt.ini index 27ab17e..17edb0a 100644 --- a/Client Applications/rcracki_mt/rcracki_mt.ini +++ b/Client Applications/rcracki_mt/rcracki_mt.ini @@ -1,33 +1,33 @@ -# Default settings for rcracki_mt -# Command line arguments override these defaults - -# Specify default amount of threads -Threads=1 - -# Set a default file to store temporary results. -# Set AlwaysStoreResultsToFile=1 or use -o to actually store results. -DefaultResultsFile=e:\default_rcracki_results.txt - -# This option requires DefaultResultsFile to be set to a file -#AlwaysStoreResultsToFile=1 - -# Set some default file locations to search for rainbow tables. -# You need to use these in combination with the command line argument -a [algorithm] -# Or you can set a default algorithm here with 'DefaultAlgorithm'. -# Algorithm is the name you use as specifier after 'DefaultRainbowTablesPath.' -# You can specify multiple lines per algorithm, one path/directory per line. -# Any locations you specify on the command line will be added to the list as well. -# For Windows users: locations in this file with a different case -# as on the command line are treated as separate locations (run through twice) -#DefaultRainbowTablePath.MD5=X:\RTI\MD5 -#DefaultRainbowTablePath.NTLM=X:\RTI\NTLM\ntlm_loweralpha-space#1-9_* - -# This option requires at least one 'DefaultRainbowTablePath.[algorithm]' to be set -#DefaultAlgorithm=MD5 - -# Always show debugging infomation (command line option -v) -# AlwaysDebug=1 - -# Always keep precalculation files after cracking, don't remove them. -# These files are saved by session name. So you can store precalculations over multiple jobs. +# Default settings for rcracki_mt +# Command line arguments override these defaults + +# Specify default amount of threads +Threads=1 + +# Set a default file to store temporary results. +# Set AlwaysStoreResultsToFile=1 or use -o to actually store results. +DefaultResultsFile=e:\default_rcracki_results.txt + +# This option requires DefaultResultsFile to be set to a file +#AlwaysStoreResultsToFile=1 + +# Set some default file locations to search for rainbow tables. +# You need to use these in combination with the command line argument -a [algorithm] +# Or you can set a default algorithm here with 'DefaultAlgorithm'. +# Algorithm is the name you use as specifier after 'DefaultRainbowTablesPath.' +# You can specify multiple lines per algorithm, one path/directory per line. +# Any locations you specify on the command line will be added to the list as well. +# For Windows users: locations in this file with a different case +# as on the command line are treated as separate locations (run through twice) +#DefaultRainbowTablePath.MD5=X:\RTI\MD5 +#DefaultRainbowTablePath.NTLM=X:\RTI\NTLM\ntlm_loweralpha-space#1-9_* + +# This option requires at least one 'DefaultRainbowTablePath.[algorithm]' to be set +#DefaultAlgorithm=MD5 + +# Always show debugging infomation (command line option -v) +# AlwaysDebug=1 + +# Always keep precalculation files after cracking, don't remove them. +# These files are saved by session name. So you can store precalculations over multiple jobs. #AlwaysKeepPrecalcFiles=1 \ No newline at end of file diff --git a/Client Applications/rcracki_mt/sha1.cpp b/Client Applications/rcracki_mt/sha1.cpp index 40c0e9f..ea8ef5b 100644 --- a/Client Applications/rcracki_mt/sha1.cpp +++ b/Client Applications/rcracki_mt/sha1.cpp @@ -1,348 +1,348 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright Martin Westergaard Jørgensen - * Copyright Wei Dai - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -//#include -#if defined(_WIN32) - #include -#endif - -#include - -#include "sha1.h" - -#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits)))) - -// this rotate isn't faster with me -#if defined(_WIN32) - #define ROTATE(a,n) _lrotl(a,n) -#else - #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) -#endif - -/* A nice byte order reversal from Wei Dai */ -#if defined(_WIN32) -/* 5 instructions with rotate instruction, else 9 */ -#define Endian_Reverse32(a) \ - { \ - unsigned long l=(a); \ - (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \ - } -#else -/* 6 instructions with rotate instruction, else 8 */ -#define Endian_Reverse32(a) \ - { \ - unsigned long l=(a); \ - l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \ - (a)=ROTATE(l,16L); \ - } -#endif - -#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) -#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) -#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) -#define F_60_79(b,c,d) F_20_39(b,c,d) - -#define K0 0x5A827999 -#define K1 0x6ED9EBA1 -#define K2 0x8F1BBCDC -#define K3 0xCA62C1D6 - -#define H0 0x67452301 -#define H1 0xEFCDAB89 -#define H2 0x98BADCFE -#define H3 0x10325476 -#define H4 0xC3D2E1F0 - -#define SHA1HashSize 20 - -void SHA1_NEW( unsigned char * pData, int length, unsigned char * pDigest) -{ - if (length > 16) - return; - - UINT4 Message_Block_Index = 0; - - union - { - unsigned char Message_Block[64]; - UINT4 Message_Block_W[16]; - }; - - Message_Block_W[0] = 0x00000000; - Message_Block_W[1] = 0x00000000; - Message_Block_W[2] = 0x00000000; - Message_Block_W[3] = 0x00000000; - Message_Block_W[4] = 0x00000000; - - UINT4 Intermediate_Hash[5] = { H0, H1, H2, H3, H4 }; - - memcpy(Message_Block, pData, length); - Message_Block_Index += length; - - //padMessage - Message_Block[length] = 0x80; - - UINT4 W_15 = length << 3; - - int t; /* Loop counter */ - UINT4 temp; /* Temporary word value */ - UINT4 W[80]; /* Word sequence */ - UINT4 A, B, C, D, E; /* Word buffers */ - - /* - * Initialize the first 16 words in the array W - */ - - #define INIT(x) W[x] = Message_Block_W[x]; - - #define INIT_NULL(x) W[x] = 0; - - - Endian_Reverse32(Message_Block_W[0]); - INIT(0); - - #define INIT_NULL_1_14 \ - INIT_NULL(1); INIT_NULL_2_14; - - #define INIT_NULL_2_14 \ - INIT_NULL(2); INIT_NULL_3_14; - - #define INIT_NULL_3_14 \ - INIT_NULL(3); INIT_NULL_4_14; - - #define INIT_NULL_4_14 \ - INIT_NULL(4); INIT_NULL_5_14; - - #define INIT_NULL_5_14 \ - INIT_NULL(5); INIT_NULL(6); INIT_NULL(7); \ - INIT_NULL(8); INIT_NULL(9); INIT_NULL(10); INIT_NULL(11); \ - INIT_NULL(12); INIT_NULL(13); INIT_NULL(14); - - #define ROTATE1_NULL_5_14 \ - ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \ - ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \ - ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; - - - #define EXPAND(t) \ - W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); \ - - #define EXPAND_3(t) W[t] = SHA1CircularShift(1,W[t-3]); - #define EXPAND_16(t) W[t] = SHA1CircularShift(1,W[t-16]); - #define EXPAND_3_8(t) W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8]); - - if (length < 4) { - INIT_NULL_1_14; - W[15] = W_15; - EXPAND_16(16); - W[17] = 0; - W[18] = W_15<<1; - } - else if (length < 8) { - Endian_Reverse32(Message_Block_W[1]); - INIT(1); - INIT_NULL_2_14; - W[15] = W_15; - EXPAND_16(16); - EXPAND_16(17); - W[18] = W_15<<1; - } - else { - Endian_Reverse32(Message_Block_W[1]); - Endian_Reverse32(Message_Block_W[2]); - Endian_Reverse32(Message_Block_W[3]); - Endian_Reverse32(Message_Block_W[4]); - INIT(1); INIT(2); INIT(3); INIT(4); - INIT_NULL_5_14; - W[15] = W_15; - EXPAND(16); - EXPAND(17); - EXPAND(18); - } - - if (length < 12) { - EXPAND_3(19); - } - else { - EXPAND(19); - } - - if (length < 16) { - EXPAND_3(20); - } - else { - EXPAND(20); - } - EXPAND_3(21); EXPAND_3(22); - EXPAND(23); - - EXPAND(24); EXPAND(25); EXPAND_3_8(26); EXPAND_3_8(27); - EXPAND(28); EXPAND(29); EXPAND(30); EXPAND(31); - EXPAND(32); EXPAND(33); EXPAND(34); EXPAND(35); - EXPAND(36); EXPAND(37); EXPAND(38); EXPAND(39); - EXPAND(40); EXPAND(41); EXPAND(42); EXPAND(43); - EXPAND(44); EXPAND(45); EXPAND(46); EXPAND(47); - EXPAND(48); EXPAND(49); EXPAND(50); EXPAND(51); - EXPAND(52); EXPAND(53); EXPAND(54); EXPAND(55); - EXPAND(56); EXPAND(57); EXPAND(58); EXPAND(59); - EXPAND(60); EXPAND(61); EXPAND(62); EXPAND(63); - EXPAND(64); EXPAND(65); EXPAND(66); EXPAND(67); - EXPAND(68); EXPAND(69); EXPAND(70); EXPAND(71); - EXPAND(72); EXPAND(73); EXPAND(74); EXPAND(75); - EXPAND(76); EXPAND(77); EXPAND(78); EXPAND(79); - - - #define ROTATE1_NEW(a, b, c, d, e, x) \ - e += SHA1CircularShift(5,a) + F_00_19(b,c,d) + x + K0; \ - b = SHA1CircularShift(30,b); - - #define ROTATE1_NULL \ - temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + E + K0; \ - E = D; D = C; \ - C = SHA1CircularShift(30,B); \ - B = A; A = temp; \ - - #define ROTATE2_NEW(a, b, c, d, e, x) \ - e += SHA1CircularShift(5,a) + F_20_39(b,c,d) + x + K1; \ - b = SHA1CircularShift(30,b); - - #define ROTATE2(t) \ - temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + W[t] + K1; \ - E = D; D = C; \ - C = SHA1CircularShift(30,B); \ - B = A; A = temp; - - #define ROTATE2_W(w) \ - temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + w + K1; \ - E = D; D = C; \ - C = SHA1CircularShift(30,B); \ - B = A; A = temp; - - #define ROTATE3(t) \ - temp = SHA1CircularShift(5,A) + F_40_59(B,C,D) + E + W[t] + K2; \ - E = D; D = C; \ - C = SHA1CircularShift(30,B); \ - B = A; A = temp; - - #define ROTATE4(t) \ - temp = SHA1CircularShift(5,A) + F_60_79(B,C,D) + E + W[t] + K3; \ - E = D; D = C; \ - C = SHA1CircularShift(30,B); \ - B = A; A = temp; - - A = H0; - B = H1; - C = H2; - D = H3; - E = H4; - - - E = H2; - //D = 2079550178; - //C = 1506887872; - B = 2679412915u + W[0]; - if (length < 4) { - A = SHA1CircularShift(5,B) + 1722862861; - } - else { - A = SHA1CircularShift(5,B) + 1722862861 + W[1]; - } - - if (length < 8) { - temp = SHA1CircularShift(5,A) + ((((1506887872) ^ (2079550178)) & (B)) ^ (2079550178)) + H2 + K0; - } - else { - temp = SHA1CircularShift(5,A) + (((572662306) & (B)) ^ (2079550178)) + H2 + K0 + W[2]; - } - C = SHA1CircularShift(30,B); //SHA1CircularShift(30,(2679412915 + W[0])); - B = A; - A = temp; - - if (length < 12) { - temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0; - } - else { - temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0 + W[3]; - } - E = 1506887872; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - - if (length < 16) { - temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0; - } - else { - temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0 + W[4]; - } - E = D; - D = C; - C = SHA1CircularShift(30,B); - B = A; - A = temp; - - ROTATE1_NULL_5_14; - - ROTATE1_NEW( A, B, C, D, E, W_15 ); - ROTATE1_NEW( E, A, B, C, D, W[16] ); - ROTATE1_NEW( D, E, A, B, C, W[17] ); - ROTATE1_NEW( C, D, E, A, B, W[18] ); - ROTATE1_NEW( B, C, D, E, A, W[19] ); - - for(t = 20; t < 40; t++) - { - if (t == 21 && length < 8) { - ROTATE2_W((length<<5)); // *32 - } - else { - ROTATE2(t); - } - } - - for(t = 40; t < 60; t++) - { - ROTATE3(t); - } - - for(t = 60; t < 80; t++) - { - ROTATE4(t); - } - - Intermediate_Hash[0] += A; - Intermediate_Hash[1] += B; - Intermediate_Hash[2] += C; - Intermediate_Hash[3] += D; - Intermediate_Hash[4] += E; - - Endian_Reverse32(Intermediate_Hash[0]); - Endian_Reverse32(Intermediate_Hash[1]); - Endian_Reverse32(Intermediate_Hash[2]); - Endian_Reverse32(Intermediate_Hash[3]); - Endian_Reverse32(Intermediate_Hash[4]); - - memcpy(pDigest, Intermediate_Hash, 20); -} +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright Martin Westergaard Jørgensen + * Copyright Wei Dai + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +//#include +#if defined(_WIN32) + #include +#endif + +#include + +#include "sha1.h" + +#define SHA1CircularShift(bits,word) (((word) << (bits)) | ((word) >> (32-(bits)))) + +// this rotate isn't faster with me +#if defined(_WIN32) + #define ROTATE(a,n) _lrotl(a,n) +#else + #define ROTATE(a,n) (((a)<<(n))|(((a)&0xffffffff)>>(32-(n)))) +#endif + +/* A nice byte order reversal from Wei Dai */ +#if defined(_WIN32) +/* 5 instructions with rotate instruction, else 9 */ +#define Endian_Reverse32(a) \ + { \ + unsigned long l=(a); \ + (a)=((ROTATE(l,8)&0x00FF00FF)|(ROTATE(l,24)&0xFF00FF00)); \ + } +#else +/* 6 instructions with rotate instruction, else 8 */ +#define Endian_Reverse32(a) \ + { \ + unsigned long l=(a); \ + l=(((l&0xFF00FF00)>>8L)|((l&0x00FF00FF)<<8L)); \ + (a)=ROTATE(l,16L); \ + } +#endif + +#define F_00_19(b,c,d) ((((c) ^ (d)) & (b)) ^ (d)) +#define F_20_39(b,c,d) ((b) ^ (c) ^ (d)) +#define F_40_59(b,c,d) (((b) & (c)) | (((b)|(c)) & (d))) +#define F_60_79(b,c,d) F_20_39(b,c,d) + +#define K0 0x5A827999 +#define K1 0x6ED9EBA1 +#define K2 0x8F1BBCDC +#define K3 0xCA62C1D6 + +#define H0 0x67452301 +#define H1 0xEFCDAB89 +#define H2 0x98BADCFE +#define H3 0x10325476 +#define H4 0xC3D2E1F0 + +#define SHA1HashSize 20 + +void SHA1_NEW( unsigned char * pData, int length, unsigned char * pDigest) +{ + if (length > 16) + return; + + UINT4 Message_Block_Index = 0; + + union + { + unsigned char Message_Block[64]; + UINT4 Message_Block_W[16]; + }; + + Message_Block_W[0] = 0x00000000; + Message_Block_W[1] = 0x00000000; + Message_Block_W[2] = 0x00000000; + Message_Block_W[3] = 0x00000000; + Message_Block_W[4] = 0x00000000; + + UINT4 Intermediate_Hash[5] = { H0, H1, H2, H3, H4 }; + + memcpy(Message_Block, pData, length); + Message_Block_Index += length; + + //padMessage + Message_Block[length] = 0x80; + + UINT4 W_15 = length << 3; + + int t; /* Loop counter */ + UINT4 temp; /* Temporary word value */ + UINT4 W[80]; /* Word sequence */ + UINT4 A, B, C, D, E; /* Word buffers */ + + /* + * Initialize the first 16 words in the array W + */ + + #define INIT(x) W[x] = Message_Block_W[x]; + + #define INIT_NULL(x) W[x] = 0; + + + Endian_Reverse32(Message_Block_W[0]); + INIT(0); + + #define INIT_NULL_1_14 \ + INIT_NULL(1); INIT_NULL_2_14; + + #define INIT_NULL_2_14 \ + INIT_NULL(2); INIT_NULL_3_14; + + #define INIT_NULL_3_14 \ + INIT_NULL(3); INIT_NULL_4_14; + + #define INIT_NULL_4_14 \ + INIT_NULL(4); INIT_NULL_5_14; + + #define INIT_NULL_5_14 \ + INIT_NULL(5); INIT_NULL(6); INIT_NULL(7); \ + INIT_NULL(8); INIT_NULL(9); INIT_NULL(10); INIT_NULL(11); \ + INIT_NULL(12); INIT_NULL(13); INIT_NULL(14); + + #define ROTATE1_NULL_5_14 \ + ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \ + ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; \ + ROTATE1_NULL; ROTATE1_NULL; ROTATE1_NULL; + + + #define EXPAND(t) \ + W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); \ + + #define EXPAND_3(t) W[t] = SHA1CircularShift(1,W[t-3]); + #define EXPAND_16(t) W[t] = SHA1CircularShift(1,W[t-16]); + #define EXPAND_3_8(t) W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8]); + + if (length < 4) { + INIT_NULL_1_14; + W[15] = W_15; + EXPAND_16(16); + W[17] = 0; + W[18] = W_15<<1; + } + else if (length < 8) { + Endian_Reverse32(Message_Block_W[1]); + INIT(1); + INIT_NULL_2_14; + W[15] = W_15; + EXPAND_16(16); + EXPAND_16(17); + W[18] = W_15<<1; + } + else { + Endian_Reverse32(Message_Block_W[1]); + Endian_Reverse32(Message_Block_W[2]); + Endian_Reverse32(Message_Block_W[3]); + Endian_Reverse32(Message_Block_W[4]); + INIT(1); INIT(2); INIT(3); INIT(4); + INIT_NULL_5_14; + W[15] = W_15; + EXPAND(16); + EXPAND(17); + EXPAND(18); + } + + if (length < 12) { + EXPAND_3(19); + } + else { + EXPAND(19); + } + + if (length < 16) { + EXPAND_3(20); + } + else { + EXPAND(20); + } + EXPAND_3(21); EXPAND_3(22); + EXPAND(23); + + EXPAND(24); EXPAND(25); EXPAND_3_8(26); EXPAND_3_8(27); + EXPAND(28); EXPAND(29); EXPAND(30); EXPAND(31); + EXPAND(32); EXPAND(33); EXPAND(34); EXPAND(35); + EXPAND(36); EXPAND(37); EXPAND(38); EXPAND(39); + EXPAND(40); EXPAND(41); EXPAND(42); EXPAND(43); + EXPAND(44); EXPAND(45); EXPAND(46); EXPAND(47); + EXPAND(48); EXPAND(49); EXPAND(50); EXPAND(51); + EXPAND(52); EXPAND(53); EXPAND(54); EXPAND(55); + EXPAND(56); EXPAND(57); EXPAND(58); EXPAND(59); + EXPAND(60); EXPAND(61); EXPAND(62); EXPAND(63); + EXPAND(64); EXPAND(65); EXPAND(66); EXPAND(67); + EXPAND(68); EXPAND(69); EXPAND(70); EXPAND(71); + EXPAND(72); EXPAND(73); EXPAND(74); EXPAND(75); + EXPAND(76); EXPAND(77); EXPAND(78); EXPAND(79); + + + #define ROTATE1_NEW(a, b, c, d, e, x) \ + e += SHA1CircularShift(5,a) + F_00_19(b,c,d) + x + K0; \ + b = SHA1CircularShift(30,b); + + #define ROTATE1_NULL \ + temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + E + K0; \ + E = D; D = C; \ + C = SHA1CircularShift(30,B); \ + B = A; A = temp; \ + + #define ROTATE2_NEW(a, b, c, d, e, x) \ + e += SHA1CircularShift(5,a) + F_20_39(b,c,d) + x + K1; \ + b = SHA1CircularShift(30,b); + + #define ROTATE2(t) \ + temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + W[t] + K1; \ + E = D; D = C; \ + C = SHA1CircularShift(30,B); \ + B = A; A = temp; + + #define ROTATE2_W(w) \ + temp = SHA1CircularShift(5,A) + F_20_39(B,C,D) + E + w + K1; \ + E = D; D = C; \ + C = SHA1CircularShift(30,B); \ + B = A; A = temp; + + #define ROTATE3(t) \ + temp = SHA1CircularShift(5,A) + F_40_59(B,C,D) + E + W[t] + K2; \ + E = D; D = C; \ + C = SHA1CircularShift(30,B); \ + B = A; A = temp; + + #define ROTATE4(t) \ + temp = SHA1CircularShift(5,A) + F_60_79(B,C,D) + E + W[t] + K3; \ + E = D; D = C; \ + C = SHA1CircularShift(30,B); \ + B = A; A = temp; + + A = H0; + B = H1; + C = H2; + D = H3; + E = H4; + + + E = H2; + //D = 2079550178; + //C = 1506887872; + B = 2679412915u + W[0]; + if (length < 4) { + A = SHA1CircularShift(5,B) + 1722862861; + } + else { + A = SHA1CircularShift(5,B) + 1722862861 + W[1]; + } + + if (length < 8) { + temp = SHA1CircularShift(5,A) + ((((1506887872) ^ (2079550178)) & (B)) ^ (2079550178)) + H2 + K0; + } + else { + temp = SHA1CircularShift(5,A) + (((572662306) & (B)) ^ (2079550178)) + H2 + K0 + W[2]; + } + C = SHA1CircularShift(30,B); //SHA1CircularShift(30,(2679412915 + W[0])); + B = A; + A = temp; + + if (length < 12) { + temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0; + } + else { + temp = SHA1CircularShift(5,A) + ((((C) ^ (1506887872)) & (B)) ^ (1506887872)) + 2079550178 + K0 + W[3]; + } + E = 1506887872; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + + if (length < 16) { + temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0; + } + else { + temp = SHA1CircularShift(5,A) + F_00_19(B,C,D) + 1506887872 + K0 + W[4]; + } + E = D; + D = C; + C = SHA1CircularShift(30,B); + B = A; + A = temp; + + ROTATE1_NULL_5_14; + + ROTATE1_NEW( A, B, C, D, E, W_15 ); + ROTATE1_NEW( E, A, B, C, D, W[16] ); + ROTATE1_NEW( D, E, A, B, C, W[17] ); + ROTATE1_NEW( C, D, E, A, B, W[18] ); + ROTATE1_NEW( B, C, D, E, A, W[19] ); + + for(t = 20; t < 40; t++) + { + if (t == 21 && length < 8) { + ROTATE2_W((length<<5)); // *32 + } + else { + ROTATE2(t); + } + } + + for(t = 40; t < 60; t++) + { + ROTATE3(t); + } + + for(t = 60; t < 80; t++) + { + ROTATE4(t); + } + + Intermediate_Hash[0] += A; + Intermediate_Hash[1] += B; + Intermediate_Hash[2] += C; + Intermediate_Hash[3] += D; + Intermediate_Hash[4] += E; + + Endian_Reverse32(Intermediate_Hash[0]); + Endian_Reverse32(Intermediate_Hash[1]); + Endian_Reverse32(Intermediate_Hash[2]); + Endian_Reverse32(Intermediate_Hash[3]); + Endian_Reverse32(Intermediate_Hash[4]); + + memcpy(pDigest, Intermediate_Hash, 20); +} diff --git a/Client Applications/rcracki_mt/sha1.h b/Client Applications/rcracki_mt/sha1.h index 231077b..4e27063 100644 --- a/Client Applications/rcracki_mt/sha1.h +++ b/Client Applications/rcracki_mt/sha1.h @@ -1,33 +1,33 @@ -/* - * rcracki_mt is a multithreaded implementation and fork of the original - * RainbowCrack - * - * Copyright 2009, 2010 Daniël Niggebrugge - * Copyright 2009, 2010 James Nobis - * - * 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 . - */ - -#ifndef SHA1_H -#define SHA1_H - -#include "global.h" - -#define SHA1_DIGEST_LENGTH 20 - -void SHA1_NEW( unsigned char * pData, int length, unsigned char * pDigest); - -#endif /* !SHA1_H */ +/* + * rcracki_mt is a multithreaded implementation and fork of the original + * RainbowCrack + * + * Copyright 2009, 2010 Daniël Niggebrugge + * Copyright 2009, 2010 James Nobis + * + * 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 . + */ + +#ifndef SHA1_H +#define SHA1_H + +#include "global.h" + +#define SHA1_DIGEST_LENGTH 20 + +void SHA1_NEW( unsigned char * pData, int length, unsigned char * pDigest); + +#endif /* !SHA1_H */ -- 2.39.2