1
|
|
2
|
- Vision Statement
- Process and Methodology
- Key Features
- Application scenarios
- What can we really do with RAIL?
- Conclusion
|
3
|
- “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.
|
4
|
|
5
|
|
6
|
- ‘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
|
7
|
- Runtime analysis tools
- Security verification
- MSIL optimization
- Application invisible proxy
substitution
- Software fault injection
- Aspect Oriented Programming
- Others!
|
8
|
- //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");
|
9
|
- //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");
|
10
|
- //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");
|
11
|
- //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");
|
12
|
- //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");
|
13
|
- //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");
|
14
|
- 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);
- }
|
15
|
- 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
|