Reflection, Code Generation and Instrumentation in the .NET platform

Download Report

Transcript Reflection, Code Generation and Instrumentation in the .NET platform

“Reflection, Code Generation and
Instrumentation in the .NET platform”
Bruno Cabral
University of Coimbra
http://www.dei.uc.pt/~bcabral
Summary

PE File




2/33
Metadata
Introspection
Assembly and Code generation
Using RAIL
21 Jan 2004
PE File



PE = Portable Executable
Marked as Code and Execute
Read for the OS loader and
the CLR
_CorExeMain (mscoree.dll)
PE/COFF headers
CLR Header
CLR Data
Metadata
IL code
Native Image Sections
.data, .rdata, .rsrc, .text
3/33
21 Jan 2004
Source Code
PE File
Managed Compiler
Metadata



PE = Portable Executable
Marked as Code and
Execute Read for the OS
loader and the CLR
_CorExeMain
(mscoree.dll)
IL code
Managed Module
Common Language Runtime
Loader
JIT Compiler
Internal Data
Structures
Native Code
Execution engine
4/33
21 Jan 2004
Prime Module
PE File


Assembly Identity
Metadata
IL code
Multiple Modules
Module = file
Metadata
IL code
Module 1
Metadata
IL code
Module 2
5/33
21 Jan 2004
PE File - Metadata


"data about data"
Describes types


Describes signatures



Fields, properties, methods, delegates, local vars
Describes types and references
Describes miscellaneous entities

6/33
Member fields, methods, properties, events
Files, modules, assemblies
21 Jan 2004
PE File - Metadata

CIL instructions reference metadata via
TOKENS



7/33
First byte of token indicates type
Last three bytes of token are either row #
(tables) or offsets (heaps)
Tokens are stored compressed in signatures
(binary file viewers not very useful)
21 Jan 2004
PE File - Metadata

Tokens (and types) in listing






Only two are directly referenced by CIL in this
example: example:


8/33
MethodDef : (0x06000001)
User string: (0x70000001)
AssemblyRef : (0x23000001)
TypeRef : (0x01000003)
MemberRef : (0x0A000002)
String (by ldstr instruction)
MemberRef (by call instruction)
21 Jan 2004
PE File - Metadata
9/33
21 Jan 2004
PE File - Metadata
Token
MemberRef
MemberRef entity
TypeRef entity
AssemblyRef entity
Parent
ResolutionSco
pe
Version
Name
Name
Flags
Signature
NameSpace
Public Key
Name
Culture
Hash
10/33
21 Jan 2004
Introspection

Two major metadata APIs available



Both are limited in different ways



11/33
Managed: System.Reflection
Unmanaged: IMetaDataImport
System.Reflection does not permit access to CIL
System.Reflection does not reveal token values
IMetaDataImport cannot resolve *Ref tokens
21 Jan 2004
Introspection

What can we do with System.Reflection?






12/33
See
See
See
See
See
…
loaded assemblies
referenced assemblies
the types defined in the assembly
the methods defined in a type
attributes
21 Jan 2004
Introspection

See loaded assemblies
Assembly [] assemblies =
AppDomain.CurrentDomain.GetAssemblies();
foreach( Assembly assembly in assemblies )
Console.WriteLine( assembly.FullName );
13/33
21 Jan 2004
Introspection

See referenced assemblies
AssemblyName[] referencedAssemblies =
assembly.GetReferencedAssemblies();
foreach( AssemblyName assemblyName in referencedAssemblies )
Console.WriteLine( "--> {0}", assemblyName.FullName );
14/33
21 Jan 2004
Introspection

See the types defined in the assembly
Assembly a = Assembly.LoadFrom("Teste.exe");
Module[] m = a.GetModules( );
Console.WriteLine("\n" + a.FullName );
Type[] types = m[0].GetTypes( );
foreach( Type type in types )
Console.WriteLine( "==> {0}", type.FullName );
15/33
21 Jan 2004
Introspection

See the methods defined in a type
Assembly a = Assembly.LoadFrom("HelloWorld.exe");
Module[] m = a.GetModules( );
Type[] types = m[0].GetTypes( );
Type type = types[0];
MethodInfo[] mInfo = type.GetMethods( );
foreach ( MethodInfo mi in mInfo )
Console.WriteLine(" {0}", mi);
16/33
21 Jan 2004
Assembly and Code
Generation

How to use System.Reflection.Emit to
generate assemblies in run-time?


17/33
AssemblyBuilder, ModuleBuilder, TypeBuilder,
MethodBuilder, …
ILGenerator
21 Jan 2004
Assembly and Code
Generation
AssemblyName myAssemblyName = new AssemblyName();
myAssemblyName.Name = "MyAssembly";
myAssemblyName.Version = new Version("1.0.0.2004");
18/33
21 Jan 2004
Assembly and Code
Generation
AssemblyBuilder myAssemblyBuilder =
Thread.GetDomain().DefineDynamicAssembly(myAssemblyName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder myModuleBuilder =
myAssemblyBuilder.DefineDynamicModule("MyModule", fileName);
TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("MyType");
19/33
21 Jan 2004
Assembly and Code
Generation
MethodBuilder myMethodBuilder =
myTypeBuilder.DefineMethod("Main", MethodAttributes.Public |
MethodAttributes.HideBySig |MethodAttributes.Static,
typeof(void), null);
ILGenerator myILGenerator = myMethodBuilder.GetILGenerator();
myILGenerator.EmitWriteLine("Hello World!");
myILGenerator.Emit(OpCodes.Ret);
20/33
21 Jan 2004
Assembly and Code
Generation
myTypeBuilder.CreateType();
myAssemblyBuilder.SetEntryPoint(myMethodBuilder);
myAssemblyBuilder.Save(fileName);
21/33
21 Jan 2004
What is missing?



22/33
Reflection
Generation
…
21 Jan 2004
What is missing?



Reflection
Generation
INTRUMENTATION…



23/33
Structural Reflection
Behavioural Reflection
HOW TO DO IT?
21 Jan 2004
…use RAIL
http://rail.dei.uc.pt
24/33
21 Jan 2004
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.



25/33
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.
21 Jan 2004
Process and Methodology
program
Source Code
Compile
program.exe/dll
PE Header
Metadata
Assembly
IL
JIT-compile
RAIL
IL
x86
Operating System
26/33
21 Jan 2004
Process and Methodology
Programmer
Manipulate the assembly
by modifying the objects structure
Run new assembly
RAIL
Assembly
27/33
Load assembly
Collect metadata and
MSIL code into a set
of objects
Create AssemblyBuilder
21 Jan
Save new assembly
2004
Key features





28/33
‘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
21 Jan 2004
Application scenarios







29/33
Runtime analysis tools
Security verification
MSIL optimization
Application invisible proxy substitution
Software fault injection
Aspect Oriented Programming
Others!
21 Jan 2004
What can we really do with RAIL?
Replace References
Add epilogues and prologues to methods
Redirect methods access/call
Redirect field access
Redirect field access to property
Redirect field read and write access to methods
Redirect property access
Replace create new instructions with a static method
Create, Run and Save assemblies
30/33
21 Jan 2004
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);
}
31/33
21 Jan 2004
Assembly Loading Interception

ResolveEventHandler
currentDomain.AssemblyResolve +=
new ResolveEventHandler(MyResolveEventHandler);



32/33
Load the assembly ourselves
Modify the CLR (SSCLI)???
Others??
21 Jan 2004
Conclusion




33/33
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
21 Jan 2004