private void OnGotHash(HashGeneratorResult result) { if (!result.Success) { status = "Error: " + result.ErrorMessage; return; } var filePath = Path.Combine(Path.GetFullPath(Application.dataPath + @"\..\"), FileName); if (!File.Exists(filePath)) { status = "No super secret file found, you're cheater!\n" + filePath; return; } var allBytes = File.ReadAllBytes(filePath); var allChars = BytesToUnicodeChars(allBytes); var decrypted = ObscuredString.Decrypt(allChars, StringKey); var separatorIndex = decrypted.IndexOf(Separator, StringComparison.InvariantCulture); if (separatorIndex == -1) { status = "Super secret file is corrupted, you're cheater!"; return; } var whitelistedHashes = decrypted.Split(new[] { Separator }, StringSplitOptions.RemoveEmptyEntries); var originalSummaryHash = whitelistedHashes[0]; // compare summary hashes first if (originalSummaryHash != result.SummaryHash) { // check all files against whitelisted hashes if summary differs // (it can differ if some files are absent due to build separation) for (var i = 1; i < whitelistedHashes.Length; i++) { var hash = whitelistedHashes[i]; if (!result.HasFileHash(hash)) { status = "Code hash differs, you're cheater!\nSummary hashes:\n" + originalSummaryHash + "\n" + result.SummaryHash + "\nWhitelisted hashes count: " + whitelistedHashes.Length; return; } } } status = "All fine!"; }
private string DecryptKey(string encryptedKey) { string decryptedKey; try { var decryptedKeyChars = Base64Utils.FromBase64ToChars(encryptedKey); decryptedKey = ObscuredString.Decrypt(decryptedKeyChars, ObscuredPrefs.GetCryptoKey()); } catch { decryptedKey = string.Empty; } return(decryptedKey); }
private void OnGotHash(HashGeneratorResult result) { if (!result.Success) { status = "Error: " + result.ErrorMessage; return; } var resultingHash = result.CodeHash; var filePath = Path.Combine(Path.GetFullPath(Application.dataPath + @"\..\"), FileName); if (!File.Exists(filePath)) { status = "No super secret file found, you're cheater!\n" + filePath; return; } var allBytes = File.ReadAllBytes(filePath); var allChars = BytesToUnicodeChars(allBytes); var decrypted = ObscuredString.Decrypt(allChars, StringKey); var separatorIndex = decrypted.IndexOf(Separator, StringComparison.InvariantCulture); if (separatorIndex == -1) { status = "Super secret file is corrupted, you're cheater!"; return; } var buildHash = decrypted.Substring(0, separatorIndex); var fileHash = decrypted.Substring(separatorIndex + SeparatorLength); var currentFileHash = GetHash(buildHash + HashSalt); if (currentFileHash != fileHash) { status = "Super secret file is corrupted, you're cheater!"; return; } if (buildHash != resultingHash) { status = "Code hash differs, you're cheater!\n" + resultingHash + "\n" + buildHash; return; } status = "All fine!"; }
public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label) { MigrateUtils.MigrateObscuredStringIfNecessary(prop); var hiddenChars = prop.FindPropertyRelative("hiddenChars"); var cryptoKey = prop.FindPropertyRelative("cryptoKey"); var inited = prop.FindPropertyRelative("inited"); var fakeValue = prop.FindPropertyRelative("fakeValue"); var fakeValueActive = prop.FindPropertyRelative("fakeValueActive"); var currentCryptoKey = GetChars(cryptoKey); var val = string.Empty; if (!inited.boolValue) { if (currentCryptoKey.Length == 0) { currentCryptoKey = ObscuredString.GenerateKey(); SetChars(cryptoKey, currentCryptoKey); } inited.boolValue = true; EncryptAndSetChars(val.ToCharArray(), hiddenChars, currentCryptoKey); fakeValue.stringValue = val; } else { var size = hiddenChars.FindPropertyRelative("Array.size"); var showMixed = size.hasMultipleDifferentValues; if (!showMixed) { for (var i = 0; i < hiddenChars.arraySize; i++) { showMixed |= hiddenChars.GetArrayElementAtIndex(i).hasMultipleDifferentValues; if (showMixed) { break; } } } if (!showMixed) { var chars = new char[hiddenChars.arraySize]; for (var i = 0; i < hiddenChars.arraySize; i++) { chars[i] = (char)hiddenChars.GetArrayElementAtIndex(i).intValue; } val = ObscuredString.Decrypt(chars, currentCryptoKey); } else { EditorGUI.showMixedValue = true; } } var dataIndex = prop.propertyPath.IndexOf("Array.data[", StringComparison.Ordinal); if (dataIndex >= 0) { dataIndex += 11; var index = "Element " + prop.propertyPath.Substring(dataIndex, prop.propertyPath.IndexOf("]", dataIndex, StringComparison.Ordinal) - dataIndex); label.text = index; } label = EditorGUI.BeginProperty(position, label, prop); EditorGUI.BeginChangeCheck(); val = EditorGUI.TextField(position, label, val); if (EditorGUI.EndChangeCheck()) { EncryptAndSetChars(val.ToCharArray(), hiddenChars, currentCryptoKey); fakeValue.stringValue = val; fakeValueActive.boolValue = true; } EditorGUI.showMixedValue = false; EditorGUI.EndProperty(); }
private void LoadAndParseAllowedAssemblies() { #if ACTK_DEBUG_NORMAL Debug.Log(ACTkConstants.LogPrefix + "Starting LoadAndParseAllowedAssemblies()", this); var sw = Stopwatch.StartNew(); #endif var assembliesSignatures = (TextAsset)Resources.Load("fndid", typeof(TextAsset)); if (assembliesSignatures == null) { signaturesAreMissing = true; signaturesAreNotGenuine = true; return; } #if ACTK_DEBUG_NORMAL sw.Stop(); Debug.Log(ACTkConstants.LogPrefix + "Creating separator array and opening MemoryStream", this); sw.Start(); #endif string[] separator = { ":" }; var ms = new MemoryStream(assembliesSignatures.bytes); var br = new BinaryReader(ms, Encoding.Unicode); var count = br.ReadInt32(); #if ACTK_DEBUG_NORMAL sw.Stop(); Debug.Log(ACTkConstants.LogPrefix + "Allowed assemblies count from MS: " + count, this); sw.Start(); #endif allowedAssemblies = new AllowedAssembly[count]; for (var i = 0; i < count; i++) { var lineLength = br.ReadInt32(); var line = br.ReadChars(lineLength); #if ACTK_DEBUG_PARANOID sw.Stop(); Debug.Log(ACTkConstants.LogPrefix + "Line: " + new string(line) + ", length: " + lineLength, this); sw.Start(); #endif var lineString = ObscuredString.Decrypt(line, ACTkConstants.StringKey); #if ACTK_DEBUG_PARANOID sw.Stop(); Debug.Log(ACTkConstants.LogPrefix + "Line decrypted : " + lineString, this); sw.Start(); #endif var strArr = lineString.Split(separator, StringSplitOptions.RemoveEmptyEntries); var stringsCount = strArr.Length; #if ACTK_DEBUG_PARANOID sw.Stop(); Debug.Log(ACTkConstants.LogPrefix + "stringsCount : " + stringsCount, this); sw.Start(); #endif if (stringsCount > 1) { var assemblyName = strArr[0]; var hashes = new int[stringsCount - 1]; for (var j = 1; j < stringsCount; j++) { var parseResult = 0; var success = int.TryParse(strArr[j], out parseResult); if (success) { hashes[j - 1] = parseResult; } else { Debug.LogError(FinalLogPrefix + "Could not parse value: " + strArr[j] + ", line:\n" + lineString); } } allowedAssemblies[i] = new AllowedAssembly(assemblyName, hashes); } else { signaturesAreNotGenuine = true; br.Close(); ms.Close(); #if ACTK_DEBUG_NORMAL sw.Stop(); #endif return; } } br.Close(); ms.Close(); Resources.UnloadAsset(assembliesSignatures); #if ACTK_DEBUG_NORMAL sw.Stop(); Debug.Log(ACTkConstants.LogPrefix + "Allowed Assemblies parsing duration: " + sw.ElapsedMilliseconds + " ms.", this); #endif hexTable = new string[256]; for (var i = 0; i < 256; i++) { hexTable[i] = i.ToString("x2"); } }