public static CalculatedSeed pullCache(int seed, ConnectionMultiplexer redis) { var db = redis.GetDatabase(); var pwdHash = new HashEntry[1]; var seedResult = new CalculatedSeed(); try { pwdHash = db.HashGetAll(Convert.ToString(seed)); seedResult = new CalculatedSeed(seed, pwdHash.ToDictionary()); } catch (RedisConnectionException) { } return(seedResult); }
private static int Main(string[] args) { var filePath = ""; var startDate = DateTime.MinValue; var startSeed = 0; var endSeed = 0; var multi = false; int fileTicks; int buffer; int offset; string outdir; var verbose = false; var delete = false; ConnectionMultiplexer redis = null; var encryptedFiles = new List <EncryptedFile>(); var result = Parser.Default.ParseArguments <Options>(args); // attempt to parse commandline options, write help if failed if (result.Tag == ParserResultType.Parsed) { var parsed = (Parsed <Options>)result; var options = parsed.Value; if (options.verbose) { verbose = true; } // load either single file or directory if (options.cryptedFilePath != null) { filePath = options.cryptedFilePath; outdir = new FileInfo(filePath).Directory.ToString(); if (File.Exists(options.cryptedFilePath)) { encryptedFiles.Add(new EncryptedFile(options.cryptedFilePath)); } else { Console.WriteLine("Error: Input file not found"); return(2); } } else if (options.dir != null) { if (Directory.Exists(options.dir)) { outdir = options.dir; if (verbose) { Console.WriteLine("Scanning directory {0} for encrypted files", options.dir); } foreach (var file in Directory.EnumerateFiles(options.dir, "*.evil*")) { encryptedFiles.Add(new EncryptedFile(file)); } if (verbose) { Console.WriteLine("Found {0} encrypted files.", encryptedFiles.Count); } } else { Console.WriteLine("Error: Invalid directory!"); return(2); } } else { Console.WriteLine("Error: Either a file or directory must be specified"); return(2); } try { startDate = Convert.ToDateTime(options.bootDate); } catch (FormatException) { Console.WriteLine("Error: Unable to parse date"); return(1); } offset = options.offset; buffer = options.buffer; if (options.multi) { multi = true; if (verbose) { Console.WriteLine("Running in multithreaded mode"); } } if (options.delete) { delete = options.delete; } if (options.redis != null) { try { redis = ConnectionMultiplexer.Connect(options.redis); } catch (RedisConnectionException) { Console.WriteLine("Warning: Unable to connect to Redis server. Disabling caching"); redis = null; } } } else { var failedParse = (NotParsed <Options>)result; return(2); } // loop through file(s) and attempt decryption foreach (var cryptFile in encryptedFiles) { fileTicks = getTicks(startDate, cryptFile.file.FullName); startSeed = fileTicks - offset - buffer; endSeed = fileTicks - offset; if (startSeed == 0 || endSeed == 0) { Console.WriteLine("Ran out of numbers!"); break; } // load encrypted file into memory cryptFile.loadBytes(); if (verbose) { Console.WriteLine("Attmepting to decrypt: {0}", cryptFile.file.Name); Console.WriteLine("Starting at seed count {0}", startSeed); } var seedResults = new List <CalculatedSeed>(); var decryptResult = false; int loopCount = 0; for (var seed = endSeed; seed > startSeed; seed--) { if (redis != null) { var db = redis.GetDatabase(); CalculatedSeed cacheHit = null; // attempt to pull from redis cache try { cacheHit = pullCache(seed, redis); } catch (Exception) { cacheHit = new CalculatedSeed(); } // check if hash was pulled, otherwise generate seed results in place, then attempt to add to redis if (cacheHit.hashValues.Count != 0) { seedResults.Add(cacheHit); } else { var pwdHashes = createPwdHashes(seed); var hashDict = pwdHashes.ToDictionary(); try { db.HashSet(Convert.ToString(seed), pwdHashes); } catch (Exception) { Console.WriteLine("Warning: Unable to write to Redis"); } seedResults.Add(new CalculatedSeed(seed, hashDict)); } } // if redis not enabled, just generate seed values and store in memory else { seedResults.Add(new CalculatedSeed(seed, createPwdHashes(seed).ToDictionary())); } // check every 10 loops so that large buffers don't suck up memory if (loopCount % 10 == 0) { decryptResult = decryptResult = tryDecrypt(cryptFile, multi, seedResults); if (decryptResult) { break; } else { if (verbose) { Console.Write("\rAttempt number: {0}", loopCount); } seedResults = new List <CalculatedSeed>(); } } loopCount++; } decryptResult = tryDecrypt(cryptFile, multi, seedResults); if (decryptResult && cryptFile.seed != 0) { Console.WriteLine("\nSuccessfully decrypted file. Writing to disk."); Console.WriteLine("Password: {0}", cryptFile.password); Console.WriteLine("Seed value: {0}", cryptFile.seed); Console.WriteLine("Seed value was off by {0} milliseconds!", calDiff(fileTicks, cryptFile.seed)); try { writeDecryptedFile(cryptFile.file.FullName, cryptFile.decryptedFilebyte); if (delete) { File.Delete(cryptFile.file.FullName); } } catch (UnauthorizedAccessException) { Console.WriteLine("Error: Unable to write decrypted file to disk. Access was denied to path."); } } else { Console.WriteLine("\nFailed to decrypt file!"); } } return(0); }