Created
August 16, 2021 04:38
-
-
Save XenocodeRCE/a4af8afbbcb9ffb11f4ee8d8dbc68c70 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| using Microsoft.CSharp; | |
| using System; | |
| using System.CodeDom.Compiler; | |
| using System.Collections.Generic; | |
| using System.Globalization; | |
| using System.Linq; | |
| using System.Text; | |
| using System.Threading; | |
| using System.Threading.Tasks; | |
| namespace JConfuse | |
| { | |
| class Program | |
| { | |
| static string oneCode = @" | |
| double a = 1.0; | |
| double b = a + 2.2; | |
| double c = 0.0; | |
| if (b > 3.3){ | |
| return c; | |
| } | |
| return 4.4; | |
| "; | |
| static string twoCode = @"System.out.println(""Java Obfuscator Online"");"; | |
| static string threeCode = @" | |
| public static int method(int param) { | |
| int a = 1; | |
| int b = a + 2; | |
| int c = 0; | |
| if (b > 3) return c; | |
| return 4; | |
| } | |
| "; | |
| static string fourCode = @" | |
| int a = 1; | |
| int b = a + 2; | |
| int c = 0; | |
| System.out.println(""This dude is massive""); | |
| if (b > 3){ | |
| return c; | |
| } | |
| return 4;"; | |
| static Dictionary<string, string> doubleDictionnary = new Dictionary<string, string>(); | |
| static Dictionary<string, string> intDictionnary = new Dictionary<string, string>(); | |
| static string[] obedCode; | |
| static Evaluator eval; | |
| private static Random random = new Random(); | |
| static void Main(string[] args) { | |
| eval = new Evaluator(); | |
| obedCode = fourCode.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| //StoreLocalValuesInArrays(); | |
| //ObfuscateStrings(); | |
| //ObfuscateIntegers(); | |
| ObfuscateCodeFlow(); | |
| Console.WriteLine(string.Join(Environment.NewLine, obedCode)); | |
| Console.ReadKey(); | |
| } | |
| private static void ObfuscateCodeFlow() { | |
| //where to store the method blocks | |
| List<string> blocks = new List<string>(); | |
| //where to store integer variables | |
| List<string> integers = new List<string>(); | |
| //first we want to make sure the variables are not | |
| //messed up with so we put their initialization outside | |
| //of all the blocks we will parse later | |
| for (int i = 0; i < obedCode.Length; i++) { | |
| var current = obedCode[i]; | |
| //sort out integers | |
| if (current.Contains("int") && current.Contains("=")) { | |
| var name = GetStringInBetween("int", "=", current, false, false).Trim(); | |
| integers.Add($"int {name} = 0;"); | |
| obedCode[i] = obedCode[i].Replace($"int {name}", $"{name}"); | |
| } | |
| } | |
| //integers.Reverse(); | |
| //parse the actual method blocks | |
| for (int i = 0; i < obedCode.Length; i++) { | |
| //parse integers and variable value set | |
| if (obedCode[i].Contains("=") || obedCode[i].Contains("(")) { | |
| blocks.Add(obedCode[i]); | |
| } | |
| //parse if branches | |
| else if (obedCode[i].Contains("if")) { | |
| List<string> IfBlock = new List<string> { | |
| obedCode[i] | |
| }; | |
| i++; | |
| while (!obedCode[i].Contains("}")) { | |
| IfBlock.Add(obedCode[i]); | |
| i++; | |
| } | |
| IfBlock.Add("}"); | |
| blocks.Add(string.Join(Environment.NewLine, IfBlock.ToArray())); | |
| } | |
| } | |
| //grab return statement, if any | |
| string returnStatement = ""; | |
| if (obedCode[obedCode.Length -1].Contains("return")) { | |
| returnStatement = obedCode[obedCode.Length - 1]; | |
| } | |
| //set switches structure | |
| string switchIndexName = RandomString(5); | |
| Dictionary<int, string> switchBlocks = new Dictionary<int, string>(); | |
| foreach (var item in blocks) { | |
| int caseNumber = random.Next(2, 150); | |
| switchBlocks.Add(caseNumber, item); | |
| } | |
| //fil in structure | |
| int indexSwitch = 0; | |
| int originalSwitchValue = 0; | |
| int endSwitchValue = random.Next(123456, 654321); | |
| string cases = ""; | |
| foreach (var item in switchBlocks) { | |
| KeyValuePair<int, string> nextData = GetNextState(switchBlocks, indexSwitch); | |
| int nextCase = 0; | |
| if (nextData.Value == "") { | |
| nextCase = endSwitchValue; | |
| } else { | |
| nextCase = nextData.Key; | |
| } | |
| cases += $@" | |
| case {item.Key}: | |
| {item.Value} | |
| {switchIndexName} = {nextCase}; | |
| break;" + Environment.NewLine; | |
| if(indexSwitch == 0) { | |
| originalSwitchValue = item.Key; | |
| } | |
| indexSwitch++; | |
| } | |
| string theSwitch = $@" | |
| {string.Join(Environment.NewLine, integers.ToArray())} | |
| int {switchIndexName} = 0; | |
| {switchIndexName} = {originalSwitchValue}; | |
| while ({switchIndexName} != {endSwitchValue}) {{ | |
| switch({switchIndexName}) {{ | |
| {cases} | |
| }} | |
| }} | |
| {returnStatement} | |
| "; | |
| var tmplist = obedCode.ToList(); | |
| foreach (var item in integers) { | |
| tmplist.Insert(0, item); | |
| } | |
| obedCode = theSwitch.Split(new[] { Environment.NewLine }, StringSplitOptions.None); | |
| } | |
| private static KeyValuePair<int, string> GetNextState(Dictionary<int, string> switchBlocks, int indexSwitch) { | |
| int index = 0; | |
| int targetindex = indexSwitch + 1; | |
| foreach (var item in switchBlocks) { | |
| if (index == targetindex) | |
| return item; | |
| index++; | |
| } | |
| return new KeyValuePair<int, string>(0, ""); | |
| } | |
| private static void ObfuscateIntegers() { | |
| for (int i = 0; i < obedCode.Length; i++) { | |
| var currentLine = obedCode[i]; | |
| var words = currentLine.Split(' '); | |
| for (int i2 = 0; i2 < words.Length; i2++) { | |
| if (words[i2].Contains(")") || words[i2].Contains(";")) { | |
| var tmp = words[i2].Replace(")", "").Replace(";", ""); | |
| if (IsInt(tmp)) { | |
| int originalValue = int.Parse(tmp); | |
| //we now have our separated integer | |
| //lets randomly build an expression | |
| int PassNumber = random.Next(2, 3); | |
| string[] mathOperations = new string[] { | |
| $"System.Math.Abs(1.0)", | |
| $"System.Math.Acos(1.0)", | |
| $"System.Math.Asin(1.0)", | |
| $"System.Math.Atan(1.0)", | |
| $"System.Math.Atan2(1.0 , 2.0)", | |
| $"System.Math.Cos(1.0)", | |
| $"System.Math.Cosh(1.0)", | |
| $"System.Math.Exp(1.0)", | |
| $"System.Math.IEEERemainder(1.0 , 2.0)", | |
| $"System.Math.Log(1.0)", | |
| $"System.Math.Log10(1.0)", | |
| $"System.Math.Max(1.0 , 2.0)", | |
| $"System.Math.Min(1.0 , 2.0)", | |
| $"System.Math.Pow(1.0 , 2.0)", | |
| $"System.Math.Round(1.0)", | |
| $"System.Math.Sign(1.0)", | |
| $"System.Math.Sinh(1.0)", | |
| $"System.Math.Sqrt(1.0)", | |
| $"System.Math.Tan(1.0)", | |
| $"System.Math.Tanh(1.0)" | |
| }; | |
| for (int mOps = 0; mOps < mathOperations.Length; mOps++) { | |
| mathOperations[mOps] = mathOperations[mOps].Replace("1.0", GetRandomNumber(1.0, 2.0).ToString().Replace(",", ".")); | |
| mathOperations[mOps] = mathOperations[mOps].Replace("2.0", GetRandomNumber(1.0, 2.0).ToString().Replace(",", ".")); | |
| } | |
| string[] mathOperators = new string[] { | |
| "+", | |
| "-", | |
| "*" | |
| }; | |
| string expression = "(int) ("; | |
| for (int p = 0; p < PassNumber; p++) { | |
| expression += mathOperations[random.Next(mathOperations.Length - 1)]; | |
| if(p != PassNumber-1) { | |
| expression += " " + mathOperators[random.Next(mathOperators.Length - 1)] + " "; | |
| } | |
| } | |
| expression += ")"; | |
| int expressionResult = eval.EvaluateExpression(expression); //-2147483648 | |
| int x = (originalValue - expressionResult) * -1; | |
| expression += $" - {x}"; | |
| obedCode[i] = obedCode[i].Replace(tmp, expression); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| private static void ObfuscateStrings() { | |
| for (int i = 0; i < obedCode.Length; i++) { | |
| var current = obedCode[i]; | |
| if (!current.Contains("\"")) continue; | |
| string str = GetStringInBetween("\"", "\"", current, false, false); | |
| string string_name = $"str_{RandomString(3)}"; | |
| string array_name = $"array_{RandomString(4)}"; | |
| List<string> encodingPass = new List<string>(); | |
| List<string> decodingPass = new List<string>(); | |
| int numberofPass = random.Next(5, 10); | |
| int tmpval; | |
| for (int x = 0; x < numberofPass; x++) { | |
| switch (random.Next(0, 2)) { | |
| case 0: | |
| tmpval = random.Next(2, 10); | |
| encodingPass.Add($"{array_name}[currentChar] -= {tmpval};" + Environment.NewLine); | |
| decodingPass.Add($"{array_name}[currentChar] += {tmpval};" + Environment.NewLine); | |
| break; | |
| case 1: | |
| tmpval = random.Next(2, 10); | |
| encodingPass.Add($"{array_name}[currentChar] += {tmpval};" + Environment.NewLine); | |
| decodingPass.Add($"{array_name}[currentChar] -= {tmpval};" + Environment.NewLine); | |
| break; | |
| } | |
| } | |
| encodingPass.Add($"{string_name} += (char){array_name}[currentChar];"); | |
| decodingPass.Add($"{string_name} += (char){array_name}[currentChar];"); | |
| string intarray = $"int[] {array_name} = {{ "; | |
| foreach (var item in str) { | |
| intarray += (int)item + ","; | |
| } | |
| intarray = intarray.Remove(intarray.Length - 1); | |
| intarray += " };"; | |
| string pass = $@" | |
| string {string_name} = """"; | |
| {intarray} | |
| for (int currentChar = 0; currentChar < {array_name}.Length; currentChar++) {{ | |
| {string.Join(Environment.NewLine, encodingPass.ToArray())} | |
| }} | |
| "; | |
| char[] r1 = eval.EvaluateCharArray(pass, string_name); | |
| string charsStr = new string(r1); | |
| intarray = $"int[] {array_name} = {{ "; | |
| foreach (var item in charsStr) { | |
| intarray += (int)item + ","; | |
| } | |
| intarray = intarray.Remove(intarray.Length - 1); | |
| intarray += " };"; | |
| pass = $@" | |
| string {string_name} = """"; | |
| {intarray} | |
| for (int currentChar = 0; currentChar < {array_name}.Length; currentChar++) {{ | |
| {string.Join(Environment.NewLine, decodingPass.ToArray())} | |
| }} | |
| "; | |
| char[] r2 = eval.EvaluateCharArray(pass, string_name); | |
| string toverif = new string(r2); | |
| if (toverif != str) | |
| throw new Exception("intput and output does not matches !"); | |
| Console.WriteLine(pass); | |
| } | |
| } | |
| private static void StoreLocalValuesInArrays() { | |
| /*Double pass*/ | |
| int index = 0; | |
| var name = RandomString(5); | |
| string tmpArray = $"double[] {name} = {{ "; | |
| for (int i = 0; i < obedCode.Length; i++) { | |
| var currentLine = obedCode[i].Replace(";", " ").Replace("(", " ").Replace(")", " ").Replace("{", " ").Replace("}", " "); | |
| var words = currentLine.Split(' '); | |
| foreach (var word in words) { | |
| if (IsDouble(word)) { | |
| tmpArray += word + ","; | |
| obedCode[i] = obedCode[i].Replace(word, $"{name}[{index}]"); | |
| index++; | |
| } | |
| } | |
| } | |
| if (index != 0) { | |
| tmpArray = tmpArray.Remove(tmpArray.Length - 1) + " };"; | |
| List<string> tmp = obedCode.ToList(); | |
| tmp.Insert(0, tmpArray); | |
| obedCode = tmp.ToArray(); | |
| } | |
| /*Int pass*/ | |
| index = 0; | |
| name = RandomString(5); | |
| tmpArray = $"int[] {name} = {{ "; | |
| for (int i = 0; i < obedCode.Length; i++) { | |
| var currentLine = obedCode[i].Replace(";", " ").Replace("(", " ").Replace(")", " ").Replace("{", " ").Replace("}", " "); | |
| var words = currentLine.Split(' '); | |
| foreach (var word in words) { | |
| if (IsInt(word)) { | |
| tmpArray += word + ","; | |
| obedCode[i] = obedCode[i].Replace(word, $"{name}[{index}]"); | |
| index++; | |
| } | |
| } | |
| } | |
| if (index != 0) { | |
| tmpArray = tmpArray.Remove(tmpArray.Length - 1) + " };"; | |
| List<string> tmp = obedCode.ToList(); | |
| tmp.Insert(0, tmpArray); | |
| obedCode = tmp.ToArray(); | |
| } | |
| } | |
| static double GetRandomNumber(double minimum, double maximum) { | |
| return random.NextDouble() * (maximum - minimum) + minimum; | |
| } | |
| static int ToInt(char c) { | |
| return (int)(c - '0'); | |
| } | |
| static bool IsInt(string text) { | |
| int i = 123456789; | |
| try { | |
| i = int.Parse(text, CultureInfo.InvariantCulture); | |
| if (i != 123456789) | |
| return true; | |
| else | |
| return false; | |
| } catch (Exception) { | |
| return false; | |
| } | |
| } | |
| static bool IsDouble(string text) { | |
| double d = 123456789.987654321; | |
| try { | |
| d = double.Parse(text, CultureInfo.InvariantCulture); | |
| if (d != 123456789.987654321) | |
| return true; | |
| else | |
| return false; | |
| } catch (Exception) { | |
| return false; | |
| } | |
| } | |
| public static string RandomString(int length) { | |
| const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; | |
| return "J" + new string(Enumerable.Repeat(chars, length) | |
| .Select(s => s[random.Next(s.Length)]).ToArray()); | |
| } | |
| public static string GetStringInBetween(string strBegin, string strEnd, string strSource, bool includeBegin, | |
| bool includeEnd) { | |
| string[] result = { string.Empty, string.Empty }; | |
| int iIndexOfBegin = strSource.IndexOf(strBegin); | |
| if (iIndexOfBegin != -1) { | |
| // include the Begin string if desired | |
| if (includeBegin) | |
| iIndexOfBegin -= strBegin.Length; | |
| strSource = strSource.Substring(iIndexOfBegin + strBegin.Length); | |
| int iEnd = strSource.IndexOf(strEnd); | |
| if (iEnd != -1) { | |
| // include the End string if desired | |
| if (includeEnd) | |
| iEnd += strEnd.Length; | |
| result[0] = strSource.Substring(0, iEnd); | |
| // advance beyond this segment | |
| if (iEnd + strEnd.Length < strSource.Length) | |
| result[1] = strSource.Substring(iEnd + strEnd.Length); | |
| } | |
| } else | |
| // stay where we are | |
| result[1] = strSource; | |
| return result[0]; | |
| } | |
| } | |
| public class Evaluator | |
| { | |
| public CompilerParameters Parameters { get; set; } = new CompilerParameters() { | |
| CompilerOptions = "/unsafe", | |
| }; | |
| public Evaluator() { | |
| Parameters.ReferencedAssemblies.Add("System.dll"); | |
| Parameters.ReferencedAssemblies.Add("System.Core.dll"); | |
| Parameters.ReferencedAssemblies.Add("Microsoft.CSharp.dll"); | |
| Parameters.GenerateInMemory = true; | |
| } | |
| public CompilerResults Compile(string methodCode) { | |
| return new CSharpCodeProvider().CompileAssemblyFromSource(Parameters, methodCode); | |
| } | |
| public int EvaluateExpression(string expression) { | |
| if (!expression.EndsWith(";")) { | |
| expression += ";"; | |
| } | |
| string code = $@" | |
| public class A{{ | |
| public static int B() {{ | |
| int result = {expression} | |
| return result; | |
| }} | |
| }} | |
| "; | |
| var results = Compile(code); | |
| if (results.Errors.Count > 0) | |
| throw new Exception("Error during expression evaluation"); | |
| var methodInfo = results.CompiledAssembly.GetTypes().Single( | |
| t => t.GetMethods().Count() > 0 | |
| && t.GetMethods().Count(m => m.ReturnParameter.ParameterType == typeof(int)) > 0 | |
| && t.GetMethods().Count(m => m.Name == "B") > 0) | |
| .GetMethods()[0]; | |
| var mResult = (int)methodInfo.Invoke(null, null); | |
| return mResult; | |
| } | |
| public char[] EvaluateCharArray(string expression, string variableName) { | |
| expression = expression.Replace("String", "string"); | |
| string code = $@" | |
| public class A{{ | |
| public static char[] B() {{ | |
| {expression} | |
| return {variableName}.ToCharArray(); | |
| }} | |
| }} | |
| "; | |
| var results = Compile(code); | |
| if (results.Errors.Count > 0) | |
| throw new Exception("Error during expression evaluation"); | |
| var methodInfo = results.CompiledAssembly.GetTypes().Single( | |
| t => t.GetMethods().Count() > 0 | |
| && t.GetMethods().Count(m => m.ReturnParameter.ParameterType == typeof(int)) > 0 | |
| && t.GetMethods().Count(m => m.Name == "B") > 0) | |
| .GetMethods()[0]; | |
| var mResult = (char[])methodInfo.Invoke(null, null); | |
| return mResult; | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment