170 likes | 332 Views
RAIL: Code Instrumentation for .NET. Paulo Marques, Bruno Cabral {pmarques,bcabral}@dei.uc.pt Dependable Systems Group University of Coimbra, Portugal. Code Instrumentation. The ability to modify an application after it has been compiled but before (or during) its execution
E N D
RAIL: Code Instrumentation for .NET Paulo Marques, Bruno Cabral{pmarques,bcabral}@dei.uc.ptDependable Systems Group University of Coimbra, Portugal
Code Instrumentation • The ability to modify an application after it has been compiled but before (or during) its execution • Application Scenarios: • Security Verifications, Dynamic Code Optimizers, Profiling, Fault Injection, AOP, among others
RAIL • Runtime Assembly Instrumentation Library • http://rail.dei.uc.pt • “An API that allows CLR assemblies to be manipulated and instrumented before they are loaded and executed” • Currently, one of the main high-level code instrumentation libraries for .NET
But what’s this RAIL API anyway? • Simple example: • How can you be sure that the application that you’ve downloaded from the Internet is not searching through your files??
RAIL • Suppose that you can open the application executable and substitute all class references from “File” to “SecureFileAccess”!!! Original File (but in binary code!) New File (also in binary code...) RAIL ... File theSecret; theSecret = newFile(“secret.doc”); ... data = theSecret.read(); internet.send(...); ... SecureFileAccess theSecret; theSecret = newSecureFileAccess(“secret.doc”); ... data = theSecret.read(); internet.send(...);
Proxy class class SecureFileAccess { File theRealFile; boolean accessPermited; SecureFileAccess(String filename) { logfile.write(“The foo is accessing {0}”, name); ... accessPermited = User.readPermitAccess(); theRealFile = new File(filename); } read() {if (accessPermited) { theRealFile.read(); } } } Real reference to the file Real File theSecret
// Load assembly into memory RAssemblyDef myAssembly = RAssemblyDef.LoadAssembly("Download.exe"); // Creates references for the old and new types to be used RType oldType = myAssembly.RModuleDef.GetType("File"); RType newType = myAssembly.RModuleDef.GetType("SecureFileAccess"); // Creates a reference replacer and apply the substitution ReferenceReplacer replacer = new ReferenceReplacer(oldType, newType); myAssembly.Accept(replacer); RAIL • Suppose that you can open the application executable and substitute all class references from “File” to “SecureFileAccess”!!! Original File (but in binary code!) New File (also in binary code...) RAIL ... File theSecret; theSecret = newFile(“secret.doc”); ... data = theSecret.read(); internet.send(...); ... SecureFileAccess theSecret; theSecret = newSecureFileAccess(“secret.doc”); ... data = theSecret.read(); internet.send(...);
What can be done with RAIL? • Iterate over code, injecting and removing code • Replace Type references • Add epilogues and prologues to methods • Redirect method accesses and calls • Redirect field and property accesses • Redirect field access to properties • Redirect field read and write access to methods • Manipulate custom attributes • Copy-Paste Types and Methods and IL code across assemblies • Manipulate Exception Blocks • Integration with CODEDOM
Source Code .cs Compile program.exe/dll PE Header Metadata IL Assembly JIT-compiler RAIL IL x86 Operating System
Object-OrientedRepresentation (diagram not complete)
Fully-configurable: Can use third-party libraries RAIL’s InternalStructure
Example Using CodeDom // Source code to usestring myProxy = @" using system; class SecureFileAccess { File theRealFile; boolean accessPermited; (...) }"; // Define the code in an assemblyRAssemblyDef dynamicAssembly = RAssemblyDef.CreateRAssemblyFromCode(myProxy, false); (...) // Creates references for the old and new types to be usedRType oldType = myAssembly.RModuleDef.GetType("File");RType newType = dynamicAssembly.RModuleDef.GetType("SecureFileAccess"); // Creates a reference replacer and apply the substitutionReferenceReplacer replacer = new ReferenceReplacer(oldType, newType);myAssembly.Accept(replacer);
Conclusion • High Level of Abstraction • No need for handling all the internal details of PEs • At the same time, has the ability to manipulate IL code directly • Object-oriented Model for representation of all assembly modules • Flexible MSIL instruction handling • Use of Design Patterns • One of the main high-level code instrumentation libraries for .NET
Questions? http://rail.dei.uc.pt