all groups > dotnet clr > february 2008 >
You're in the

dotnet clr

group:

assembly loading


assembly loading RedLars
2/26/2008 1:59:28 PM
dotnet clr:
Does mscoree.dll use MajorRuntimeVersion and MinorRuntimeVersion
variables of the struct IMAGE_COR20_HEADER to determine which CLR
Version to use for a particular .NET assembly given no app.config is
present?

How does the CLR know the difference between .NET 1.0 and 1.1 when
both are assigned the values 2 and 0 for major and minor runtime
Re: assembly loading Jeroen Mostert
2/27/2008 12:00:00 AM
[quoted text, click to view]
Yes:

1. When it comes to books on a particular tool or technology, only read the
latest books on the latest versions, and toss everything else in the fire
when newer books come out. Nothing's as deadly as out-of-date wisdom. Point
in case: the book you're referring to was written when .NET 1.1 was still
new and hot, and .NET 2.0 actually changed the rules for how these fields
are used.

2. A technical book that has nothing more to say about a field called
"runtime version" than that it's the version of the runtime somehow is
wasting its audience's time. The authors can be excused for not knowing the
full details of every field in an assembly (heaven knows *I* don't know
them) but they should never stick to dangerously misleading assumptions out
of a desire to be complete. Readers can make educated guesses for
themselves; the reason they're reading a book is because they're not
interested in guesses.

3. The only sources that should be considered reliable are first-hand
sources. Other sources can be as valuable and reliable (or even more so) but
not automatically. The book I cited was written by Serge Lidin, who's not
just anybody: he's the Microsoft employee responsible for the design of MSIL
and the IL (dis)assembly tools. Though he's not the one responsible for the
assembly format, we can be pretty sure that his information on assembly data
is more reliable than that of most other sources.

To put it more bluntly: not everything that's written down is accurate,
sincere though the authors may be. Check author credentials and reader
reviews carefully, especially when you're talking about in-depth subjects
like these.

[quoted text, click to view]

I don't know, so the following is speculation. The metadata format is
versioned independently of the assembly format and runtime version to better
guarantee interoperability between the various components that process
assembly metadata -- the CLR runtime, the OS loaders and assembly
compilers/decompilers. These are all maintained separately, so no single one
of them has been made responsible for the metadata format, nor do they
necessarily share the same implementation. All they have to agree on is the
format, and that's what the version is used to verify.

The current format version is 1.1. It stands to reason that there was once a
version 1.0, but I don't know whether it was ever used "in the wild" and
whether the current runtimes still support it. Only when a
backwards-incompatible change to the metadata format is made would it have
to be updated (say, for example, that the metadata is extended with new
security fields that have to be understood by loaders to meaningfully
process the assembly).

The resulting assembly probably couldn't be loaded by *any* tool written
before the change (because they're presumably written to reject newer
versions as unsupported), so such a change would be rare.

--
Re: assembly loading Jeroen Mostert
2/27/2008 12:08:29 AM
[quoted text, click to view]
No. That would be too easy.

[quoted text, click to view]

You'd think they would have learned from the many, many fields in the PE
header that are supposed to indicate the required/desired/targeted Windows
version (but don't) to get it right in the CLR, but history has a tendency
of repeating itself.

MajorRuntimeVersion and MinorRuntimeVersion are 2 and 0 for .NET 1.0/1.1 and
2 and 5 for .NET 2.0 (sounds workable, if not logical). However, these
fields are not actually used for determining what version of the CLR to
load; in fact, the "5" for MinorRuntimeVersion is actually used to identify
the assembly as 64-bit aware, which 2.0 assemblies are and 1.0/1.1
assemblies can be forced to be (see
http://blogs.msdn.com/joshwil/archive/2004/10/15/243019.aspx).

What version of the CLR to load (and remember, there can be only one
instance of the CLR in every process) is wholly determined by the unmanaged
code that loads the runtime. This is the startup code in the exe itself for
pre-XP Windows, and the OS loader (which is .NET aware) for XP and beyond.
When using a custom host, it can actually specify which version of the
runtime to load (or just "the latest available").

But how does the unmanaged code know which version to load, given the
startup assembly? From the assembly's metadata. This data starts with the
magic constant BSJB and contains further fields as detailed here:
http://books.google.com/books?id=oAcCRKd6EZgC&pg=PA76&source=gbs_search_s&sig=KIROXrhuy0dM1SVchOqmZlIw6go

The metadata header *also* contains version fields, which *also* don't have
anything do to with the CLR version (it's actually the metadata format
version), but right after that is the version string, and that's the string
you're after. For most 2.0 assemblies, this will be "v2.0.50727", which is
exactly the string you'd pass to CorBindToRuntime[Ex] to load the
appropriate version of the CLR.

--
Re: assembly loading RedLars
2/27/2008 12:47:51 AM
[quoted text, click to view]

Thought so.

[quoted text, click to view]

It sounds reasonable. I then read a chapter from the book ".NET
Framework" (O'Reilly) where they state "runtime version - Indicates
the runtime version that is required ro run this program" (1). Have
also seen it explained as "minimum required version of the runtime" or
word to that effect (cannot find the url atm). So part of the problem
for me is a lack of good documentation on the matter. Do you have any
thoughts?

1. http://books.google.com/books?id=Kid1EZUc9psC&pg=PA19&vq=CLR+Header&hl=no&source=gbs_search_r&cad=1_1&sig=V18znUG8iiCnfMliqqswonH703s


[quoted text, click to view]

Using dumpbin /all assembluname.dll I managed to view an .NET
assembly. I guess this is the interesting part;

10032560: 42 53 4A 42 01 00 01 00 00 00 00 00 0C 00 00 00
BSJB............
10032570: 76 31 2E 30 2E 33 37 30 35 00 00 00 00 00 04 00
v1.0.3705.......

There seem to be quite a few different versions in an .NET assembly.

CLR Header major \ minor runtime version // 64 or 32 bit - either 2.0
or 2.5
Metadata Header major \ minor version // always 1 and 1? whats it
used for?
Metadata pVersion // .NET used to
build assembly and therefore the version require to run it.

Re: assembly loading RedLars
2/28/2008 5:12:29 AM
[quoted text, click to view]

Thank you very much.

AddThis Social Bookmark Button