Regarding static checking.

Jun 22, 2009 at 4:57 PM

I am new to CCI and am trying to work with code instrumentation. Can you help me to get started. I want to know how to wrk on the statement level for instance in this example C# code there is no null check for parameter a, which will result in Exception of it has been instantiated null at run time. I want to know how do I go about finding these conditions using CCI. An example would be appriciated and is there any documentation available which I can look up for the same.

public bool sample(string a, Boolean b)

        {

            if ((a == "1") && (b))

                return true;

            else

                return false;

        }

Thanks in advance.

Regards,

Rahul Pandita

Jun 24, 2009 at 8:29 PM

I was able to get to the conditional statement level and obtain an object implementing "IConditionalStatement" by in Visit(IMethodBody methodBody) function of SourceEmitter class of AST sample.  I also figured out the I can get get "IExpression" from it but still am strugling with finding the boundary values for expression. As in the example above I want to know what variables are being used, which are "a" and "b" and what are they being compared to. Can anyone help me in this regard.

 

Thanks in advance.

Regards,

Rahul Pandita

Coordinator
Jun 25, 2009 at 2:02 PM

I am not quite clear on what you are tring to do. The statement level (Code Model) is a good fit for adding instrumentation (code) to an existing program. However, code analysis, such as finding which expressions may fail at runtime because of null dereference errors is a much harder problem. Frameworks for doing such analyses have been built on top of CCI, but are not part of CCI. Building such a framework can be years of effort.

Jun 25, 2009 at 3:45 PM

Thank you hermanv,

I understand that these checks are not a part of CCI and its a mamoth effort. I wanted to know how do I get the variable names and the associated comparison values in an Expression, pertaining to this example I want to know How can I extract the following information from the code statement "if ((a == "1") && (b))" 

  • A String type variable a is compared with a String "1"
  • A Boolean type variable b is evaluated for true value.
  • Finally logical && of the output is evaluated

Also you mentioned that frameworks have been built on top of CCI, are they open source. Can I have a look at the code base. Can you kindly link me to them.

 

Thanks in advance.

Regards,

Rahul Pandita

Coordinator
Jun 25, 2009 at 4:17 PM

The IConditionalStatement will have an object in its Condition property that implements IConditional (the && expression will have been encoded as a == "1" ? b : false, which is an IConditional). The a == "1" will be in the Condition property of the ICondtional object. It will be an IEquality object and LeftOperand will be an IBoundExpression while RightOperand will be an ICompileTimeConstant. The Definition property of the IBoundExpression will be an IParameterDefinition. And so on.

I am not sure what you mean by "boundary value". If you are wondering about the set of all interface types that ultimately implement IExpression, then you'd probably be best off if you just look at the source code in Expressions.cs in the CodeModel project.

At present there are no open source analysis frameworks built on top of CCI that I'm aware of.

Jul 20, 2009 at 3:59 AM
Edited Jul 20, 2009 at 4:00 AM

Thank you again for the previous reply.

I am working on Instrumentation of the assembly. I have following query. This is a sample code which I want to instrument.

class larger

 {

        public void sample(int x)

        {

            if (x > 10)

            {

                Console.WriteLine("Greater than 10");

            }

            else

            {

                Console.WriteLine("Less than 11");

            }

        }

    }

I am interested after the if condition. I want to add an assumption statement in the block following it. Following your PeToPe sample I found out that for this example class in "private class CreateMutableType" under CodeMutator class the function "Visit(IConditionalStatement conditionalStatement)" is being called 5 times. To cross check it I found out the function Visit(IGreaterThan greaterThan) is also being called 5 times. In presence of insufficient documentation I am unsure what is happenning. I want to add an Assume statement after the if condition. For that I need to to identify when an IF condition is encountered. According to the previous replies I am looking for the ConditionalStatements as the code is being Visited. Am I looking in a wrong place alltogether??

Can someone guide me on this.

Thanks in advance,

Rahul Pandita

Coordinator
Jul 20, 2009 at 6:22 AM

The IL decompiler does several passes over the object model. You want to add yet another pass by making your own mutator and getting it to visit the decompiled object model, while making the changes you desire. Your mutator should see a single call to Viist(IConditionalStatement).

Jul 20, 2009 at 3:57 PM
Edited Jul 20, 2009 at 4:17 PM

Thanks again for the response, that was really quick. Appreciated for the time and patience. 

I am still unsure of how to go about it can you give me a basic example as to how to add a statement in the decompiled object model.

It would really be helpful.

I am sorry for the naive questions.

 

I have created a my own mutator and am calling Visit(Assembly) function over it, but still the control is not passed to Visit(ConditionalStatement) or Visit(GreaterThan)

The input to the constructor are same as the input to the SourceMutator initialised previously. Should I create new  IMetadataHost, SourceMethodBodyProvider , SourceToILConverterProvider, ISourceLocationProvider. 

class AssumptionAdder: CodeMutator

    {

        IModule module;

 

        public AssumptionAdder(IMetadataHost host, SourceMethodBodyProvider ilToSourceProvider, SourceToILConverterProvider sourceToILProvider, ISourceLocationProvider/*?*/ sourceLocationProvider)

            : base(host, ilToSourceProvider, sourceToILProvider, sourceLocationProvider)

        {

            //this.copyOnlyIfNotAlreadyMutable = false;

        }

 

 

        public override IStatement Visit(ConditionalStatement conditionalStatement)

        {

            Console.WriteLine("TBD1");

            return base.Visit(conditionalStatement);

        }

 

        public override IExpression Visit(GreaterThan greaterThan)

        {

            Console.WriteLine("TBD2");

            return base.Visit(greaterThan);

        }

 

class AssumptionAdder: CodeMutator
    {
        IModule module;
        public AssumptionAdder(IMetadataHost host, SourceMethodBodyProvider ilToSourceProvider, SourceToILConverterProvider sourceToILProvider, ISourceLocationProvider/*?*/ sourceLocationProvider)
            : base(host, ilToSourceProvider, sourceToILProvider, sourceLocationProvider)
        {
            //this.copyOnlyIfNotAlreadyMutable = false;
        }
        public override IStatement Visit(ConditionalStatement conditionalStatement)
        {
            Console.WriteLine("TBD1");
            return base.Visit(conditionalStatement);
        }
        public override IExpression Visit(GreaterThan greaterThan)
        {
            Console.WriteLine("TBD2");
            return base.Visit(greaterThan);
        }

 

 

Thanks in advance

Rahul Pandita 

Jul 20, 2009 at 6:51 PM

Sorry for repeated posts but I figured out what was wrong previously, I was calling visit(IAssembly) instead of visit(Assembly) so that part is solved. (But thank you for the time you spent trying to figure out what was wrong)

can you help me with this I have written my own mutator and on every true branch of a conditional statement I want to insert an assumption that

the condition is true. For that I have written following code.  

 

public override IStatement Visit(ConditionalStatement conditionalStatement)
        {
            if (!assume)
            {
                Statement statement = ExtractCondition(conditionalStatement.Condition as Expression);
                BlockStatement blockStatement = conditionalStatement.TrueBranch as BlockStatement;
                Console.WriteLine(blockStatement.Statements.Count);
                if (blockStatement != null)
                {
                    List<IStatement> statementList = new List<IStatement>();
                    statementList.Add(statement as IStatement);
                    foreach (Statement stmt in blockStatement.Statements)
                    {
                        statementList.Add(stmt as IStatement);
                    }
                    blockStatement.Statements = statementList;
                    Console.WriteLine(blockStatement.Statements.Count);
                }
                conditionalStatement.TrueBranch = blockStatement;
            }
            return base.Visit(conditionalStatement);
        }
        private Statement ExtractCondition(Expression expression)
        {
            if (expression as GreaterThan != null)
            {
                IExpression condition = Traverse(expression as GreaterThan);
                AssumeStatement assume = new AssumeStatement();
                assume.Condition = condition;
                return assume as Statement;
            }
            return new AssumeStatement() as Statement;
        }

 

public override IStatement Visit(ConditionalStatement conditionalStatement)

        {

            if (!assume)

            {

                AssumeStatement assume = new AssumeStatement();

                assume.Condition = conditionalStatement.Condition as Expression;

Statement statement = assume as Statement;

                BlockStatement blockStatement = conditionalStatement.TrueBranch as BlockStatement;

                if (blockStatement != null)

                {

                    List<IStatement> statementList = new List<IStatement>();

                    statementList.Add(statement as IStatement);

                    foreach (Statement stmt in blockStatement.Statements)

                    {

                        statementList.Add(stmt as IStatement);

                    }

                    blockStatement.Statements = statementList;

                }

                conditionalStatement.TrueBranch = blockStatement;

            }

            return base.Visit(conditionalStatement);

        }

I see that the statement is being added and being visited in Visit(AssumeStatement) method, but the output dosent change. (I ran PeToText sample on the generated PE)

The PE file produced now when run gives out error that it is not a valid Win32 application which was not the case earlier. But PeToText does not have any problem when the file is Visited.

Can you help me on that.

Thanks in Advance,

Rahul Pandita

Coordinator
Jul 30, 2009 at 4:52 PM

Looking at your example it is not clear to me what the problem is. One way you can try to debug this is to comment out statements until the out produced is a valid Win32 application (be sure to run PEVerify). Then add back the statements one by one until the output is invalid. Perhaps things will then be clear.

If not, please construct an example that I can compile and execute, so that I can look at your example in the debugger, which makes it much easier for me to understand what is going on.

Jul 31, 2009 at 4:49 AM

I tried solving the issue as Directed but could not find anything substantial. 

So I switched to another approach using a refrence to PexAssume.IsTrue(bool); method from Microsoft Pex framework

it is static method of a static class having one boolean argument. I am stuck with the following issue.

The statement gets embedded into the PE (verified with PEtoText sample) cleanly but when the generated PE is executed the following exception occurs

System.MissingMethodException was unhandled

Message: Method not found: 'Void Microsoft.Pex.Framework.PexAssume.IsTrue(Void)'.

The code to generate the method refrence is

 

 

 


Microsoft.Cci.MethodReference methodRef;

 

HostEnvironment host1 = this.host as HostEnvironment;

List<IParameterTypeInformation> parameters = new List<IParameterTypeInformation>();

//paramTypeInfo.ContainingSignature = ??

paramTypeInfo.Type = host1.PlatformType.SystemBoolean;

parameters.Add(paramTypeInfo);

methodRef = new Microsoft.Cci.MethodReference(host1, host1.myplatform.PexAssume, CallingConvention.Default, host1.PlatformType.SystemVoid, host.NameTable.GetNameFor("IsTrue"), 1, parameters, this.host.PlatformType.SystemBoolean);

MethodCall methodCall = new MethodCall();

methodCall.MethodToCall = methodRef;

methodCall.Arguments = new List<IExpression> { expression };

methodCall.IsStaticCall = true;

 


 

I am doing the cast to HostEnvironment because I have defined myplatform property over there as (followed it up from the other post :-) )


this.pexAssume = this.CreateReference(this.pexAssemblyRefernce, true, "Microsoft.Pex.Framework", "PexAssume");

 

where pexAssemblyRefrence is the refernce to Assembly which was loaded into the host from the MicrosoftPexFramework.dll. 

 

 

 

 

 

System.MissingMethodException was unhandled
Message: Method not found: 'Void Microsoft.Pex.Framework.PexAssume.IsTrue(Void)'.I