#include
#include
#include
#include
unsigned int fletcher32(char * data,unsigned int len);
bool compare(std::map::value_type &i1, std::map::value_type &i2)
{
return i1.second < i2.second;
}
int main(int argc, char** argv)
{
if (argc < 2)
{
printf("No file given.\n");
return 1;
}
std::ifstream fIn;
fIn.open(argv[1],std::ios_base::binary);
if (!fIn)
{
printf("Error opening file.\n");
fIn.close();
return 1;
}
//get size of file
unsigned int ifSize;
fIn.seekg(0x0,std::ios_base::end);
ifSize = fIn.tellg();
fIn.seekg(0x0,std::ios_base::beg);
//Verify valid filesize.
if (!((ifSize%512) == 0))
{
printf("Filesize invalid, uneven chunk size.\n");
fIn.close();
return 1;
}
//Calculate Chunk count
unsigned int iChunkCount;
iChunkCount = ifSize/512;
printf("%i Chunks Detected\n",iChunkCount);
//Hash table:chunk array
std::map vChunks;
//temp map to detect most common element.
std::map vTemp;
unsigned int iHash = 0;
char * cChunk;
//Hash chunks and filter out 0xFF chunks.
for (int i = 0; i < iChunkCount; i++)
{
cChunk = new char[512];
fIn.read(cChunk,512);
iHash = fletcher32(cChunk,512);
//if the hash matches that of a 0xFF chunk
if (iHash == 4278058495)
{
delete [] cChunk;
continue; // Move on.
}
printf("Block %i:hash %u\n",i,iHash);
vChunks.insert(std::pair(iHash,cChunk));
//increase count.
//this is used to detect the highest and most common hash value in the file.
vTemp[iHash] += 1;
}
//now to find the most common chunk in by finding the highest value in vTemp
std::map::iterator iCommon = std::max_element(vTemp.begin(),vTemp.end(),compare);
char * key = vChunks[iCommon->first];
printf("XOR key found. Block hash %u.\nSaving to key.bin\n",iCommon->first);
std::ofstream fOut;
fOut.open("key.bin",std::ios::binary);
fOut.write(key,512);
fOut.close();
//Cleanup
for (std::map::const_iterator it = vChunks.begin();
it != vChunks.end();
it++)
{
delete [] it->second;
}
fIn.close();
return 0;
}
unsigned int fletcher32(char *data, unsigned int len )
{
unsigned int sum1 = 0xffff, sum2 = 0xffff;
while (len) {
unsigned int tlen = len > 360 ? 360 : len;
len -= tlen;
do {
sum1 += *data++;
sum2 += sum1;
tlen -= sizeof( unsigned char );
} while (tlen);
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
}
/* Second reduction step to reduce sums to 16 bits */
sum1 = (sum1 & 0xffff) + (sum1 >> 16);
sum2 = (sum2 & 0xffff) + (sum2 >> 16);
return sum2