コード例 #1
0
		static Expression GenerateExpression(RandomGenerator random, Expression current, int currentDepth, int targetDepth) {
			if (currentDepth == targetDepth || (currentDepth > targetDepth / 3 && random.NextInt32(100) > 85))
				return current;

			switch ((ExpressionOps)random.NextInt32(6)) {
				case ExpressionOps.Add:
					return GenerateExpression(random, current, currentDepth + 1, targetDepth) +
					       GenerateExpression(random, (LiteralExpression)random.NextUInt32(), currentDepth + 1, targetDepth);

				case ExpressionOps.Sub:
					return GenerateExpression(random, current, currentDepth + 1, targetDepth) -
					       GenerateExpression(random, (LiteralExpression)random.NextUInt32(), currentDepth + 1, targetDepth);

				case ExpressionOps.Mul:
					return GenerateExpression(random, current, currentDepth + 1, targetDepth) * (LiteralExpression)(random.NextUInt32() | 1);

				case ExpressionOps.Xor:
					return GenerateExpression(random, current, currentDepth + 1, targetDepth) ^
					       GenerateExpression(random, (LiteralExpression)random.NextUInt32(), currentDepth + 1, targetDepth);

				case ExpressionOps.Not:
					return ~GenerateExpression(random, current, currentDepth + 1, targetDepth);

				case ExpressionOps.Neg:
					return -GenerateExpression(random, current, currentDepth + 1, targetDepth);
			}
			throw new UnreachableException();
		}
コード例 #2
0
		static Expression ProcessExpression(Expression exp) {
			if (exp is BinOpExpression) {
				var binOp = (BinOpExpression)exp;
				var binOpRight = binOp.Right as BinOpExpression;
				//  a + (b + c) => (a + b) + c
				if (binOpRight != null && binOpRight.Operation == binOp.Operation &&
				    (binOp.Operation == BinOps.Add || binOp.Operation == BinOps.Mul ||
				     binOp.Operation == BinOps.Or || binOp.Operation == BinOps.And ||
				     binOp.Operation == BinOps.Xor)) {
					binOp.Left = new BinOpExpression {
						Left = binOp.Left,
						Operation = binOp.Operation,
						Right = binOpRight.Left
					};
					binOp.Right = binOpRight.Right;
				}

				binOp.Left = ProcessExpression(binOp.Left);
				binOp.Right = ProcessExpression(binOp.Right);

				if (binOp.Right is LiteralExpression && ((LiteralExpression)binOp.Right).Value == 0 &&
				    binOp.Operation == BinOps.Add) // x + 0 => x
					return binOp.Left;
			}
			else if (exp is ArrayIndexExpression) {
				((ArrayIndexExpression)exp).Array = ProcessExpression(((ArrayIndexExpression)exp).Array);
			}
			else if (exp is UnaryOpExpression) {
				((UnaryOpExpression)exp).Value = ProcessExpression(((UnaryOpExpression)exp).Value);
			}
			return exp;
		}
コード例 #3
0
        public static void GeneratePair(RandomGenerator random, Expression var, Expression result, int depth, out Expression expression, out Expression inverse)
        {
            expression = GenerateExpression(random, var, 0, depth);
            SwapOperands(random, expression);

            var hasVar = new Dictionary<Expression, bool>();
            HasVariable(expression, hasVar);

            inverse = GenerateInverse(expression, result, hasVar);
        }
コード例 #4
0
		void Compile(RPContext ctx, CilBody body, out Func<int, int> expCompiled, out Expression inverse) {
			var var = new Variable("{VAR}");
			var result = new Variable("{RESULT}");

			Expression expression;
			ctx.DynCipher.GenerateExpressionPair(
				ctx.Random,
				new VariableExpression { Variable = var }, new VariableExpression { Variable = result },
				ctx.Depth, out expression, out inverse);

			expCompiled = new DMCodeGen(typeof(int), new[] { Tuple.Create("{VAR}", typeof(int)) })
				.GenerateCIL(expression)
				.Compile<Func<int, int>>();
		}
コード例 #5
0
		static IEnumerable<Variable> GetVariableUsage(Expression exp) {
			if (exp is VariableExpression)
				yield return ((VariableExpression)exp).Variable;
			else if (exp is ArrayIndexExpression) {
				foreach (Variable i in GetVariableUsage(((ArrayIndexExpression)exp).Array))
					yield return i;
			}
			else if (exp is BinOpExpression) {
				foreach (Variable i in GetVariableUsage(((BinOpExpression)exp).Left)
					.Concat(GetVariableUsage(((BinOpExpression)exp).Right)))
					yield return i;
			}
			else if (exp is UnaryOpExpression) {
				foreach (Variable i in GetVariableUsage(((UnaryOpExpression)exp).Value))
					yield return i;
			}
		}
コード例 #6
0
		static void SwapOperands(RandomGenerator random, Expression exp) {
			if (exp is BinOpExpression) {
				var binExp = (BinOpExpression)exp;
				if (random.NextBoolean()) {
					Expression tmp = binExp.Left;
					binExp.Left = binExp.Right;
					binExp.Right = tmp;
				}
				SwapOperands(random, binExp.Left);
				SwapOperands(random, binExp.Right);
			}
			else if (exp is UnaryOpExpression)
				SwapOperands(random, ((UnaryOpExpression)exp).Value);
			else if (exp is LiteralExpression || exp is VariableExpression)
				return;
			else
				throw new UnreachableException();
		}
コード例 #7
0
ファイル: x86CodeGen.cs プロジェクト: EmilZhou/ConfuserEx
		public x86Register? GenerateX86(Expression expression, Func<Variable, x86Register, IEnumerable<x86Instruction>> loadArg) {
			instrs = new List<x86Instruction>();
			usedRegs = new bool[8];
			MaxUsedRegister = -1;

			// CRITICAL registers!
			usedRegs[(int)x86Register.EBP] = true;
			usedRegs[(int)x86Register.ESP] = true;

			try {
				return ((x86RegisterOperand)Emit(expression, loadArg)).Register;
			}
			catch (Exception ex) {
				if (ex.Message == "Register overflowed.")
					return null;
				throw;
			}
		}
コード例 #8
0
        private static Expression ProcessExpression(Expression exp)
        {
            if (exp is BinOpExpression) {
                var binOp = (BinOpExpression)exp;
                if (binOp.Operation == BinOps.Mul && binOp.Right is LiteralExpression) {
                    // Decompose multiplication into shifts, e.g. x * 3 => x << 1 + x
                    uint literal = ((LiteralExpression)binOp.Right).Value;
                    if (literal == 0) return (LiteralExpression)0;
                    if (literal == 1) return binOp.Left;

                    uint bits = NumberOfSetBits(literal);
                    if (bits <= 2) {
                        var sum = new List<Expression>();
                        int n = 0;
                        while (literal != 0) {
                            if ((literal & 1) != 0) {
                                if (n == 0)
                                    sum.Add(binOp.Left);
                                else
                                    sum.Add(binOp.Left << n);
                            }
                            literal >>= 1;
                            n++;
                        }
                        BinOpExpression x = sum.OfType<BinOpExpression>().First();
                        foreach (Expression i in sum.Except(new[] { x }))
                            x += i;
                        return x;
                    }
                }
                else {
                    binOp.Left = ProcessExpression(binOp.Left);
                    binOp.Right = ProcessExpression(binOp.Right);
                }
            }
            else if (exp is ArrayIndexExpression) {
                ((ArrayIndexExpression)exp).Array = ProcessExpression(((ArrayIndexExpression)exp).Array);
            }
            else if (exp is UnaryOpExpression) {
                ((UnaryOpExpression)exp).Value = ProcessExpression(((UnaryOpExpression)exp).Value);
            }
            return exp;
        }
コード例 #9
0
		static bool HasVariable(Expression exp, Dictionary<Expression, bool> hasVar) {
			bool ret;
			if (!hasVar.TryGetValue(exp, out ret)) {
				if (exp is VariableExpression)
					ret = true;
				else if (exp is LiteralExpression)
					ret = false;
				else if (exp is BinOpExpression) {
					var binExp = (BinOpExpression)exp;
					ret = HasVariable(binExp.Left, hasVar) || HasVariable(binExp.Right, hasVar);
				}
				else if (exp is UnaryOpExpression) {
					ret = HasVariable(((UnaryOpExpression)exp).Value, hasVar);
				}
				else
					throw new UnreachableException();
				hasVar[exp] = ret;
			}
			return ret;
		}
コード例 #10
0
		static Expression ReplaceVar(Expression exp, Variable buff) {
			if (exp is VariableExpression) {
				if (((VariableExpression)exp).Variable.Name[0] != 'v') return exp;
				return new ArrayIndexExpression {
					Array = new VariableExpression { Variable = buff },
					Index = (int)(exp as VariableExpression).Variable.Tag
				};
			}
			if (exp is ArrayIndexExpression) {
				((ArrayIndexExpression)exp).Array = ReplaceVar(((ArrayIndexExpression)exp).Array, buff);
			}
			else if (exp is BinOpExpression) {
				((BinOpExpression)exp).Left = ReplaceVar(((BinOpExpression)exp).Left, buff);
				((BinOpExpression)exp).Right = ReplaceVar(((BinOpExpression)exp).Right, buff);
			}
			else if (exp is UnaryOpExpression) {
				((UnaryOpExpression)exp).Value = ReplaceVar(((UnaryOpExpression)exp).Value, buff);
			}
			return exp;
		}
コード例 #11
0
ファイル: CILCodeGen.cs プロジェクト: EmilZhou/ConfuserEx
		void EmitStore(Expression exp, Expression value) {
			if (exp is ArrayIndexExpression) {
				var arrIndex = (ArrayIndexExpression)exp;
				EmitLoad(arrIndex.Array);
				Emit(Instruction.CreateLdcI4(arrIndex.Index));
				EmitLoad(value);
				Emit(Instruction.Create(OpCodes.Stelem_I4));
			}
			else if (exp is VariableExpression) {
				var var = (VariableExpression)exp;
				EmitLoad(value);
				StoreVar(var.Variable);
			}
			else
				throw new NotSupportedException();
		}
コード例 #12
0
		static Expression GenerateInverse(Expression exp, Expression var, Dictionary<Expression, bool> hasVar) {
			Expression result = var;
			while (!(exp is VariableExpression)) {
				Debug.Assert(hasVar[exp]);
				if (exp is UnaryOpExpression) {
					var unaryOp = (UnaryOpExpression)exp;
					result = new UnaryOpExpression {
						Operation = unaryOp.Operation,
						Value = result
					};
					exp = unaryOp.Value;
				}
				else if (exp is BinOpExpression) {
					var binOp = (BinOpExpression)exp;
					bool leftHasVar = hasVar[binOp.Left];
					Expression varExp = leftHasVar ? binOp.Left : binOp.Right;
					Expression constExp = leftHasVar ? binOp.Right : binOp.Left;

					if (binOp.Operation == BinOps.Add)
						result = new BinOpExpression {
							Operation = BinOps.Sub,
							Left = result,
							Right = constExp
						};

					else if (binOp.Operation == BinOps.Sub) {
						if (leftHasVar) {
							// v - k = r => v = r + k
							result = new BinOpExpression {
								Operation = BinOps.Add,
								Left = result,
								Right = constExp
							};
						}
						else {
							// k - v = r => v = k - r
							result = new BinOpExpression {
								Operation = BinOps.Sub,
								Left = constExp,
								Right = result
							};
						}
					}
					else if (binOp.Operation == BinOps.Mul) {
						Debug.Assert(constExp is LiteralExpression);
						uint val = ((LiteralExpression)constExp).Value;
						val = MathsUtils.modInv(val);
						result = new BinOpExpression {
							Operation = BinOps.Mul,
							Left = result,
							Right = (LiteralExpression)val
						};
					}
					else if (binOp.Operation == BinOps.Xor)
						result = new BinOpExpression {
							Operation = BinOps.Xor,
							Left = result,
							Right = constExp
						};

					exp = varExp;
				}
			}
			return result;
		}
コード例 #13
0
 public void GenerateExpressionPair(RandomGenerator random, Expression var, Expression result, int depth, out Expression expression, out Expression inverse)
 {
     ExpressionGenerator.GeneratePair(random, var, result, depth, out expression, out inverse);
 }
コード例 #14
0
 private static IEnumerable<Variable> GetVariableDefinition(Expression exp)
 {
     if (exp is VariableExpression)
         yield return ((VariableExpression)exp).Variable;
 }
コード例 #15
0
ファイル: CILCodeGen.cs プロジェクト: EmilZhou/ConfuserEx
		public void GenerateCIL(Expression expression) {
			EmitLoad(expression);
		}
コード例 #16
0
ファイル: CILCodeGen.cs プロジェクト: EmilZhou/ConfuserEx
		void EmitLoad(Expression exp) {
			if (exp is ArrayIndexExpression) {
				var arrIndex = (ArrayIndexExpression)exp;
				EmitLoad(arrIndex.Array);
				Emit(Instruction.CreateLdcI4(arrIndex.Index));
				Emit(Instruction.Create(OpCodes.Ldelem_U4));
			}
			else if (exp is BinOpExpression) {
				var binOp = (BinOpExpression)exp;
				EmitLoad(binOp.Left);
				EmitLoad(binOp.Right);
				OpCode op;
				switch (binOp.Operation) {
					case BinOps.Add:
						op = OpCodes.Add;
						break;
					case BinOps.Sub:
						op = OpCodes.Sub;
						break;
					case BinOps.Div:
						op = OpCodes.Div;
						break;
					case BinOps.Mul:
						op = OpCodes.Mul;
						break;
					case BinOps.Or:
						op = OpCodes.Or;
						break;
					case BinOps.And:
						op = OpCodes.And;
						break;
					case BinOps.Xor:
						op = OpCodes.Xor;
						break;
					case BinOps.Lsh:
						op = OpCodes.Shl;
						break;
					case BinOps.Rsh:
						op = OpCodes.Shr_Un;
						break;
					default:
						throw new NotSupportedException();
				}
				Emit(Instruction.Create(op));
			}
			else if (exp is UnaryOpExpression) {
				var unaryOp = (UnaryOpExpression)exp;
				EmitLoad(unaryOp.Value);
				OpCode op;
				switch (unaryOp.Operation) {
					case UnaryOps.Not:
						op = OpCodes.Not;
						break;
					case UnaryOps.Negate:
						op = OpCodes.Neg;
						break;
					default:
						throw new NotSupportedException();
				}
				Emit(Instruction.Create(op));
			}
			else if (exp is LiteralExpression) {
				var literal = (LiteralExpression)exp;
				Emit(Instruction.CreateLdcI4((int)literal.Value));
			}
			else if (exp is VariableExpression) {
				var var = (VariableExpression)exp;
				LoadVar(var.Variable);
			}
			else
				throw new NotSupportedException();
		}
コード例 #17
0
ファイル: x86CodeGen.cs プロジェクト: 89sos98/ConfuserEx
        private Ix86Operand Emit(Expression exp, Func<Variable, x86Register, IEnumerable<x86Instruction>> loadArg)
        {
            if (exp is BinOpExpression) {
                var binOp = (BinOpExpression)exp;
                x86Register reg;
                switch (binOp.Operation) {
                    case BinOps.Add:
                        reg = Normalize(x86Instruction.Create(x86OpCode.ADD, Emit(binOp.Left, loadArg), Emit(binOp.Right, loadArg)));
                        break;

                    case BinOps.Sub:
                        reg = Normalize(x86Instruction.Create(x86OpCode.SUB, Emit(binOp.Left, loadArg), Emit(binOp.Right, loadArg)));
                        break;

                    case BinOps.Mul:
                        reg = Normalize(x86Instruction.Create(x86OpCode.IMUL, Emit(binOp.Left, loadArg), Emit(binOp.Right, loadArg)));
                        break;

                    case BinOps.Xor:
                        reg = Normalize(x86Instruction.Create(x86OpCode.XOR, Emit(binOp.Left, loadArg), Emit(binOp.Right, loadArg)));
                        break;

                    default:
                        throw new NotSupportedException();
                }
                TakeRegister(reg);
                return new x86RegisterOperand(reg);
            }

            if (exp is UnaryOpExpression) {
                var unaryOp = (UnaryOpExpression)exp;
                x86Register reg;
                switch (unaryOp.Operation) {
                    case UnaryOps.Negate:
                        reg = Normalize(x86Instruction.Create(x86OpCode.NEG, Emit(unaryOp.Value, loadArg)));
                        break;

                    case UnaryOps.Not:
                        reg = Normalize(x86Instruction.Create(x86OpCode.NOT, Emit(unaryOp.Value, loadArg)));
                        break;

                    default:
                        throw new NotSupportedException();
                }
                TakeRegister(reg);
                return new x86RegisterOperand(reg);
            }

            if (exp is LiteralExpression)
                return new x86ImmediateOperand((int)((LiteralExpression)exp).Value);

            if (exp is VariableExpression) {
                x86Register reg = GetFreeRegister();
                TakeRegister(reg);
                instrs.AddRange(loadArg(((VariableExpression)exp).Variable, reg));
                return new x86RegisterOperand(reg);
            }

            throw new NotSupportedException();
        }