コード例 #1
0
ファイル: SatSolver.cs プロジェクト: vaginessa/Probfuscator
        private ISatExpressionWrapper /*?*/ GetSolverExpressionFor(List <Instruction> listOfExpressions)
        {
            Contract.Requires(listOfExpressions != null);

            var n = listOfExpressions.Count;

            if (n == 0)
            {
                return(null);
            }
            ISatExpressionWrapper /*?*/ conjunct = null;

            for (int i = 0; i < n; i++)
            {
                if (listOfExpressions[i] == null)
                {
                    return(null);
                }
                var expression = this.GetSolverExpressionFor(listOfExpressions[i]);
                if (conjunct == null)
                {
                    conjunct = expression;
                }
                else
                {
                    conjunct = this.satSolver.MakeExpression(this.andOp, conjunct.Type, conjunct, expression);
                }
            }
            return(conjunct);
        }
コード例 #2
0
ファイル: SatSolver.cs プロジェクト: vaginessa/Probfuscator
        internal ISatExpressionWrapper /*?*/ GetSolverExpressionFor(List <List <Instruction> > listOfConjunctions)
        {
            Contract.Requires(listOfConjunctions != null);

            var n = listOfConjunctions.Count;

            if (n == 0)
            {
                return(null);
            }
            ISatExpressionWrapper /*?*/ disjunct = null;

            for (int i = 0; i < n; i++)
            {
                if (listOfConjunctions[i] == null)
                {
                    return(null);
                }
                var conjunct = this.GetSolverExpressionFor(listOfConjunctions[i]);
                if (conjunct == null)
                {
                    return(null);
                }
                if (disjunct == null)
                {
                    disjunct = conjunct;
                }
                else
                {
                    disjunct = this.satSolver.MakeExpression(this.orOp, disjunct.Type, disjunct, conjunct);
                }
            }
            return(disjunct);
        }
コード例 #3
0
 public void AddInverse(ISatExpressionWrapper expression)
 {
     if (expression.Type.TypeCode != PrimitiveTypeCode.Boolean)
     {
         this.isDummy = true;
     }
     else
     {
         this.solverContext.Assert(this.solver.MkNot(expression.Unwrap <BoolExpr>()));
     }
 }
コード例 #4
0
 private BoolExpr ConvertToBool(ISatExpressionWrapper expr)
 {
     if (expr.Type.TypeCode == PrimitiveTypeCode.Boolean)
     {
         return(expr.Unwrap <BoolExpr>());
     }
     if (HasBitVectorSort(expr.Type))
     {
         var bv = expr.Unwrap <BitVecExpr>();
         return(this.solver.MkNot(this.solver.MkEq(bv, this.solver.MkBV(0, bv.SortSize))));
     }
     return(this.solver.MkBoolConst("bool" + expr.GetHashCode().ToString()));
 }
コード例 #5
0
        private BitVecExpr ConvertToBitVector(ISatExpressionWrapper expr, uint size)
        {
            if (HasBitVectorSort(expr.Type))
            {
                return(expr.Unwrap <BitVecExpr>());
            }
            BitVecExpr result = null;

            if (expr.Type.TypeCode == PrimitiveTypeCode.Boolean)
            {
                result = this.solver.MkITE(expr.Unwrap <BoolExpr>(), this.solver.MkBV(1, 32), this.solver.MkBV(0, 32)) as BitVecExpr; //TODO: this cast might never work
            }
            if (result != null)
            {
                return(result);
            }
            return(this.solver.MkInt2BV(size, this.solver.MkIntConst("int" + expr.GetHashCode().ToString())));
        }
コード例 #6
0
 public ISatExpressionWrapper MakeImplication(ISatExpressionWrapper operand1, ISatExpressionWrapper operand2)
 {
     return(new ExpressionWrapper(this.solver.MkImplies(operand1.Unwrap <BoolExpr>(), operand2.Unwrap <BoolExpr>()), operand1.Type));
 }
コード例 #7
0
        public ISatExpressionWrapper MakeExpression(IOperation operation, ITypeReference expressionType, ISatExpressionWrapper operand1, ISatExpressionWrapper operand2)
        {
            Expr expr;
            var  operationSize = Math.Max(Math.Max(TypeHelper.SizeOfType(expressionType), TypeHelper.SizeOfType(operand1.Type)), TypeHelper.SizeOfType(operand2.Type)) <= 4  ? 32u : 64u;

            switch (operation.OperationCode)
            {
            //Instructions that are side-effect free and cacheable and that could result in compile time values.
            //We attempt to compute the compile time values.
            case OperationCode.Add:
            case OperationCode.Add_Ovf:
            case OperationCode.Add_Ovf_Un:
                expr = this.solver.MkBVAdd(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.And:
                if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean)
                {
                    expr = this.solver.MkAnd(operand1.Unwrap <BoolExpr>(), this.ConvertToBool(operand2));
                }
                else
                {
                    expr = this.solver.MkBVAND(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                }
                break;

            case OperationCode.Div:
                expr = this.solver.MkBVSDiv(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Div_Un:
                expr = this.solver.MkBVUDiv(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Mul:
            case OperationCode.Mul_Ovf:
            case OperationCode.Mul_Ovf_Un:
                expr = this.solver.MkBVMul(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Or:
                if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean)
                {
                    expr = this.solver.MkOr(operand1.Unwrap <BoolExpr>(), this.ConvertToBool(operand2));
                }
                else
                {
                    expr = this.solver.MkBVOR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                }
                break;

            case OperationCode.Rem:
                expr = this.solver.MkBVSRem(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Rem_Un:
                expr = this.solver.MkBVURem(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Shl:
                expr = this.solver.MkBVURem(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Shr:
                expr = this.solver.MkBVASHR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Shr_Un:
                expr = this.solver.MkBVLSHR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Sub:
            case OperationCode.Sub_Ovf:
            case OperationCode.Sub_Ovf_Un:
                expr = this.solver.MkBVSub(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Xor:
                if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean)
                {
                    expr = this.solver.MkXor(operand1.Unwrap <BoolExpr>(), this.ConvertToBool(operand2));
                }
                else
                {
                    expr = this.solver.MkBVXOR(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                }
                break;

            //Boolean expression
            case OperationCode.Beq:
            case OperationCode.Beq_S:
            case OperationCode.Ceq:
                expr = this.solver.MkEq(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Bge:
            case OperationCode.Bge_S:
                expr = this.solver.MkBVSGE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Bge_Un:
            case OperationCode.Bge_Un_S:
                expr = this.solver.MkBVUGE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Bgt:
            case OperationCode.Bgt_S:
            case OperationCode.Cgt:
                expr = this.solver.MkBVSGT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Bgt_Un:
            case OperationCode.Bgt_Un_S:
            case OperationCode.Cgt_Un:
                expr = this.solver.MkBVUGT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Ble:
            case OperationCode.Ble_S:
                expr = this.solver.MkBVSLE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Ble_Un:
            case OperationCode.Ble_Un_S:
                expr = this.solver.MkBVULE(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Blt:
            case OperationCode.Blt_S:
            case OperationCode.Clt:
                expr = this.solver.MkBVSLT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Blt_Un:
            case OperationCode.Blt_Un_S:
            case OperationCode.Clt_Un:
                expr = this.solver.MkBVULT(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize));
                break;

            case OperationCode.Bne_Un:
            case OperationCode.Bne_Un_S:
                expr = this.solver.MkNot(this.solver.MkEq(this.ConvertToBitVector(operand1, operationSize), this.ConvertToBitVector(operand2, operationSize)));
                break;

            //Instructions that cause side-effect that we do not currently track.
            case OperationCode.Call:
            case OperationCode.Calli:
            case OperationCode.Callvirt:
            case OperationCode.Cpblk:
            case OperationCode.Cpobj:
            case OperationCode.Initblk:
            case OperationCode.Newobj:
            case OperationCode.Stfld:
            case OperationCode.Stind_I:
            case OperationCode.Stind_I1:
            case OperationCode.Stind_I2:
            case OperationCode.Stind_I4:
            case OperationCode.Stind_I8:
            case OperationCode.Stind_R4:
            case OperationCode.Stind_R8:
            case OperationCode.Stind_Ref:
            case OperationCode.Stobj:
                goto default;

            //Instructions that are side-effect free and cacheable and that could result in compile time values.
            //We do NOT attempt to compute the compile time values at this time.
            case OperationCode.Ldelem_I:
            case OperationCode.Ldelem_I1:
            case OperationCode.Ldelem_I2:
            case OperationCode.Ldelem_I4:
            case OperationCode.Ldelem_I8:
            case OperationCode.Ldelem_R4:
            case OperationCode.Ldelem_R8:
            case OperationCode.Ldelem_Ref:
            case OperationCode.Ldelem_U1:
            case OperationCode.Ldelem_U2:
            case OperationCode.Ldelem_U4:
            case OperationCode.Ldelema:
                goto default;

            case OperationCode.Nop:
                var v = operation.Value as INamedEntity;
                if (v != null && !(v.Name is Dummy)) //phi node
                {
                    expr = this.GetVariableFor(v, expressionType);
                    break;
                }
                goto default;

            default:
                var hashCode = operation.GetHashCode();
                if (operation is Dummy)
                {
                    hashCode = new object().GetHashCode();
                }
                expr = this.solver.MkConst("binary" + hashCode, this.GetSortFor(expressionType));
                break;
            }
            return(new ExpressionWrapper(expr, expressionType));
        }
コード例 #8
0
        public ISatExpressionWrapper /*?*/ MakeExpression(IOperation operation, ITypeReference expressionType, ISatExpressionWrapper operand1)
        {
            Expr expr;
            ExpressionWrapper wrapper1 = operand1 as ExpressionWrapper;
            var operationSize          = Math.Max(TypeHelper.SizeOfType(expressionType), TypeHelper.SizeOfType(operand1.Type)) <= 4  ? 32u : 64u;

            switch (operation.OperationCode)
            {
            case OperationCode.Conv_I1:
            case OperationCode.Conv_Ovf_I1:
            case OperationCode.Conv_Ovf_I1_Un:
                expr = this.solver.MkSignExt(24, this.solver.MkExtract(7, 0, this.ConvertToBitVector(operand1, operationSize)));
                break;

            case OperationCode.Conv_I2:
            case OperationCode.Conv_Ovf_I2:
            case OperationCode.Conv_Ovf_I2_Un:
                expr = this.solver.MkSignExt(16, this.solver.MkExtract(16, 0, this.ConvertToBitVector(operand1, operationSize)));
                break;

            case OperationCode.Conv_I4:
            case OperationCode.Conv_Ovf_I4:
            case OperationCode.Conv_Ovf_I4_Un:
                expr = this.solver.MkExtract(32, 0, this.ConvertToBitVector(operand1, operationSize));
                break;

            case OperationCode.Conv_I8:
            case OperationCode.Conv_Ovf_I8:
            case OperationCode.Conv_Ovf_I8_Un:
                if (TypeHelper.SizeOfType(operand1.Type) == 8)
                {
                    expr = this.ConvertToBitVector(operand1, 64);
                }
                else
                {
                    expr = this.solver.MkSignExt(32, this.ConvertToBitVector(operand1, operationSize));
                }
                break;

            case OperationCode.Conv_R4:
                goto default;

            case OperationCode.Conv_R8:
                goto default;

            case OperationCode.Conv_U1:
            case OperationCode.Conv_Ovf_U1:
            case OperationCode.Conv_Ovf_U1_Un:
                expr = this.solver.MkZeroExt(24, this.solver.MkExtract(7, 0, this.ConvertToBitVector(operand1, operationSize)));
                break;

            case OperationCode.Conv_U2:
            case OperationCode.Conv_Ovf_U2:
            case OperationCode.Conv_Ovf_U2_Un:
                expr = this.solver.MkZeroExt(16, this.solver.MkExtract(16, 0, this.ConvertToBitVector(operand1, operationSize)));
                break;

            case OperationCode.Conv_U4:
            case OperationCode.Conv_Ovf_U4:
            case OperationCode.Conv_Ovf_U4_Un:
                expr = this.solver.MkExtract(32, 0, this.ConvertToBitVector(operand1, operationSize));
                break;

            case OperationCode.Conv_U8:
            case OperationCode.Conv_Ovf_U8:
            case OperationCode.Conv_Ovf_U8_Un:
                if (TypeHelper.SizeOfType(operand1.Type) == 8)
                {
                    expr = this.ConvertToBitVector(operand1, 64);
                }
                else
                {
                    expr = this.solver.MkZeroExt(32, this.ConvertToBitVector(operand1, 32));
                }
                break;

            case OperationCode.Conv_I:
            case OperationCode.Conv_Ovf_I:
            case OperationCode.Conv_Ovf_I_Un:
                if (expressionType.PlatformType.PointerSize == 8)
                {
                    goto case OperationCode.Conv_I8;
                }
                else
                {
                    goto case OperationCode.Conv_I4;
                }

            case OperationCode.Conv_U:
            case OperationCode.Conv_Ovf_U:
            case OperationCode.Conv_Ovf_U_Un:
                if (expressionType.PlatformType.PointerSize == 8)
                {
                    goto case OperationCode.Conv_U8;
                }
                else
                {
                    goto case OperationCode.Conv_U4;
                }

            case OperationCode.Conv_R_Un:
                goto default;

            case OperationCode.Dup:
                return(operand1);

            case OperationCode.Neg:
                expr = this.solver.MkBVNeg(this.ConvertToBitVector(operand1, operationSize));
                break;

            case OperationCode.Nop:
                var v = operation.Value as INamedEntity;
                if (v != null && !(v.Name is Dummy)) //phi node
                {
                    expr = this.GetVariableFor(v, expressionType);
                    break;
                }
                goto default;

            case OperationCode.Not:
                if (operand1.Type.TypeCode == PrimitiveTypeCode.Boolean)
                {
                    expr = this.solver.MkNot(operand1.Unwrap <BoolExpr>());
                }
                else
                {
                    expr = this.solver.MkBVNot(this.ConvertToBitVector(operand1, operationSize));
                }
                break;

            default:
                var hashCode = operation.GetHashCode();
                if (operation is Dummy)
                {
                    hashCode = new object().GetHashCode();
                }
                expr = this.solver.MkConst("unary" + hashCode, this.GetSortFor(expressionType));
                break;
            }
            return(new ExpressionWrapper(expr, expressionType));
        }