Professional Documents
Culture Documents
NET
Matthew Conover
May 2002
1
What is .NET?
• .NET = dumb name
• .NET is a framework
• .NET is OS and platform independent
• .NET is language-insensitive
• .NET specs are publicly available
2
Topics of Discussion
• Introduction to .NET
• Assemblies and Metadata
• Microsoft’s implementation of .NET
• .NET Hook Library (dotNetHookLibrary)
3
Introduction to .NET
• .NET Specifications
– Partition I – Architecture
– Partition II – Metadata
– Partition III – Common Intermediate Language
– 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)
– Hosts managed code
5
Introduction to .NET
Base Class Library
• Similar to Java’s System namespace.
• Used by all .NET applications
• Has classes for IO, threading, database,
text, graphics, console, sockets/web/mail,
security, cryptography, COM, run-time
type discovery/invocation, assembly
generation
6
Introduction to .NET
• Common Language Runtime (CLR)
– Common Type System (CTS)
– Execution Engine (EE)
7
Introduction to .NET
Common Language Runtime
• Common Type System
– Specifies certain types required to be hosted by
CLR
– Specifies rules for class, struct, enums,
interface, delegate, etc.
– Everything is actually an object
8
Introduction to .NET
Common Language Runtime
• Execution Engine
– Compiles Microsoft Intermediate Language
(MSIL) into native code
– Handles garbage collection
– Handles exceptions
– Enforces code access security (sandbox)
– Handles verification
• Managed v. Unmanaged
9
Introduction to .NET
Assembly
JIT
CLR
Machine Code
10
Assemblies
• .NET Library/Executable (PE file format)
• Single-file or multi-file assemblies
• Modular design
– Eliminates DLL problems
– Locations resolved at runtime
• Components:
– Metadata
– MSIL (or native) code
11
Assemblies
Physical Layout
MSDOS Header
Single-file Assembly
PE Header
PE Section Headers Includes .NET Header
Code section .text (includes Metadata)
Data section .rsrc or .data
Relocations section .reloc or .rdata
12
Assemblies
• .NET Executable (PE file format)
• Single-file or multi-file assemblies
• Modular design
• Components:
– Metadata
– MSIL (or native) code
13
Assemblies
Metadata
• Contains all .NET application data
• Very revealing!
– Needed for MSIL compilation
– Assembly can be converted to native format
• Streams or heaps (sections of related data)
14
Assemblies
Metadata
Signature, Version, Flags
Metadata Header
Stream count (n)
Data offset
Stream size Stream Header 1
Name (variable length)
… Stream Header n
15
Assemblies
Streams
• #Strings (a.k.a. strings heap)
– Array of strings
• #US (a.k.a. user strings heap)
– Array of strings used by application at runtime
• #GUID
– Array of GUIDs (16 bytes each)
• #Blob
– Contains compressed binary data
• #- or #~
– Contains tables of methods, fields, etc.
16
Assemblies
#~ and #- Stream
Version
Heap sizes Tables Header
Valid tables (n)
… Tables 1-n
17
Assemblies
Tables in #~/#- Stream
• In a predefined order
– MethodDef = table 6
– Param table = table 8
• Each table contains specific types
– MethodDef = method definitions
– TypeDef = type definitions
– AssemblyRef = assemblies references
• Tables interact with each other
• Tables interact with certain heaps
18
Assemblies
Sample - MethodDef Table
Relative Virtual Address (RVA) Offset to method
Implementation flags
Method flags
19
Assemblies
Sample - MethodDef Table
Param Table
Flags
Sequence number
Parameter count
Return type
Parameter types 20
Assemblies
Sample - func(int arg)
MethodDef Param
func arg
… #Strings …
“func”
“arg”
…
#Blob
func method signature
arg type signature
…
21
Assemblies
• .NET Executable (PE file format)
• Single-file or multi-file assemblies
• Components:
– Metadata
– MSIL (or native) code
22
Assemblies
MSIL
• Pseudo-assembly
– Converted into native code
– Object “aware” intermediate language
– Examples: nop, break, ret, call, callvirt, newobj,
newarr, add, mul, xor, arglist, sizeof, throw, catch, dup
• Supports up to 512 opcodes
– 0xFE = first byte of two byte opcodes
• All calls are stack-based
23
Assemblies
Call Stack
C# MSIL
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
24
Assemblies
• Sample IL
25
Assemblies
MSIL
ldc.i4.s 9 MSIL 0x1f 0x09
call Print(Int32) Assembler 0x28 0x06000006
Method token
26
Assemblies
Tokens
• A replacement for pointers
• References a row in a table
Token
Table Number Row Index
Upper 8 bits Lower 24 bits
27
Assemblies
MSIL Samples
• ld = load on stack, st = store from stack
• stloc
– Stores a value from the stack into local variable
• ldarg
– Puts an argument on the stack
• ldelem
– Puts the value of an element on the stack
28
Microsoft’s .NET
Implementation
• File locations
• System libraries
• .NET application flow
29
Microsoft’s .NET Implementation
File Locations
• Framework: %SystemRoot
%\Microsoft.NET
• Global Assembly Cache (GAC):
%SystemRoot%\Assembly +
– \GAC
– \NativeImages*
30
Microsoft’s .NET
Implementation
• File locations
• System libraries
• .NET application flow
31
Microsoft’s .NET Implementation
System Libraries
• mscoree.dll (execution engine)
• mscorwks.dll (does most initialization)
• mscorjit.dll (contains JIT)
• mscorlib.dll (BCL)
• fusion.dll (assembly binding)
32
Microsoft’s .NET Implementation
System Libraries
mscoree.dll
mscorwks.dll
33
Microsoft’s .NET
Implementation
• File locations
• System libraries
• .NET application flow
34
Microsoft’s .NET Implementation
.NET Application Flow
Application mscoree.dll
_CorExeMain
CoInitializeEE
35
Microsoft’s .NET Implementation
.NET Application Flow
• Jumps to _CorExeMain (mscoree)
• Calls _CorExeMain in mscorwks.dll
• _CorExeMain calls CoInitializeEE
• CoInitializeEE calls:
– EEStartup
– ExecuteEXE
36
EEStartup
• GCHeap.Initialize
• ECall.Init
– SetupGenericPInvokeCalliStub
– PInvokeCalliWorker
• NDirect.Init
• UMThunkInit.UMThunkInit
• COMDelegate.Init
• ExecutionManger.Init
• COMNlsInfo.InitializeNLS
37
EEStartup (cont.)
• Security::Start
• SystemDomain.Init
• SystemDomain.NotifyProfilerStartup (ICorProfiler)
• SystemDomain.NotifyNewDomainLoads
• SystemDomain.PublishAppDomainAndInformDebugger
(ICorPublish/ICorDebug)
38
SystemDomain.Init
• LoadBaseSystemClasses
• SystemDomain.CreatePreallocatedExceptions
39
LoadBaseSystemClasses
• SystemDomain.LoadSystemAssembly
– Loads mscorlib.dll
• Binder::StartupMscorlib
• Binder::FetchClass(OBJECT)
• MethodTable::InitForFinalization
• InitJITHelpers2
• Binder::FetchClass(VALUE)
• Binder::FetchClass(ARRAY)
40
LoadBaseSystemClasses
• Binder.FetchType(OBJECT_ARRAY)
• Binder.FetchClass(STRING)
• Binder.FetchClass(ENUM)
• Binder.FetchClass(ExceptionClass)
• Binder.FetchClass(OutOfMemoryExceptionClass)
• Binder.FetchClass(StackOverflowExceptionClass)
41
LoadBaseSystemClasses
• Binder.FetchClass(ExecutionEngineExceptionClass)
• Binder.FetchClass(DelegateClass)
• Binder.FetchClass(MultiDelegateClass)
42
.NET Application Flow
• Jumps to _CorExeMain (mscoree)
• Calls _CorExeMain in mscorwks.dll
• _CorExeMain calls CoInitializeEE
• CoInitializeEE calls:
– EEStartup
– ExecuteEXE
43
ExecuteEXE
• StrongNamesignatureVerification
– In mscorsn.dll
• PEFile::Create
– Loads executable
• ExecuteMainMethod
• FusionBind.CreateFusionName
• Assembly.ExecuteMainMethod
44
ExecuteMainMethod
• Thread.EnterRestrictiedContext
• PEFile::GetMDImport
• SystemDomain.SetDefaultDomainAttributes
– Sets entry point
• SystemDomain.InitializeDefaultDomain
• BaseDomain.LoadAssembly
45
ExecuteEXE
• StrongNamesignatureVerification
– In mscorsn.dll
• PEFile::Create
– Loads executable
• ExecuteMainMethod
• FusionBind.CreateFusionName
• Assembly.ExecuteMainMethod
46
Assembly.ExecuteMainMethod
• Assembly::GetEntryPoint
• ClassLoader::ExecuteMainMethod
– EEClass:FindMethod(entry point token)
47
EEClass.FindMethod
• ValidateMainMethod
• CorCommandLine.GetArgvW
• MethodDesc.Call
– MethodDesc.IsRemotingIntercepted
– MethodDesc.CallDescr calls
MethodDesc.CallDescrWorker
– CallDescrWorker calls Main()
48
.NET Application
• Main() needs to be compiled
• Main() calls PreStubWorker (mscorwks)
• PreStubWorker
– Compiles all MSIL methods
– Calls MethodDesc.DoPrestub
49
MethodDesc.DoPrestub
• MethodDesc.GetSecurityFlags
• MethodDesc.GetUnsafeAddrofCode
• MethodDesc.GetILHeader
• MethodDesc.GetRVA
• COR_DECODE_METHOD
– Decode tiny/fat format
• Security._CanSkipVerification
50
MethodDesc.DoPrestub (cont.)
• EEConfig.ShouldJitMethod
• MakeJitWorker
– JITFunction
51
JITFunction
• ExecutionManager::GetJitForType
– EEJitManager::LoadJIT
– Loads mscorjit.dll (in LoadJIT)
– Calls getJit in mscorjit (in LoadJIT)
• CallCompileMethodWithSEHWrapper
– Debugger.JitBeginning
– CILJit.compileMethod
– Debugger.JitComplete
52
CILJit.compileMethod
• Calls jitNativeCode
• jitNativeCode
– Compiler.compInit
– Compiler.compCompile
53
Compiler.compCompile
• Compiler.eeGetMethodClass
• Compiler.eeGetClassAttribs
• emitter.emitBegCG
• Compiler.eeGetMethodAttribs
• Compiler.comptInitDebuggingInfo
• Compiler.genGenerateCode
• emitter.emitEndCG
54
Compiler.genGenerateCode
• emitter.emitBegFN
• Compiler.genCodeForBBlist
• Compiler.genFnProlog
• Compiler.genFnEpilog
• emitter.emitEndCodeGen
• Compiler.gcInfoBlocKHdrSave
• emitter.emitEndFN
55
.NET Hook – What It Is
• An API for hooking .NET assemblies
• Includes a sample application that will
insert a NOP into all “interesting” methods
56
.NET Hook – What It Does
• Reads through method table
• Reads method
– Parses header, code, EH data
• Hooks interesting 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
57
.NET Hook - API
• Load(string AssemblyName)
• Hook(HookedFunction Function)
• Save()
58
.NET Hook - Hook
• Specifies a callback function
• Callback function receives a HookedFunction
59
.NET Hook - HookedFunction
• Name (I.e., “Main”)
• FullName (I.e., “void Class1::Main(string[] args”)
• DeclaringTypeName (I.e., “Class1”)
• ReturnType (I.e., “void”)
• Parameters[] (includes name and type)
• Header[] and HeaderSize
• Code[] and CodeSize
• EHData[] and EHSize
60
.NET Hook
Hooked Assembly
.text section
Functions
61
Assemblies
Hooked Method
MethodDef table entry
RVA Original method
Implementation flags Hooked method
Method flags
Signature offset
Parameters index
62
.NET Hook
Tiny Method Body
• Header size = 1 byte
• Used when:
– Code size < 64 bytes
– Maximum stack size is less than 8
– The method has no local variables
– No exceptions
Header (flags and code size)
64
.NET Hook
Fat Method
Header size = 12 bytes
Flags
Header size
Max. stack size
Code size
Local var. signature Describes local variables
Method body (MSIL)
Extra data sections Currently only used for exceptions
65
.NET Hook
Hooked Fat Method
Flags
Header size
Max. stack size
Code size Updated
Local var. signature
Hooking code (MSIL) Inserted
Method body (MSIL)
Extra data sections Updated
66
.NET Hook Demo
67
.NET Hook - Next Steps
• Better type handling
• Don’t break exception handling
• More developers needed
68
Summary
• .NET Framework is made up of BCL & CLR
• .NET applications stored in assemblies
• .NET Hook manipulates assemblies
• Assemblies contain Metadata & MSIL code
• Metadata contains streams
• The #~/#- stream contains tables
• Tables contain the important stuff
69
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
70
Acknowledgements
• Entercept’s Ricochet Team
– http://www.entercept.com/ricochet
• w00w00
– http://www.w00w00.org
71