Recommending a Strategy by liamei12345

VIEWS: 3 PAGES: 15

									 Bruno Cabral
http://rail.dei.uc.pt
Summary
   Vision Statement
   Process and Methodology
   Key Features
   Application scenarios
   What can we really do with RAIL?
   Conclusion
Vision Statement
   “Create an API that allows CLR assemblies to
    be manipulated and instrumented before they
    are loaded and executed“
       The reflection capabilities of the CLR are extremely powerful.
            Query the existing types at runtime
            Define new assemblies in memory and use Reflection.Emit to
             generate MSIL on-the-fly.
   Our plan is to fill the gap between these two concepts.
Process and Methodology
                       program           Source Code
                               Compile

                 program.exe/dll
                   PE Header
                       Metadata           Assembly
  JIT-compile             IL

                                                 RAIL
                  IL             x86


                Operating System
 Process and Methodology                          Programmer




                                              Manipulate the assembly
                                          by modifying the objects structure
                                                                                                Run new assembly




                                                        RAIL




                           Collect metadata and
Assembly   Load assembly   MSIL code into a set                        Create AssemblyBuilder
                                 of objects




                                                                                                Save new assembly
Key features
   ‘Rapid’ assembly instrumentation library
   High level of abstraction, no need for
    handling all the internal details
   Convenient object model for
    representation of all assembly modules
   Flexible MSIL instruction handling
   Use of design patterns
Application scenarios
   Runtime analysis tools
   Security verification
   MSIL optimization
   Application invisible proxy substitution
   Software fault injection
   Aspect Oriented Programming
   Others!
   What can we really do with RAIL?
Replace References
//Create the RAssemblyDef objects of the two assemblies
RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly("Teste.exe");
RAssemblyDef rAssembly2 = RAssemblyDef.LoadAssembly("Teste2.dll");
//Get the type to copy from assembly Teste2.dll to assembly Teste.exe
RType typeToCopy = rAssembly2.RModuleDef.GetType("Bar");
//Copies the type Bar to Teste.exe assembly
rAssembly.RModuleDef.CopyType(typeToCopy,typeToCopy.Name);
//Creates the RType instances of the to types
RType oldType = rAssembly.RModuleDef.GetType("Foo");
RType newType = rAssembly.RModuleDef.GetType("Bar");
//Creates the ReferenceReplacer visitor object
ReferenceReplacer rr = new ReferenceReplacer(oldType,newType);
//Aplly the change to the assembly an its members
rAssembly.Accept(rr);
//Remove the previous used type Foo
rAssembly.RModuleDef.RemoveType("Foo");
//Save the new assembly
rAssembly.SaveAssembly("Teste.exe");
   What can we really do with RAIL?
Add epilogues and prologues to methods
//Create the RAssemblyDef instance for the Teste3.exe assembly
RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly("Teste3.exe");
//Get the RType object of the FooBar type
RType rtd = rAssembly.RModuleDef.GetType("FooBar");
//Create an array of RParameter objects
RParameter [] paramsz = new RParameter[1];
//Set the first element of the array
paramsz[0] = new RParameter(0,rAssembly.GetType("System.String"));
//Get the method which code is to be inserted at the start of the method
RMethodDef rmd0 =
     (RMethodDef)rtd.GetMethod("WriteToScreenBefore",rAssembly.GetType("System.Void"),paramsz);
//Get the method which code is to be inserted at the end of the method
RMethodDef rmd1 =
     (RMethodDef)rtd.GetMethod("WriteToScreenAfter",rAssembly.GetType("System.Void"),paramsz);
//Get the method to instrument
RMethodDef rmd2 = (RMethodDef)rtd.GetMethod("MyMethod",rAssembly.GetType("System.Void"),paramsz);
//Create the CodeTransformer object
CodeTransformer cc = new CodeTransformer();
//Set the transformations to make in the code
cc.InsertAtMethodStart(rmd0);
cc.InsertAtMethodEnd(rmd1);
//Apply the change to the code
rmd2.Accept(cc);
//Save the new assembly
rAssembly.SaveAssembly("Teste3.exe");
   What can we really do with RAIL?
Redirect methods access/call
//Create the RAssemblyDef instance for the Teste3.exe assembly
RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly("Teste3.exe");
//Get the RType object for the type that declares the methods
RType rtd = rAssembly.RModuleDef.GetType("FooBar");
//Create a RParameter object array
RParameter [] paramsz = new RParameter[1];
//Set the first element of the array
paramsz[0] = new RParameter(0,rAssembly.GetType("System.String"));
//Get the method to replace the original
RMethodDef rmdReplacer =
      (RMethodDef)rtd.GetMethod("wrt",rAssembly.GetType("System.Void"),paramsz);
//Get the original method
RMethodDef rmdOriginal =
      (RMethodDef)rtd.GetMethod("MyMethod",rAssembly.GetType("System.Void"),paramsz);
//Create a CodeTransformer object
CodeTransformer cc = new CodeTransformer();
//Set the transformation to make in the code
cc.RedirectMethodCall(rmdOriginal,rmdReplacer);
// Aplly the transformation to all methods and constructors
// in the in the assembly
rAssembly.Accept(cc);
//Save the method
rAssembly.SaveAssembly("Teste3.exe");
  What can we really do with RAIL?
Redirect field access
Redirect field access to property
Redirect field read and write access to methods
   //Create the RAssemblyDef representation of the Teste3.exe assembly
   RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly("Teste3.exe");
   //Get the RTypeDef obejct for the type where the field and property are declared
   RTypeDef rtd = (RTypeDef)rAssembly.RModuleDef.GetType("FooBar");
   //Get tje constructor method where to apply the changes
   RConstructorDef rcd = (RConstructorDef)rtd.GetConstructor(new RType[0]);
   //Get the field
   RField rfld1 = rtd.GetField("Val1");
   //Get the property
   RProperty rprop = rtd.GetProperty("Prop");
   //Create the code trasnformer object
   CodeTransformer cc = new CodeTransformer();
   //Set the transformation to make in the code
   cc.RedirectFieldAccess(rfld1,rprop);
   //Apply the changes
   rcd.Accept(cc);
   //Save the assembly
   rAssembly.SaveAssembly("Teste3.exe");
   What can we really do with RAIL?
Redirect property access
//Create the RAssemblyDef representation of the Teste3.exe assembly
RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly("Teste3.exe");
//Get the RTypeDef object for the type where teh properties are declared
RTypeDef rtd = (RTypeDef)rAssembly.RModuleDef.GetType("FooBar");
//Get the constructor method where to apply the changes
RConstructorDef rcd = (RConstructorDef)rtd.GetConstructor(new RType[0]);
//Get the property to be replaced
RProperty rpro1 = rtd.GetProperty("Prop");
//Get the replacement property
RProperty rpro2 = rtd.GetProperty("Prop2");
//Create the code transformer object
CodeTransformer cc = new CodeTransformer();
//Set the transformations to make in the code
cc.RedirectPropertyAccess(rpro1,rpro2);
//Aplly th changes
rcd.Accept(cc);
//Save the assembly
rAssembly.SaveAssembly("Teste3.exe");
   What can we really do with RAIL?
Replace create new instructions with a static method
Create, Run and Save assemblies
//Create the RAssemblyDef representation of the Teste3.exe assembly
RAssemblyDef rAssembly = RAssemblyDef.LoadAssembly("Teste3.exe");
//Get the RTypeDef object for the type where the method is declared
RTypeDef rtd = (RTypeDef)rAssembly.RModuleDef.GetType("FooBar");
//Get the RTypeDef of the object to create with the create new instruction
RTypeDef rtd2 = (RTypeDef)rAssembly.RModuleDef.GetType("ReferencedClass");
//Get the constructor method where to apply the changes
RConstructorDef rcd = (RConstructorDef)rtd.GetConstructor(new RType[0]);
//Get to raplacement method
RMethod rmGet = rtd.GetMethod("GetVal",rtd2,new RParameter[0]);
//Create a code transformer object
CodeTransformer cc = new CodeTransformer();
//Set the transformation to make in the code
cc.ReplaceNew(rtd2,rmGet);
//Aplly the changes
rcd.Accept(cc);
//Save the new assembly
rAssembly. RunAndSaveAssembly("Teste3.exe");
    What can we really do with RAIL?
Play with MSIL code!!

private void Replace(MSIL.Code code, int pos)
{
    MSIL.ILMethod ilm = new MSIL.ILMethod(OpCodes.Call, this.newMethod);
    code.Remove(pos);
    code.Insert(pos,ilm);

}
Conclusion

   Code instrumentation is not a simple task
   With RAIL it’s easy to develop high level
    functionalities
   Assembly creation mechanisms can be
    very slow
   The design patterns are very useful

								
To top