private void ObscuredStringExample() { /* -------------- usage example -------------- */ // hey, Daniele! ;D var regular = "the Goscurry is not a lie ;)"; // obscured <-> regular conversion is implicit ObscuredString obscured = regular; // you can get raw encrypted value at any time // and save it somewhere for example along with encryptionKey char[] encryptionKey; var encryptedValueRaw = obscured.GetEncrypted(out encryptionKey); // to construct new obscured instance from it after loading it back var newObscured = ObscuredString.FromEncrypted(encryptedValueRaw, encryptionKey); // all other obscured types have similar usage pipeline and APIs /* -------------- logs-------------- */ logBuilder.Length = 0; logBuilder.AppendLine("[ ObscuredString example ]"); logBuilder.AppendLine("Original value:\n" + regular); logBuilder.AppendLine("Obscured value in memory:\n" + newObscured.GetEncrypted(out encryptionKey)); Debug.Log(logBuilder); }
internal static string EncryptKey(string key) { var keyChars = ObscuredString.Encrypt(key.ToCharArray(), GetCryptoKey()); key = Base64Utils.ToBase64(keyChars); return(key); }
public void UseRegular() { useRegular = true; cleanString = "Hey, you can easily change me in memory!"; obscuredString = ""; Debug.Log("Try to change this string in memory:\n" + cleanString); }
private void ObscuredStringExample() { /* -------------- usage example -------------- */ // you can change default crypto key using this method // it will be automatically used by any new ObscuredString // instances and it will be applied to any existing instance // on the value change ObscuredString.SetNewCryptoKey("I LOVE MY GIRLz"); // hey, Daniele! ;D var regular = "the Goscurry is not a lie ;)"; // obscured <-> regular conversion is implicit ObscuredString obscured = regular; // you can get raw encrypted value at any time // and save it somewhere for example var encryptedValueRaw = obscured.GetEncrypted(); // to construct new obscured instance from it after loading it back var newObscured = ObscuredString.FromEncrypted(encryptedValueRaw); // all other obscured types have similar usage pipeline and APIs /* -------------- logs-------------- */ logBuilder.Length = 0; logBuilder.AppendLine("[ ObscuredString example ]"); logBuilder.AppendLine("Original value:\n" + regular); logBuilder.AppendLine("Obscured value in memory:\n" + newObscured.GetEncrypted()); Debug.Log(logBuilder); }
public void UseObscured() { useRegular = false; obscuredString = "Hey, you can't change me in memory!"; cleanString = ""; Debug.Log("Try to change this string in memory:\n" + obscuredString); }
public ObscuredValueConverter() { list.Add(typeof(ObscuredInt), new Conv( typeof(int), o => { return((int)(ObscuredInt)o); }, o => { ObscuredInt value = Convert.ToInt32(o); return(value); } )); list.Add(typeof(ObscuredFloat), new Conv( typeof(float), o => { return((float)(ObscuredFloat)o); }, o => { ObscuredFloat value = Convert.ToSingle(o); return(value); } )); list.Add(typeof(ObscuredDouble), new Conv( typeof(double), o => { return((double)(ObscuredDouble)o); }, o => { ObscuredDouble value = Convert.ToSingle(o); return(value); } )); list.Add(typeof(ObscuredBool), new Conv( typeof(bool), o => { return((bool)(ObscuredBool)o); }, o => { ObscuredBool value = Convert.ToBoolean(o); return(value); } )); list.Add(typeof(ObscuredString), new Conv( typeof(string), o => { return((string)(ObscuredString)o); }, o => { ObscuredString value = o + ""; return(value); } )); }
internal static char[] GetCryptoKey(string dynamicSuffix = null) { if (generatedCryptoKey == null) { var savedKey = PlayerPrefs.GetString(PrefsKey); if (!string.IsNullOrEmpty(savedKey)) { generatedCryptoKey = Base64Utils.FromBase64ToChars(savedKey); } else { generatedCryptoKey = ObscuredString.GenerateKey(); var b64 = Base64Utils.ToBase64(generatedCryptoKey); PlayerPrefs.SetString(PrefsKey, b64); PlayerPrefs.Save(); } } if (string.IsNullOrEmpty(dynamicSuffix)) { return(generatedCryptoKey); } var suffixChars = dynamicSuffix.ToCharArray(); var result = new char[generatedCryptoKey.Length + suffixChars.Length]; Buffer.BlockCopy(generatedCryptoKey, 0, result, 0, generatedCryptoKey.Length); Buffer.BlockCopy(suffixChars, 0, result, generatedCryptoKey.Length + 1, suffixChars.Length); return(result); }
private static IEnumerable <AllowedAssembly> LoadAndParseLegacyWhitelist() { var result = new List <AllowedAssembly>(); string[] separator = { InjectionConstants.DataSeparator }; var fs = new FileStream(InjectionConstants.LegacyWhitelistRelativePath, FileMode.Open, FileAccess.Read, FileShare.Read); var br = new BinaryReader(fs); try { var count = br.ReadInt32(); for (var i = 0; i < count; i++) { var line = br.ReadString(); line = new string(ObscuredString.Encrypt(line, ACTkConstants.StringKey)); var strArr = line.Split(separator, StringSplitOptions.RemoveEmptyEntries); var stringsCount = strArr.Length; 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(ACTkConstants.LogPrefix + "Could not parse value: " + strArr[j] + ", line:\n" + line); } } result.Add(new AllowedAssembly(assemblyName, hashes)); } else { Debug.LogWarning(EditorTools.ConstructError("Error parsing whitelist file line!")); } } } catch (Exception e) { Debug.LogError(ACTkConstants.LogPrefix + "Error while reading legacy whitelist:\n" + e); } finally { br.Close(); fs.Close(); } return(result); }
public override void OnGUI(Rect position, SerializedProperty prop, GUIContent label) { SerializedProperty hiddenValue = prop.FindPropertyRelative("hiddenValue"); SetBoldIfValueOverridePrefab(prop, hiddenValue); SerializedProperty cryptoKey = prop.FindPropertyRelative("currentCryptoKey"); SerializedProperty fakeValue = prop.FindPropertyRelative("fakeValue"); SerializedProperty inited = prop.FindPropertyRelative("inited"); string currentCryptoKey = cryptoKey.stringValue; string val = ""; if (!inited.boolValue) { if (string.IsNullOrEmpty(currentCryptoKey)) { currentCryptoKey = cryptoKey.stringValue = ObscuredString.cryptoKeyEditor; } inited.boolValue = true; EncryptAndSetBytes(val, hiddenValue, currentCryptoKey); } else { byte[] bytes = new byte[hiddenValue.arraySize]; for (int i = 0; i < hiddenValue.arraySize; i++) { bytes[i] = (byte)hiddenValue.GetArrayElementAtIndex(i).intValue; } val = ObscuredString.EncryptDecrypt(GetString(bytes), currentCryptoKey); } int dataIndex = prop.propertyPath.IndexOf("Array.data["); if (dataIndex >= 0) { dataIndex += 11; string index = "Element " + prop.propertyPath.Substring(dataIndex, prop.propertyPath.IndexOf("]", dataIndex) - dataIndex); label.text = index; } EditorGUI.BeginChangeCheck(); val = EditorGUI.TextField(position, label, val); if (EditorGUI.EndChangeCheck()) { EncryptAndSetBytes(val, hiddenValue, currentCryptoKey); } fakeValue.stringValue = val; /*if (prop.isInstantiatedPrefab) * { * SetBoldDefaultFont(prop.prefabOverride); * }*/ }
private void SetRankInfo(ObscuredInt ranking, /*ObscuredUShort charLevel,*/ ObscuredString userName) { // 3412 {0} 위 _rank.text = string.Format(StringTableManager.GetData(3412), ranking); //_level.text = string.Format("{0}{1}", StringTableManager.GetData(12), charLevel); _level.gameObject.SetActive(false); _charName = userName; _userName.text = userName; }
private void Start() { Debug.Log("===== ObscuredStringTest =====\n"); ObscuredString.SetNewCryptoKey("I LOVE MY GIRL"); cleanString = "Try Goscurry! Or better buy it!"; Debug.Log("Original string:\n" + cleanString); obscuredString = cleanString; Debug.Log("How your string is stored in memory when obscured:\n" + obscuredString.GetEncrypted()); obscuredString = (cleanString = string.Empty); }
private static void OnHashesGenerated(BuildReport report, BuildHashes[] hashedBuilds) { Debug.Log("CodeHashGeneratorListener example listener saying hello."); var whitelistedHashes = string.Empty; // Upload hashes to the server or do anything you would like to. // // Note, you may have multiple builds each with own hashes in some cases after build, // e.g. when using "Split APKs by target architecture" option. foreach (var hashedBuild in hashedBuilds) { hashedBuild.PrintToConsole(); whitelistedHashes += hashedBuild.SummaryHash + GenuineValidatorExample.Separator; var fileHashes = hashedBuild.FileHashes; var fileHashesLength = fileHashes.Length; for (var i = 0; i < fileHashesLength; i++) { var fileHash = fileHashes[i]; whitelistedHashes += fileHash.Hash; if (i != fileHashesLength - 1) { whitelistedHashes += GenuineValidatorExample.Separator; } } } // for example, you may put hashes next to the standalone build to compare them offline // just as a proof of concept, but please consider uploading your hashes to the server // and make comparison on the server-side instead when possible to add cheaters some more pain var outputFolder = Path.GetDirectoryName(report.summary.outputPath); if (string.IsNullOrEmpty(outputFolder) || !Directory.Exists(outputFolder)) { Debug.LogError(ACTkConstants.LogPrefix + "Couldn't find build folder!"); return; } var filePath = Path.Combine(outputFolder, GenuineValidatorExample.FileName); // encrypt to hide hashes from the eye var encryptedValue = ObscuredString.Encrypt(whitelistedHashes, GenuineValidatorExample.StringKey); // now just get raw bytes and write them to the file to compare hashes in runtime var bytes = GenuineValidatorExample.UnicodeCharsToBytes(encryptedValue); File.WriteAllBytes(filePath, bytes); }
private void ObscuredStringExample() { this.logBuilder.Length = 0; this.logBuilder.AppendLine("[ACTk] <b>[ ObscuredString test ]</b>"); ObscuredString.SetNewCryptoKey("I LOVE MY GIRLz"); string text = "the Goscurry is not a lie ;)"; this.logBuilder.AppendLine("Original string:\n" + text); ObscuredString obscuredString = text; this.logBuilder.AppendLine("How your string is stored in memory when obscured:\n" + obscuredString.GetEncrypted()); Debug.Log(this.logBuilder); }
private static void EncryptAndSetBytes(string val, SerializedProperty prop, string key) { var encrypted = ObscuredString.EncryptDecrypt(val, key); var encryptedBytes = GetBytes(encrypted); prop.ClearArray(); prop.arraySize = encryptedBytes.Length; for (var i = 0; i < encryptedBytes.Length; i++) { prop.GetArrayElementAtIndex(i).intValue = encryptedBytes[i]; } }
private static void LoadAndParseWhitelist() { whitelistPath = ACTkEditorGlobalStuff.ResolveInjectionUserWhitelistPath(); if (string.IsNullOrEmpty(whitelistPath) || !File.Exists(whitelistPath)) { return; } string[] separator = { ACTkEditorGlobalStuff.InjectionDataSeparator }; var fs = new FileStream(whitelistPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); var br = new BinaryReader(fs); var count = br.ReadInt32(); for (var i = 0; i < count; i++) { var line = br.ReadString(); line = ObscuredString.EncryptDecrypt(line, "Elina"); var strArr = line.Split(separator, StringSplitOptions.RemoveEmptyEntries); var stringsCount = strArr.Length; 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("Could not parse value: " + strArr[j] + ", line:\n" + line); } } whitelist.Add(new AllowedAssembly(assemblyName, hashes)); } else { Debug.LogWarning("Error parsing whitelist file line! Please report to " + ACTkEditorGlobalStuff.ReportEmail); } } br.Close(); fs.Close(); }
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 void LoadAndParseAllowedAssemblies() { TextAsset textAsset = (TextAsset)Resources.Load("fndid", typeof(TextAsset)); if (Object.op_Equality((Object)textAsset, (Object)null)) { this.signaturesAreNotGenuine = true; } else { string[] separator = new string[1] { ":" }; MemoryStream memoryStream = new MemoryStream(textAsset.get_bytes()); BinaryReader binaryReader = new BinaryReader((Stream)memoryStream); int length1 = binaryReader.ReadInt32(); this.allowedAssemblies = new InjectionDetector.AllowedAssembly[length1]; for (int index1 = 0; index1 < length1; ++index1) { string[] strArray = ObscuredString.EncryptDecrypt(binaryReader.ReadString(), "Elina").Split(separator, StringSplitOptions.RemoveEmptyEntries); int length2 = strArray.Length; if (length2 > 1) { string name = strArray[0]; int[] hashes = new int[length2 - 1]; for (int index2 = 1; index2 < length2; ++index2) { hashes[index2 - 1] = int.Parse(strArray[index2]); } this.allowedAssemblies[index1] = new InjectionDetector.AllowedAssembly(name, hashes); } else { this.signaturesAreNotGenuine = true; binaryReader.Close(); memoryStream.Close(); return; } } binaryReader.Close(); memoryStream.Close(); Resources.UnloadAsset((Object)textAsset); this.hexTable = new string[256]; for (int index = 0; index < 256; ++index) { this.hexTable[index] = index.ToString("x2"); } } }
private void LoadAndParseAllowedAssemblies() { TextAsset textAsset = (TextAsset)Resources.Load("fndid", typeof(TextAsset)); if (textAsset == null) { signaturesAreNotGenuine = true; } else { string[] separator = new string[1] { ":" }; MemoryStream memoryStream = new MemoryStream(textAsset.bytes); BinaryReader binaryReader = new BinaryReader(memoryStream); int num = binaryReader.ReadInt32(); allowedAssemblies = new AllowedAssembly[num]; for (int i = 0; i < num; i++) { string value = binaryReader.ReadString(); value = ObscuredString.EncryptDecrypt(value, "Elina"); string[] array = value.Split(separator, StringSplitOptions.RemoveEmptyEntries); int num2 = array.Length; if (num2 <= 1) { signaturesAreNotGenuine = true; binaryReader.Close(); memoryStream.Close(); return; } string name = array[0]; int[] array2 = new int[num2 - 1]; for (int j = 1; j < num2; j++) { array2[j - 1] = int.Parse(array[j]); } allowedAssemblies[i] = new AllowedAssembly(name, array2); } binaryReader.Close(); memoryStream.Close(); Resources.UnloadAsset(textAsset); hexTable = new string[256]; for (int k = 0; k < 256; k++) { hexTable[k] = k.ToString("x2"); } } }
private static void WriteWhitelist() { if (whitelist.Count > 0) { var fileExisted = File.Exists(whitelistPath); ACTkEditorGlobalStuff.RemoveReadOnlyAttribute(whitelistPath); var fs = new FileStream(whitelistPath, FileMode.Create, FileAccess.Write, FileShare.Read); var br = new BinaryWriter(fs); br.Write(whitelist.Count); foreach (var assembly in whitelist) { var assemblyName = assembly.name; var hashes = ""; for (var j = 0; j < assembly.hashes.Length; j++) { hashes += assembly.hashes[j]; if (j < assembly.hashes.Length - 1) { hashes += ACTkEditorGlobalStuff.InjectionDataSeparator; } } var line = ObscuredString.EncryptDecrypt(assemblyName + ACTkEditorGlobalStuff.InjectionDataSeparator + hashes, "Elina"); br.Write(line); } br.Close(); fs.Close(); if (!fileExisted) { AssetDatabase.Refresh(); } } else { ACTkEditorGlobalStuff.RemoveReadOnlyAttribute(whitelistPath); FileUtil.DeleteFileOrDirectory(whitelistPath); FileUtil.DeleteFileOrDirectory(whitelistPath + ".meta"); AssetDatabase.Refresh(); } ACTkPostprocessor.InjectionAssembliesScan(); }
internal static bool MigrateObscuredStringIfNecessary(SerializedProperty sp) { var hiddenValueProperty = sp.FindPropertyRelative("hiddenValue"); if (hiddenValueProperty == null || hiddenValueProperty.arraySize == 0) { return(false); } var currentCryptoKeyOldProperty = sp.FindPropertyRelative("currentCryptoKey"); if (currentCryptoKeyOldProperty == null) { return(false); } var currentCryptoKeyOld = currentCryptoKeyOldProperty.stringValue; if (string.IsNullOrEmpty(currentCryptoKeyOld)) { return(false); } var hiddenCharsProperty = sp.FindPropertyRelative("hiddenChars"); if (hiddenCharsProperty == null || hiddenCharsProperty.arraySize == 0) { return(false); } var hiddenValue = ObscuredStringDrawer.GetBytesObsolete(hiddenValueProperty); var decrypted = ObscuredString.EncryptDecryptObsolete(ObscuredString.GetStringObsolete(hiddenValue), currentCryptoKeyOld); var currentCryptoKey = ObscuredString.GenerateKey(); var hiddenChars = ObscuredString.InternalEncryptDecrypt(decrypted.ToCharArray(), currentCryptoKey); ObscuredStringDrawer.SetChars(hiddenCharsProperty, hiddenChars); var currentCryptoKeyProperty = sp.FindPropertyRelative("cryptoKey"); ObscuredStringDrawer.SetChars(currentCryptoKeyProperty, currentCryptoKey); hiddenValueProperty.arraySize = 0; currentCryptoKeyOldProperty.stringValue = null; return(true); }
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); }
void Start() { ObscuredString token = ObscuredPrefs.GetString("LoginToken", ""); if (!string.IsNullOrEmpty(token) && !string.IsNullOrEmpty(TheStageSetting.UserName)) { int year = ObscuredPrefs.GetInt("TokenYear", 0); int day = ObscuredPrefs.GetInt("TokenDay", 0); int time = (System.DateTime.Now.Year - year) * 365 + System.DateTime.Now.Day - day; if (time < 15) { IsSignedIn = true; StartCoroutine(NetworkManager.TryLoadSongListInfo()); } } }
private string DecryptKey(string encryptedKey) { string decryptedKey; try { byte[] bytes = Convert.FromBase64String(encryptedKey); decryptedKey = Encoding.UTF8.GetString(bytes); decryptedKey = ObscuredString.EncryptDecrypt(decryptedKey, ObscuredPrefs.CryptoKey); } 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!"; }
private void TestString() { logBuilder.AppendLine("ObscuredString vs string, " + stringIterations + " iterations for read and write"); ObscuredString obscured = "abcd"; string notObscured = obscured; var dummy = ""; var sw = Stopwatch.StartNew(); for (var i = 0; i < stringIterations; i++) { dummy = obscured; } for (var i = 0; i < stringIterations; i++) { obscured = dummy; } sw.Stop(); logBuilder.AppendLine("ObscuredString:").AppendLine(sw.ElapsedMilliseconds + " ms"); sw.Reset(); sw.Start(); for (var i = 0; i < stringIterations; i++) { dummy = notObscured; } for (var i = 0; i < stringIterations; i++) { notObscured = dummy; } sw.Stop(); logBuilder.AppendLine("string:").AppendLine(sw.ElapsedMilliseconds + " ms"); if (dummy != "") { } if (obscured != "") { } if (notObscured != "") { } }
private void Start() { Debug.Log("===== ObscuredStringTest =====\n"); // example of custom crypto key using // this is not necessary! default key is "4441" ObscuredString.SetNewCryptoKey("I LOVE MY GIRL"); // just a small self-test here (hey, Daniele! :D) cleanString = "Try Goscurry! Or better buy it!"; Debug.Log("Original string:\n" + cleanString); obscuredString = cleanString; Debug.Log("How your string is stored in memory when obscured:\n" + obscuredString.GetEncrypted()); obscuredString = cleanString = ""; }
private void TestString() { Debug.Log(" Testing ObscuredString vs string preformance:\n " + stringIterations + " iterations for read and same for write"); Stopwatch sw = Stopwatch.StartNew(); ObscuredString obscured = "abcd"; string notObscured = obscured; string dummy = ""; for (int i = 0; i < stringIterations; i++) { dummy = obscured; } for (int i = 0; i < stringIterations; i++) { obscured = dummy; } Debug.Log(" ObscuredString:\n " + sw.ElapsedMilliseconds + " ms "); sw.Reset(); sw.Start(); for (int i = 0; i < stringIterations; i++) { dummy = notObscured; } for (int i = 0; i < stringIterations; i++) { notObscured = dummy; } sw.Stop(); Debug.Log(" string:\n " + sw.ElapsedMilliseconds + " ms "); if (dummy != "") { } if (obscured != "") { } if (notObscured != "") { } }
private void WriteWhiteList() { if (whiteList.Count > 0) { bool fileExisted = File.Exists(whitelistPath); ActEditorGlobalStuff.RemoveReadOnlyAttribute(whitelistPath); FileStream fs = new FileStream(whitelistPath, FileMode.Create, FileAccess.Write, FileShare.Read); BinaryWriter br = new BinaryWriter(fs); br.Write(whiteList.Count); foreach (AllowedAssembly assembly in whiteList) { string assemblyName = assembly.name; string hashes = ""; for (int j = 0; j < assembly.hashes.Length; j++) { hashes += assembly.hashes[j]; if (j < assembly.hashes.Length - 1) { hashes += ActEditorGlobalStuff.INJECTION_DATA_SEPARATOR; } } string line = ObscuredString.EncryptDecrypt(assemblyName + ActEditorGlobalStuff.INJECTION_DATA_SEPARATOR + hashes, "Elina"); br.Write(line); } br.Close(); fs.Close(); if (!fileExisted) { AssetDatabase.Refresh(); } } else { ActEditorGlobalStuff.RemoveReadOnlyAttribute(whitelistPath); FileUtil.DeleteFileOrDirectory(whitelistPath); AssetDatabase.Refresh(); } ActPostprocessor.InjectionAssembliesScan(); }
private static void OnHashesGenerate(BuildReport report, Dictionary <string, string> buildHashes) { Debug.Log("CodeHashGeneratorListener example listener saying hello."); // Upload hashes to the server or do anything you would like to. // // Note, you may have multiple builds each with own hash in some cases after build, // e.g. when using "Split APKs by target architecture" option. foreach (var buildHash in buildHashes) { Debug.Log("Build: " + buildHash.Key + "\n" + "Hash: " + buildHash.Value); } // for example, you may put hash next to the standalone build to compare it offline // just as a proof of concept, please consider uploading your hash to the server // and make comparison on the server-side to add some more pain to the cheaters\ var firstBuildHash = buildHashes.FirstOrDefault().Value; if (string.IsNullOrEmpty(firstBuildHash)) { Debug.LogError(ACTkConstants.LogPrefix + "Couldn't find first build hash!"); return; } var outputFolder = Path.GetDirectoryName(report.summary.outputPath); if (string.IsNullOrEmpty(outputFolder) || !Directory.Exists(outputFolder)) { Debug.LogError(ACTkConstants.LogPrefix + "Couldn't find build folder!"); return; } var filePath = Path.Combine(outputFolder, GenuineValidatorExample.FileName); var hashOfTheHashHaha = GenuineValidatorExample.GetHash(firstBuildHash + GenuineValidatorExample.HashSalt); // let's put together build hash with its hash and encrypt it using constant key var encryptedValue = ObscuredString.Encrypt(firstBuildHash + GenuineValidatorExample.Separator + hashOfTheHashHaha, GenuineValidatorExample.StringKey); // now just get raw bytes and write them to the file to compare hash in runtime var bytes = GenuineValidatorExample.UnicodeCharsToBytes(encryptedValue); File.WriteAllBytes(filePath, bytes); }
public static void SaveCollectionInfo() { ObscuredString unlocked = ""; for (int i = 0; i < mColUnlocked.Length; i++) { unlocked = unlocked + mColUnlocked[i].ToString(); } Saved.SetString(SaveKey.CollectionUnlocked, unlocked); ObscuredString states = ""; for (int i = 0; i < mColStates.Length; i++) { states = states + mColStates[i].ToString(); } Saved.SetString(SaveKey.CollectionStates, states); }