예제 #1
0
        // this function generates code for the "state change"
        private void createCodeStateChange(ref BasicBlock outStateChangeBasicBlock, ref SwitchBranchTarget outStateChangeExitBranch, GraphRandomStateGenerator randomStateGenerator, BasicBlockGraphNodeLink link, LocalDefinition intStateLocal) {

            // create a basic block to change the current global state
            BasicBlock stateChangeBasicBlock = new BasicBlock();
            stateChangeBasicBlock.startIdx = 0;
            stateChangeBasicBlock.endIdx = 0;

            // create graph transformer metadata for the basic block
            GraphTransformerStateChangeBasicBlock metadataChange = new GraphTransformerStateChangeBasicBlock();
            metadataChange.correspondingGraphNodes.Add(link);
            stateChangeBasicBlock.transformationMetadata.Add(metadataChange);

            // generate code for setting the new global state
            List<IOperation> tempOperations = randomStateGenerator.generateCodeSetRandomState(intStateLocal);
            stateChangeBasicBlock.operations.AddRange(tempOperations);

            // create switch statement for the "state switch"
            stateChangeBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, intStateLocal));
            uint[] switchSize = new uint[this.graph.graphValidPathCount];
            stateChangeBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Switch, switchSize));

            // create exit branch for the new state basic block
            SwitchBranchTarget stateChangeExitBranch = new SwitchBranchTarget();
            stateChangeExitBranch.sourceBasicBlock = stateChangeBasicBlock;
            stateChangeBasicBlock.exitBranch = stateChangeExitBranch;

            // create the dead code for this "state switch"
            BasicBlock deadCodeBasicBlock = new BasicBlock();
            deadCodeBasicBlock.startIdx = 0;
            deadCodeBasicBlock.endIdx = 0;

            // set the dead code basic block as "not taken" target for the conditional branch of the checking basic block
            deadCodeBasicBlock.entryBranches.Add(stateChangeExitBranch);
            stateChangeExitBranch.notTakenTarget = deadCodeBasicBlock; // TODO at the moment always the not taken branch of the switch statement is the dead code basic block

            // generate dead code for the dead code basic block
            GraphTransformerDeadCodeBasicBlock deadCodeMetadata = new GraphTransformerDeadCodeBasicBlock();
            deadCodeBasicBlock.transformationMetadata.Add(deadCodeMetadata);

            outStateChangeBasicBlock = stateChangeBasicBlock;
            outStateChangeExitBranch = stateChangeExitBranch;

        }
예제 #2
0
        // this function generates code for an opaque predicate that evaluates to "true"
        // => the "taken" branch of the conditional branch have to be taken for the correct code path
        private void createCodeTruePredicate(ref BasicBlock outStartBasicBlock, ref ConditionalBranchTarget outConditionalBranch,
            BasicBlockGraphNodeLink link, LocalDefinition currentNodeLocal) {

            // create a basic block that checks the opaque predicate (this check evaluates to "true")
            BasicBlock startBasicBlock = new BasicBlock();
            startBasicBlock.startIdx = 0;
            startBasicBlock.endIdx = 0;

            // add graph transformer metadata to the basic block
            GraphTransformerPredicateBasicBlock metadata = new GraphTransformerPredicateBasicBlock();
            metadata.predicateType = GraphOpaquePredicate.True;
            metadata.correspondingGraphNodes.Add(link);
            startBasicBlock.transformationMetadata.Add(metadata);

            // search for the valid and invalid interfaces list of the current valid path id
            List<ITypeReference> validInterfaces = null;
            List<ITypeReference> invalidInterfaces = null;
            foreach (PathElement pathElement in link.graphNode.pathElements) {
                if (pathElement.validPathId == link.validPathId) {
                    validInterfaces = pathElement.validInterfaces;
                    invalidInterfaces = pathElement.invalidInterfaces;
                }
            }
            if (validInterfaces == null
                || invalidInterfaces == null) {
                throw new ArgumentException("No valid/invalid interface list was found.");
            }

            emitPredicateCode(startBasicBlock, currentNodeLocal, validInterfaces, invalidInterfaces);

            // create the conditional branch for the checking basic block (taken => correct code; not taken => dead code)
            ConditionalBranchTarget startBasicBlockExitBranch = new ConditionalBranchTarget();
            startBasicBlockExitBranch.sourceBasicBlock = startBasicBlock;
            startBasicBlock.exitBranch = startBasicBlockExitBranch;

            // create the dead code for this opaque predicate
            BasicBlock deadCodeBasicBlock = new BasicBlock();
            deadCodeBasicBlock.startIdx = 0;
            deadCodeBasicBlock.endIdx = 0;

            // set the dead code basic block as "not taken" target for the conditional branch of the checking basic block
            deadCodeBasicBlock.entryBranches.Add(startBasicBlockExitBranch);
            startBasicBlockExitBranch.notTakenTarget = deadCodeBasicBlock;

            // generate dead code for the dead code basic block
            GraphTransformerDeadCodeBasicBlock deadCodeMetadata = new GraphTransformerDeadCodeBasicBlock();
            deadCodeBasicBlock.transformationMetadata.Add(deadCodeMetadata);

            // set the created basic block and conditional jumps as output
            outStartBasicBlock = startBasicBlock;
            outConditionalBranch = startBasicBlockExitBranch;

        }
예제 #3
0
        // this function generates code for the "state switch"
        private void createCodeStateSwitch(ref BasicBlock outStateBasicBlock, ref SwitchBranchTarget outStateExitBranch, LocalDefinition intStateLocal, List<BasicBlockGraphNodeLink> links) {

            BasicBlock stateBasicBlock = new BasicBlock();
            stateBasicBlock.startIdx = 0;
            stateBasicBlock.endIdx = 0;

            // create graph transformer metadata for the basic block
            GraphTransformerStateBasicBlock stateMetadata = new GraphTransformerStateBasicBlock();
            foreach (BasicBlockGraphNodeLink link in links) {
                stateMetadata.correspondingGraphNodes.Add(link);
            }            
            stateBasicBlock.transformationMetadata.Add(stateMetadata);

            // create switch statement for the "state switch"
            stateBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, intStateLocal));
            uint[] switchSize = new uint[this.graph.graphValidPathCount];
            stateBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Switch, switchSize));

            // create exit branch for the new state basic block
            SwitchBranchTarget stateExitBranch = new SwitchBranchTarget();
            stateExitBranch.sourceBasicBlock = stateBasicBlock;
            stateBasicBlock.exitBranch = stateExitBranch;

            // create the dead code for this "state switch"
            BasicBlock deadCodeBasicBlock = new BasicBlock();
            deadCodeBasicBlock.startIdx = 0;
            deadCodeBasicBlock.endIdx = 0;

            // set the dead code basic block as "not taken" target for the conditional branch of the checking basic block
            deadCodeBasicBlock.entryBranches.Add(stateExitBranch);
            stateExitBranch.notTakenTarget = deadCodeBasicBlock; // TODO at the moment always the not taken branch of the switch statement is the dead code basic block

            // generate dead code for the dead code basic block
            GraphTransformerDeadCodeBasicBlock deadCodeMetadata = new GraphTransformerDeadCodeBasicBlock();
            deadCodeBasicBlock.transformationMetadata.Add(deadCodeMetadata);

            // set new created basic blocks and exit branch as output
            outStateBasicBlock = stateBasicBlock;
            outStateExitBranch = stateExitBranch;
        }
예제 #4
0
        // this function generates code for an opaque predicate that evaluates to "false"
        // => the "not taken" branch of the conditional branch have to be taken for the correct code path
        private void createCodeFalsePredicate(ref BasicBlock outStartBasicBlock, ref ConditionalBranchTarget outConditionalBranch, BasicBlockGraphNodeLink link, LocalDefinition currentNodeLocal) {

            // create a basic block that checks the opaque predicate (this check evaluates to "false")
            BasicBlock startBasicBlock = new BasicBlock();
            startBasicBlock.startIdx = 0;
            startBasicBlock.endIdx = 0;

            // add graph transformer metadata to the basic block
            GraphTransformerPredicateBasicBlock metadata = new GraphTransformerPredicateBasicBlock();
            metadata.predicateType = GraphOpaquePredicate.False;
            metadata.correspondingGraphNodes.Add(link);
            startBasicBlock.transformationMetadata.Add(metadata);

            // search for the valid and invalid interfaces list of the current valid path id
            List<ITypeReference> validInterfaces = null;
            List<ITypeReference> invalidInterfaces = null;
            foreach (PathElement pathElement in link.graphNode.pathElements) {
                if (pathElement.validPathId == link.validPathId) {
                    validInterfaces = pathElement.validInterfaces;
                    invalidInterfaces = pathElement.invalidInterfaces;
                }
            }
            if(validInterfaces == null
                || invalidInterfaces == null) {
                    throw new ArgumentException("No valid/invalid interface list was found.");
            }

            // add a random check to the code
            // important: for this predicate the dead code is reached by the "taken" branch and the correct code is reached by the "not taken" branch
            int randPosition;
            ITypeReference interfaceToCheck = null;
            switch (this.prng.Next(8)) {
                case 0:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(validInterfaces.Count());
                    interfaceToCheck = validInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Cgt_Un));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brfalse, 0));
                    break;

                case 1:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(validInterfaces.Count());
                    interfaceToCheck = validInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Cgt_Un));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldc_I4_0));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ceq));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brtrue, 0));
                    break;

                case 2:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(validInterfaces.Count());
                    interfaceToCheck = validInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Cgt_Un));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldc_I4_1));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ceq));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brfalse, 0));
                    break;

                case 3:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(validInterfaces.Count());
                    interfaceToCheck = validInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ceq));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brtrue, 0));
                    break;

                case 4:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(invalidInterfaces.Count());
                    interfaceToCheck = invalidInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Cgt_Un));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brtrue, 0));
                    break;

                case 5:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(invalidInterfaces.Count());
                    interfaceToCheck = invalidInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Cgt_Un));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldc_I4_0));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ceq));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brfalse, 0));
                    break;

                case 6:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(invalidInterfaces.Count());
                    interfaceToCheck = invalidInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Cgt_Un));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldc_I4_1));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ceq));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brtrue, 0));
                    break;

                case 7:
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldloc, currentNodeLocal));

                    randPosition = this.prng.Next(invalidInterfaces.Count());
                    interfaceToCheck = invalidInterfaces.ElementAt(randPosition);
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Isinst, interfaceToCheck));

                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ldnull));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Ceq));
                    startBasicBlock.operations.Add(this.helperClass.createNewOperation(OperationCode.Brfalse, 0));
                    break;

                default:
                    throw new ArgumentException("This case should never be reached.");
            }

            // create the conditional branch for the checking basic block (not taken => correct code; taken => dead code)
            ConditionalBranchTarget startBasicBlockExitBranch = new ConditionalBranchTarget();
            startBasicBlockExitBranch.sourceBasicBlock = startBasicBlock;
            startBasicBlock.exitBranch = startBasicBlockExitBranch;


            // create the dead code for this opaque predicate
            BasicBlock deadCodeBasicBlock = new BasicBlock();
            deadCodeBasicBlock.startIdx = 0;
            deadCodeBasicBlock.endIdx = 0;

            // set the dead code basic block as "taken" target for the conditional branch of the checking basic block
            deadCodeBasicBlock.entryBranches.Add(startBasicBlockExitBranch);
            startBasicBlockExitBranch.takenTarget = deadCodeBasicBlock;

            // generate dead code for the dead code basic block
            GraphTransformerDeadCodeBasicBlock deadCodeMetadata = new GraphTransformerDeadCodeBasicBlock();
            deadCodeBasicBlock.transformationMetadata.Add(deadCodeMetadata);

            // set the created basic block and conditional jumps as output
            outStartBasicBlock = startBasicBlock;
            outConditionalBranch = startBasicBlockExitBranch;

        }