Upload
samuel-maldonado
View
215
Download
1
Embed Size (px)
Citation preview
Paulo Marques, Bruno Cabral{pmarques,bcabral}@dei.uc.pt
Dependable Systems Group University of Coimbra, Portugal
RAIL: Code Instrumentation for .NET
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”!!!
......
FileFile theSecret; theSecret;
theSecret = newtheSecret = new FileFile(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
......
FileFile theSecret; theSecret;
theSecret = newtheSecret = new FileFile(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
Original File (but in binary code!) RAIL......
SecureFileAccessSecureFileAccess theSecret; theSecret;
theSecret = newtheSecret = new SecureFileAccessSecureFileAccess(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
......
SecureFileAccessSecureFileAccess theSecret; theSecret;
theSecret = newtheSecret = new SecureFileAccessSecureFileAccess(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
New File (also in binary code...)
class class SecureFileAccessSecureFileAccess { {
File theRealFile;File theRealFile; boolean accessPermited; boolean accessPermited;
SecureFileAccess(String filename) {SecureFileAccess(String filename) { logfile.write(“The foo is accessing {0}”, name); logfile.write(“The foo is accessing {0}”, name); ... ... accessPermited = User.readPermitAccess(); accessPermited = User.readPermitAccess(); theRealFile = new File(filename); theRealFile = new File(filename); } }
read() {read() { if (accessPermited) {if (accessPermited) { theRealFile.read(); theRealFile.read(); } } } }
}}
class class SecureFileAccessSecureFileAccess { {
File theRealFile;File theRealFile; boolean accessPermited; boolean accessPermited;
SecureFileAccess(String filename) {SecureFileAccess(String filename) { logfile.write(“The foo is accessing {0}”, name); logfile.write(“The foo is accessing {0}”, name); ... ... accessPermited = User.readPermitAccess(); accessPermited = User.readPermitAccess(); theRealFile = new File(filename); theRealFile = new File(filename); } }
read() {read() { if (accessPermited) {if (accessPermited) { theRealFile.read(); theRealFile.read(); } } } }
}}
theSecrettheSecrettheSecrettheSecret
Proxy class
RealFile
Real reference to the file
RAIL Suppose that you can open the
application executable and substitute all class references from “File” to “SecureFileAccess”!!!
......
FileFile theSecret; theSecret;
theSecret = newtheSecret = new FileFile(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
......
FileFile theSecret; theSecret;
theSecret = newtheSecret = new FileFile(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
Original File (but in binary code!) RAIL......
SecureFileAccessSecureFileAccess theSecret; theSecret;
theSecret = newtheSecret = new SecureFileAccessSecureFileAccess(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
......
SecureFileAccessSecureFileAccess theSecret; theSecret;
theSecret = newtheSecret = new SecureFileAccessSecureFileAccess(“secret.doc”);(“secret.doc”);
......
data = theSecret.read();data = theSecret.read();
internet.send(...);internet.send(...);
New File (also in binary code...)
// Load assembly into memory RAssemblyDef myAssembly = RAssemblyDef.LoadAssembly("Download.exe");
// Creates references for the old and new types to be usedRType oldType = myAssembly.RModuleDef.GetType("File");RType newType = myAssembly.RModuleDef.GetType("SecureFileAccess");
// Creates a reference replacer and apply the substitutionReferenceReplacer replacer = new ReferenceReplacer(oldType, newType);myAssembly.Accept(replacer);
Development Model
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
Operating SystemOperating SystemOperating SystemOperating System
program.exe/dllprogram.exe/dllprogram.exe/dllprogram.exe/dll
PE HeaderPE Header
MetadataMetadata
ILIL
PE HeaderPE Header
MetadataMetadata
ILIL
ILIL x86x86
Source CodeSource Code
CompileCompile
AssemblyAssembly
JIT-compilerJIT-compiler
RAILRAIL
.cs
Structure of an Assembly
PE/COFF headers
CLR Header
CLR Data
Metadata IL code
Native Image Sections
.data, .rdata, .rsrc, .text
Managed Module
Metadata
IL code
Source Code
Managed Compiler
Common Language Runtime
Loader JIT Compiler
Internal DataStructures
Native Code
Execution engine
Object-OrientedRepresentation
(diagram not complete)
Assembly
RAIL
Mono.PEToolkit
RAIL.Reflect RAIL.MSIL
Rail High Level Instrumentation classes
System.Reflection
System.Reflection.Emit
AssemblyBuilder object
Assembly
Save
AppDomain
Load
Load
RAIL’s InternalStructure
Fully-configurable:Can use third-partylibraries
Source CodeCODEDOM
// Source code to usestring myProxy = @" using system;
class SecureFileAccess { File theRealFile; boolean accessPermited; (...) }";
// Define the code in an assembly RAssemblyDef 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);
Example Using
CodeDom
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