static void Test(string hash, string[] strings) { if (hash.StartsWith("0x", StringComparison.CurrentCultureIgnoreCase)) { uint fnv; bool match = false; if (uint.TryParse(hash.Substring(2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out fnv)) { foreach (string str in strings) { uint strHash = Checksum.FFnv32(str); if (strHash == fnv) { Console.WriteLine($"Match! :> {hash} : {str}"); } } if (!match) { Console.WriteLine("No matches :<"); } return; } } Console.WriteLine("Badly formatted hash, please us this format: 0xAABBCCDD"); }
static void Generate(FileInfo input, FileInfo output) { List <string> files = new List <string>(); if (Directory.Exists(input.FullName)) { files = Directory.GetFiles(input.FullName, "*.sd2", SearchOption.AllDirectories).ToList(); } else if (!input.Exists) { Console.WriteLine("Input file does not exist!"); return; } else { files.Add(input.FullName); } HashSet <string> uniqueSet = new HashSet <string>(); List <string> uniqueStrings = new List <string>(); Result result = new Result(); StaticDB sdb; int x = 1; foreach (string sdbFile in files) { Console.WriteLine($"Parsing SDB file {x} of {files.Count}: {sdbFile}"); x++; sdb = new StaticDB(); try { sdb.Read(sdbFile); } catch (Exception) { Console.WriteLine("Parsing returned an error, maybe it's too old?"); continue; } foreach (StaticDB.Table sdbTable in sdb) { // add hashes AddHashHashToResult(sdbTable.Id); for (int col = 0; col < sdbTable.Columns.Count; col++) { StaticDB.Column sdbColumn = sdbTable.Columns[col]; AddHashHashToResult(sdbColumn.Id); // check strings if (sdbColumn.Type == StaticDB.DBType.String) { foreach (StaticDB.Row row in sdbTable) { string str = ((string)row.Fields[col]); if (str != null) { string w = str.Trim(); string lw = w.ToLower(); string uw = w.ToUpper(); if (!uniqueSet.Contains(w)) { uniqueSet.Add(w); uniqueStrings.Add(w); } if (!uniqueSet.Contains(lw)) { uniqueSet.Add(lw); uniqueStrings.Add(lw); } if (!uniqueSet.Contains(uw)) { uniqueSet.Add(uw); uniqueStrings.Add(uw); } string[] words2 = w.Split(new[] { '<', '>', '=', '"', '\\', '/', '.', '-', '_', '\0' }); foreach (string word2 in words2) { w = word2.Trim(); lw = w.ToLower(); uw = w.ToUpper(); if (!uniqueSet.Contains(w)) { uniqueSet.Add(w); uniqueStrings.Add(w); } if (!uniqueSet.Contains(lw)) { uniqueSet.Add(lw); uniqueStrings.Add(lw); } if (!uniqueSet.Contains(uw)) { uniqueSet.Add(uw); uniqueStrings.Add(uw); } } } } } } } sdb = null; GC.Collect(); } Console.WriteLine($"Found a total of {uniqueStrings.Count} unique strings!"); Console.WriteLine($"Performing dictionary attack..."); foreach (string str in uniqueStrings) { if (result.TryGetValue(Checksum.FFnv32(str), out Match match)) { if (!match.Matches.Contains(str)) { match.Matches.Add(str); if (match.BestGuess == null) { match.BestGuess = str; } } } } Console.WriteLine($"Saving results to: {output.FullName}"); result.Save(output.FullName); void AddHashHashToResult(uint hash) { if (!result.ContainsKey(hash)) { result.Add(hash, new Match()); } } }
static bool BinaryAttack(ref Result result, string[] targets, out int matches) { HashSet <string> uniqueSet = new HashSet <string>(); List <string> uniqueStrings = new List <string>(); foreach (string file in targets) { Console.WriteLine($"Looking for unique strings in {file}"); Span <byte> data = File.ReadAllBytes(file); int start = 0; int next = 0; bool found = false; int minLen = 3; while (next < data.Length) { bool valid = data[next] > 32 && data[next] < 127; if (!found) { // range of printable ascii strings if (valid) { start = next; found = true; } } else { if (!valid) { found = false; if (next - start > minLen) { string str = Encoding.UTF8.GetString(data.Slice(start, next - start)); string w = str.Trim(); string lw = w.ToLower(); string uw = w.ToUpper(); if (!uniqueSet.Contains(w)) { uniqueSet.Add(w); uniqueStrings.Add(w); } if (!uniqueSet.Contains(lw)) { uniqueSet.Add(lw); uniqueStrings.Add(lw); } if (!uniqueSet.Contains(uw)) { uniqueSet.Add(uw); uniqueStrings.Add(uw); } string[] words2 = str.Split(new[] { '<', '>', '=', '"', '\\', '/', '.', '-', '_', '\0' }); foreach (string word2 in words2) { w = word2.Trim(); lw = w.ToLower(); uw = w.ToUpper(); if (!uniqueSet.Contains(w)) { uniqueSet.Add(w); uniqueStrings.Add(w); } if (!uniqueSet.Contains(lw)) { uniqueSet.Add(lw); uniqueStrings.Add(lw); } if (!uniqueSet.Contains(uw)) { uniqueSet.Add(uw); uniqueStrings.Add(uw); } } } } } next++; } } matches = 0; if (uniqueStrings.Count > 0) { Console.WriteLine($"Performing attack with the {uniqueStrings.Count} unique strings found :>"); foreach (string str in uniqueStrings) { if (result.TryGetValue(Checksum.FFnv32(str), out Match match)) { if (!match.Matches.Contains(str)) { match.Matches.Add(str); if (match.BestGuess == null) { match.BestGuess = str; } Console.WriteLine($"Got match! 0x{Checksum.FFnv32(str).ToString("x8")} : {str}"); matches++; } } } return(true); } return(false); }
static bool DictionaryAttack(ref Result result, string[] targets, out int matches) { HashSet <string> uniqueSet = new HashSet <string>(); List <string> uniqueStrings = new List <string>(); foreach (string file in targets) { Console.WriteLine($"Looking for unique strings in {file}"); string[] words = File.ReadAllText(file).Split(new [] { ' ', '\r', '\n', '\t' }); foreach (string word in words) { string w = word.Trim(); string lw = w.ToLower(); string uw = w.ToUpper(); if (!uniqueSet.Contains(w)) { uniqueSet.Add(w); uniqueStrings.Add(w); } if (!uniqueSet.Contains(lw)) { uniqueSet.Add(lw); uniqueStrings.Add(lw); } if (!uniqueSet.Contains(uw)) { uniqueSet.Add(uw); uniqueStrings.Add(uw); } string[] words2 = w.Split(new[] { '<', '>', '=', '"', '\\', '/', '.', '-', '_', '\0' }); foreach (string word2 in words2) { w = word2.Trim(); lw = w.ToLower(); uw = w.ToUpper(); if (!uniqueSet.Contains(w)) { uniqueSet.Add(w); uniqueStrings.Add(w); } if (!uniqueSet.Contains(lw)) { uniqueSet.Add(lw); uniqueStrings.Add(lw); } if (!uniqueSet.Contains(uw)) { uniqueSet.Add(uw); uniqueStrings.Add(uw); } } } } matches = 0; if (uniqueStrings.Count > 0) { Console.WriteLine($"Performing attack with the {uniqueStrings.Count} unique strings found :>"); foreach (string str in uniqueStrings) { if (result.TryGetValue(Checksum.FFnv32(str), out Match match)) { if (!match.Matches.Contains(str)) { match.Matches.Add(str); if (match.BestGuess == null) { match.BestGuess = str; } Console.WriteLine($"Got match! 0x{Checksum.FFnv32(str).ToString("x8")} : {str}"); matches++; } } } return(true); } return(false); }