Microsoft's .NET Implementation
Matthew Conover
April 2002
What is .NET?
• .NET = dumb name
• .NET != web services
• .NET is a framework
• .NET is platform independent
• .NET is language insensitive
• .NET specs are publicly available
2
Topics of Discussion
• Introduction to .NET
• Assemblies
• Microsoft’s implementation of .NET
• .NET Hook (dotNetHook) tool
3
Introduction to .NET
• .NET CLI specifications (ECMA)
– Partition I – Architecture
– Partition II – Metadata
– Partition III – CIL
– Partition IV – Library
– Partition V – Annexes
– Class Library (XML specification)
4
Introduction to .NET
• Base Class Library (BCL)
– Shared among all languages
• Common Language Runtime (CLR)
– Common Type System (CTS)
– Common Language Specification (CLS)
– Execution Engine
5
Base Class Library
• Similar to Java’s System namespace.
• Has classes for IO, threading, database, text, graphics,
console, sockets/web/mail, security, cryptography,
COM, run-time type discovery/invocation, assembly
generation
6
Common Language Runtime
• Common Type Specification
– Specifies certain types required to be hosted by CLR
– Specifies rules for class, structure, enumeration, interfaces,
delegates, etc.
– Everything is actually an object
7
Common Language Runtime
• Execution Engine
– Handles object layout/references
– Handles garbage collection
• Managed heap
– Enforces code access security
– Handles verification
• Safe methods can only do safe things
– Compiles MSIL (bytecode) into native code
8
Common Language Runtime
Assembly
BCL Class Loader External Assembly
JIT
Execution Engine
Machine Code
9
Assemblies
• Single-file or multi-file assemblies
• Components:
– Manifest
– Metadata
– MSIL (or native) code
– Resources
10
Manifest
• Defines assembly
• Strong name
• Files in the assembly
• Type references
• Referenced assemblies
1
Metadata
• Contains all .NET data
• Streams
– #Strings
– #Blob
– #GUID
– #US
– #- or #~
• Tables (stored in #- or #~)
– In a predefined order
– I.e., MethodDef, AssemblyRef, Constant
12
Metadata
Signature, Version, Flags
Stream count Metadata Header
Data offset
Stream size Stream Header 1
Name
… Stream Header 2
… Stream bodies
13
#~ and #- Stream
Version
Heap sizes
Tables Header
Valid tables
Sorted tables
Table row count Valid Table 1
… Valid Table 2
… Table bodies
14
MethodDef Table (0x06)
RVA Offset to method
Implementation flags
Method flags
Method name Offset into #Strings
Signature Offset into #Blob
Parameters Index into Param table (0x08)
15
MethodDef Table (0x06)
Param Table (0x08)
Flags
Sequence number
Parameter name Offset into #Strings
Signature Blob
Flags
Parameter count
Return type
Parameter types 16
MSIL
• Pseudo-assembly
– nop, break, ret, call, callvirt, newobj, newarr, add, mul, xor, arglist,
sizeof, throw, catch, dup
• 0xFE = first byte of two byte opcodes
• Uses “tokens” instead of offsets/pointers
• All calls are stack based
– “this” pointer passed as first argument
– Arguments passed left-to-right by default
– varargs passes an extra signature
17
MSIL
ldc.i4.s 9 0x1f 0x09
IL
call Print(Int32) Assembler 0x28 0x06000006
Method token
Token
Table Number Row Index
Upper 8 bits Lower 24 bits
18
Call Stack
ClassType a; ldc.i4.1
a.func(1, 2) ldc.i4.2
call ClassType::func(Int32, Int32)
1
2
this pointer
Stack top
Left-to-right ordering
19
MSIL Samples
• Ldloc
– Puts value on stack from a local variable
• Ldarg
– Puts an argument on the stack
• Ldlen
– Puts the length of an array on the stack
• Ldelem
– Puts the value of an element on the stack
• Ld*a
– Puts the address of something on the stack
20
MSIL Samples (cont.)
• Brtrue
– Branch to target if value on stack is true
• Dup
– Duplicate a value on the stack
• Ldnull
– Puts a null value on the stack
2
Microsoft’s .NET Implementation
• %SystemRoot%\Microsoft.NET
• %SystemRoot%\Assembly +
– \GAC
– \NativeImages*
22
System Libraries
• mscoree.dll (execution engine)
• mscorjit.dll (contains JIT)
• mscorsn.dll (strong name)
• mscorlib.dll (BCL)
• fushion.dll (assembly binding)
23
.NET Application
• Jumps to _CorExeMain (mscoree)
• Calls _CorExeMain in mscorwks.dll
• _CorExeMain calls CoInitializeEE
• CoInitializeEE calls:
– EEStartup
– ExecuteEXE
24
EEStartup
• GCHeap.Initialize
– Managed heap = Doug Lea’s malloc?
• ECall.Init
– SetupGenericPInvokeCalliStub
– PInvokeCalliWorker
• NDirect.Init
• UMThunkInit.UMThunkInit
• COMDelegate.Init
• ExecutionManger.Init
• COMNlsInfo.InitializeNLS 25
EEStartup (cont.)
• Security::Start
• SystemDomain.Init
– Loads BCL
• SystemDomain.NotifyProfilerStartup
• SystemDomain.NotifyNewDomainLoads
• SystemDomain.PublishAppDomainAndInformDebugger
(ICorPublish/ICorDebug)
26
SystemDomain.Init
• LoadBaseSystemClasses
• SystemDomain.CreatePreallocatedExceptions
27
LoadBaseSystemClasses
• SystemDomain.LoadSystemAssembly
– Loads mscorlib.dll
• Binder::StartupMscorlib
• Binder::FetchClass(OBJECT)
• MethodTable::InitForFinalization
• InitJITHelpers2
• Binder::FetchClass(VALUE)
• Binder::FetchClass(ARRAY)
28
LoadBaseSystemClasses
• Binder.FetchType(OBJECT_ARRAY)
• Binder.FetchClass(STRING)
• Binder.FetchClass(ENUM)
• Binder.FetchClass(ExceptionClass)
• Binder.FetchClass(OutOfMemoryExceptionClass)
• Binder.FetchClass(StackOverflowExceptionClass)
29
LoadBaseSystemClasses
• Binder.FetchClass(ExecutionEngineExceptionClass)
• Binder.FetchClass(DelegateClass)
• Binder.FetchClass(MultiDelegateClass)
30
.NET Application (review)
• Jumps to _CorExeMain (mscoree)
• Calls _CorExeMain in mscorwks.dll
• _CorExeMain calls CoInitializeEE
• CoInitializeEE calls:
– EEStartup
– ExecuteEXE
3
ExecuteEXE
• StrongNamesignatureVerification
– In mscorsn.dll
• PEFile::Create
– Loads executable
• ExecuteMainMethod
• FushionBind.CreateFushionName
• Assembly.ExecuteMainMethod
32
ExecuteMainMethod
• Thread.EnterRestrictiedContext
• PEFile::GetMDImport
• SystemDomain.SetDefaultDomainAttributes
– Sets entry point
• SystemDomain.InitializeDefaultDomain
• BaseDomain.LoadAssembly
33
BaseDomain.LoadAssembly
• BaseDomain.ApplySharePolicy
• AssemblySecurityDescriptor.Init
• Module.Create
• BaseDomain.SetAssemblyManifestModule
• AssemblySecurityDescriptor.AddDescriptorToDomainLis
t
34
ExecuteEXE (review)
• StrongNamesignatureVerification
– In mscorsn.dll
• PEFile::Create
– Loads executable
• ExecuteMainMethod
• FushionBind.CreateFushionName
• Assembly.ExecuteMainMethod
35
Assembly.ExecuteMainMethod
• Assembly::GetEntryPoint
• ClassLoader::ExecuteMainMethod
– EEClass:FindMethod(entry point token)
36
EEClass.FindMethod
• ValidateMainMethod
• CorCommandLine.GetArgvW
• MethodDesc.Call
– MethodDesc.IsRemotingIntercepted
– MethodDesc.CallDescr calls MethodDesc.CallDescrWorker
– CallDescrWorker calls Main()
37
.NET Application
• Main() needs to be compiled
• Main() calls PreStubWorker (mscorwks)
• PreStubWorker
– Compiles all IL methods
– Calls MethodDesc.DoPrestub
38
MethodDesc.DoPrestub
• MethodDesc.GetSecurityFlags
• MethodDesc.GetUnsafeAddrofCode
• MethodDesc.GetILHeader
• MethodDesc.GetRVA
• COR_DECODE_METHOD
– Decode tiny/fat format
• Security._CanSkipVerification
39
MethodDesc.DoPrestub
• EEConfig.ShouldJitMethod
• MakeJitWorker
– JITFunction
– GetPrejittedCode
40
JITFunction
• ExecutionManager::GetJitForType
– EEJitManager::LoadJIT
– Loads mscorjit.dll (in LoadJIT)
– Calls getJit in mscorjit (in LoadJIT)
• CallCompileMethodWithSEHWrapper
– Debugger.JitBeginning
– CILJit.compileMethod
– Debugger.JitComplete
4
CILJit.compileMethod
• Calls jitNativeCode
• jitNativeCode
– Compiler.compInit
– Compiler.compCompile
42
Compiler.compCompile
• Compiler.eeGetMethodClass
• Compiler.eeGetClassAttribs
• emitter.emitBegCG
• Compiler.eeGetMethodAttribs
• Compiler.comptInitDebuggingInfo
• Compiler.genGenerateCode
• emitter.emitEndCG
43
Compiler.genGenerateCode
• emitter.emitBegFN
• Compiler.genCodeForBBlist
• Compiler.genFnProlog
• Compiler.genFnEpilog
• emitter.emitEndCodeGen
• Compiler.gcInfoBlocKHdrSave
• emitter.emitEndFN
44
.NET Application
• Show flowchart
45
.NET Hook
• Reads through method table
• Reads method
– Parses header, code, EH data
• Hooks interest functions
– Inserts hooked code at front of method
– Stored at the end of the .text section
• Updates PE and section headers
• Changes function RVAs in Metadata
46
Method Definition (review)
RVA Offset to method
Implementation flags
Method flags
Method name Offset into #Strings
Signature Offset into #Blob
Parameters Index into Param table (0x08)
47
Tiny Method Body
• Header size = 1 byte
• Used when:
– Maximum stack size is less than 8
– The method has no local variables
– No extra data section
– No exceptions
48
Tiny Method
Header (flags and code size)
Method body (IL)
49
Fat Method
• Header size = 12 bytes
Flags
Header size
Max. stack size
Code size
Local var. signature Describes local variables
Method body (IL)
Extra data sections Currently only used for exceptions
50
Hooked Tiny Method
Header (flags and code size) Updated
Hooking code (IL) Inserted
Method body (IL)
5
Hooked Fat Method
Flags
Header size
Max. stack size
Code size Updated
Local var. signature
Hooking code (IL) Inserted
Method body (IL)
Extra data sections Updated
52
Hooked Assembly
.text section
Functions (IL)
Metadata References both
Import Address Table End of old
.text section
Hooked Functions (IL)
End of new
.text section
53
Next Steps
• More developers needed
• Insert needed functions into metadata tables
• Display contents of parameters
• Don’t break exception handling
54
More Information
• .NET Specifications:
– http://msdn.microsoft.com/net/ecma
• SSCLI and .NET Framework SDK
– http://msdn.microsoft.com/netframework/
• .NET Hook
– http://dotnethook.sourceforge.net
55
Acknowledgements
• Entercept’s Ricochet Team
– http://www.entercept.com
• w00w00
– http://www.w00w00.org
56