1
Microsoft's .NET Implementation
Matthew ConoverApril 2002
2
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
3
Topics of Discussion
• Introduction to .NET• Assemblies• Microsoft’s implementation of .NET• .NET Hook (dotNetHook) tool
4
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)
5
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
6
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
7
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
8
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
9
Common Language Runtime
BCL
Assembly
Class Loader
JIT
Machine Code
External Assembly
Execution Engine
10
Assemblies
• Single-file or multi-file assemblies• Components:
– Manifest– Metadata– MSIL (or native) code– Resources
11
Manifest
• Defines assembly• Strong name• Files in the assembly• Type references• Referenced assemblies
12
Metadata
• Contains all .NET data• Streams
– #Strings– #Blob– #GUID– #US– #- or #~
• Tables (stored in #- or #~)– In a predefined order– I.e., MethodDef, AssemblyRef, Constant
13
MetadataSignature, Version, Flags
Stream count Metadata Header
Data offset
Stream size
Name
Stream Header 1
Stream bodies
Stream Header 2…
…
14
#~ and #- StreamVersion
Heap sizes
Valid tables
Sorted tables
…
Tables Header
Table row count Valid Table 1
Valid Table 2
… Table bodies
15
MethodDef Table (0x06)
RVA
Implementation flags
Method flags
Method name Offset into #Strings
Signature
Parameters
Offset into #Blob
Index into Param table (0x08)
Offset to method
16
MethodDef Table (0x06)
Flags
Sequence number
Parameter name Offset into #Strings
Flags
Parameter count
Return type
Parameter types
Signature Blob
Param Table(0x08)
17
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
18
MSIL
ldc.i4.s 9
call Print(Int32)
ILAssembler
0x1f 0x09
0x28 0x06000006
Method token
Token
Table Number Row Index
Upper 8 bits Lower 24 bits
19
Call Stack
1
Stack top
this pointer
2
ldc.i4.1
ldc.i4.2
call ClassType::func(Int32, Int32)
Left-to-right ordering
ClassType a;
a.func(1, 2)
20
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
21
MSIL Samples (cont.)
• Brtrue <target>– Branch to target if value on stack is
true
• Dup– Duplicate a value on the stack
• Ldnull– Puts a null value on the stack
22
Microsoft’s .NET Implementation
• %SystemRoot%\Microsoft.NET• %SystemRoot%\Assembly +
– \GAC– \NativeImages*
23
System Libraries
• mscoree.dll (execution engine)• mscorjit.dll (contains JIT)• mscorsn.dll (strong name)• mscorlib.dll (BCL)• fushion.dll (assembly binding)
24
.NET Application
• Jumps to _CorExeMain (mscoree)• Calls _CorExeMain in mscorwks.dll• _CorExeMain calls CoInitializeEE• CoInitializeEE calls:
– EEStartup– ExecuteEXE
25
EEStartup
• GCHeap.Initialize– Managed heap = Doug Lea’s malloc?
• ECall.Init– SetupGenericPInvokeCalliStub– PInvokeCalliWorker
• NDirect.Init• UMThunkInit.UMThunkInit• COMDelegate.Init• ExecutionManger.Init• COMNlsInfo.InitializeNLS
26
EEStartup (cont.)
• Security::Start• SystemDomain.Init
– Loads BCL
• SystemDomain.NotifyProfilerStartup• SystemDomain.NotifyNewDomainLoads• SystemDomain.PublishAppDomainAndI
nformDebugger (ICorPublish/ICorDebug)
27
SystemDomain.Init
• LoadBaseSystemClasses• SystemDomain.CreatePreallocated
Exceptions
28
LoadBaseSystemClasses
• SystemDomain.LoadSystemAssembly– Loads mscorlib.dll
• Binder::StartupMscorlib• Binder::FetchClass(OBJECT)• MethodTable::InitForFinalization• InitJITHelpers2• Binder::FetchClass(VALUE)• Binder::FetchClass(ARRAY)
29
LoadBaseSystemClasses
• Binder.FetchType(OBJECT_ARRAY)• Binder.FetchClass(STRING)• Binder.FetchClass(ENUM)• Binder.FetchClass(ExceptionClass)• Binder.FetchClass(OutOfMemoryExcepti
onClass)• Binder.FetchClass(StackOverflowExcepti
onClass)
30
LoadBaseSystemClasses
• Binder.FetchClass(ExecutionEngineExceptionClass)
• Binder.FetchClass(DelegateClass)• Binder.FetchClass(MultiDelegateClass
)
31
.NET Application (review)
• Jumps to _CorExeMain (mscoree)• Calls _CorExeMain in mscorwks.dll• _CorExeMain calls CoInitializeEE• CoInitializeEE calls:
– EEStartup– ExecuteEXE
32
ExecuteEXE
• StrongNamesignatureVerification– In mscorsn.dll
• PEFile::Create– Loads executable
• ExecuteMainMethod• FushionBind.CreateFushionName• Assembly.ExecuteMainMethod
33
ExecuteMainMethod
• Thread.EnterRestrictiedContext• PEFile::GetMDImport• SystemDomain.SetDefaultDomainAt
tributes– Sets entry point
• SystemDomain.InitializeDefaultDomain
• BaseDomain.LoadAssembly
34
BaseDomain.LoadAssembly
• BaseDomain.ApplySharePolicy• AssemblySecurityDescriptor.Init• Module.Create• BaseDomain.SetAssemblyManifest
Module• AssemblySecurityDescriptor.AddDe
scriptorToDomainList
35
ExecuteEXE (review)
• StrongNamesignatureVerification– In mscorsn.dll
• PEFile::Create– Loads executable
• ExecuteMainMethod• FushionBind.CreateFushionName• Assembly.ExecuteMainMethod
36
Assembly.ExecuteMainMethod
• Assembly::GetEntryPoint• ClassLoader::ExecuteMainMethod
– EEClass:FindMethod(entry point token)
37
EEClass.FindMethod
• ValidateMainMethod• CorCommandLine.GetArgvW• MethodDesc.Call
– MethodDesc.IsRemotingIntercepted– MethodDesc.CallDescr calls
MethodDesc.CallDescrWorker– CallDescrWorker calls Main()
38
.NET Application
• Main() needs to be compiled• Main() calls PreStubWorker
(mscorwks)• PreStubWorker
– Compiles all IL methods– Calls MethodDesc.DoPrestub
39
MethodDesc.DoPrestub
• MethodDesc.GetSecurityFlags• MethodDesc.GetUnsafeAddrofCode• MethodDesc.GetILHeader• MethodDesc.GetRVA• COR_DECODE_METHOD
– Decode tiny/fat format
• Security._CanSkipVerification
40
MethodDesc.DoPrestub
• EEConfig.ShouldJitMethod• MakeJitWorker
– JITFunction– GetPrejittedCode
41
JITFunction
• ExecutionManager::GetJitForType– EEJitManager::LoadJIT– Loads mscorjit.dll (in LoadJIT)– Calls getJit in mscorjit (in LoadJIT)
• CallCompileMethodWithSEHWrapper– Debugger.JitBeginning– CILJit.compileMethod– Debugger.JitComplete
42
CILJit.compileMethod
• Calls jitNativeCode • jitNativeCode
– Compiler.compInit– Compiler.compCompile
43
Compiler.compCompile
• Compiler.eeGetMethodClass• Compiler.eeGetClassAttribs• emitter.emitBegCG• Compiler.eeGetMethodAttribs• Compiler.comptInitDebuggingInfo• Compiler.genGenerateCode• emitter.emitEndCG
44
Compiler.genGenerateCode
• emitter.emitBegFN• Compiler.genCodeForBBlist• Compiler.genFnProlog• Compiler.genFnEpilog• emitter.emitEndCodeGen• Compiler.gcInfoBlocKHdrSave• emitter.emitEndFN
45
.NET Application
• Show flowchart
46
.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
47
Method Definition (review)
RVA
Implementation flags
Method flags
Method name Offset into #Strings
Signature
Parameters
Offset into #Blob
Index into Param table (0x08)
Offset to method
48
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
49
Tiny Method
Header (flags and code size)
Method body (IL)
50
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
51
Hooked Tiny Method
Header (flags and code size)
Hooking code (IL)
Method body (IL)
Updated
Inserted
52
Hooked Fat Method
Flags
Header size
Max. stack size
Code size
Local var. signature
Method body (IL)
Extra data sections
Hooking code (IL) Inserted
Updated
Updated
53
Hooked Assembly
Metadata
Functions (IL)
Hooked Functions (IL)
Import Address Table End of old .text sectionEnd of
new .text section
.text section
References both
54
Next Steps
• More developers needed• Insert needed functions into
metadata tables• Display contents of parameters• Don’t break exception handling
55
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
56
Acknowledgements
• Entercept’s Ricochet Team– http://www.entercept.com
• w00w00– http://www.w00w00.org