Hi there! 👋
It’s a new day and new opportunity to learn something interesting about .NET and CLR :)
For those just joining this train, This is a continuation of my Deep-dive into CLR (i.e. .NET’s runtime) series. If you haven’t seen any of the past articles - I’d recommend you start from the beginning.
NOTE: This article is a bit longer and might get cut off by your email client. I suggest opening it either in Substack app or in your web browser.
Today I want to talk about something that is deemed to be boring. Well hell, I myself avoided reading about it because I thought it’s boring as crap. And to tell you the truth - I was, in fact, right. It is boring as crap. Metadata. Metadata tables. Anything that has “meta” in it is usually something that you deal with only if you’re forced to, right? :) Nobody likes meta (no pun intended).
To tell you the truth - I never really planned on writing this article. Seriously. Because I didn’t care about it and I’m sure you don’t care either. But something changed. And what changed is that, all of a sudden, it all clicked in my head. FUCK. Holy FUCK. That Metadata thing … That metadata thing is actually REALLY COOL! Like FUCKING AWESOME. It’s like Assembly itself WANTS you to inspect it. Look into it. Explore it! Plus, it tells you ALL about its behavior, its constraints, its memory requirements … you name it and there’s likely a metadata about it! It’s a GOLD MINE if you want to learn stuff about DLL or EXE in front of you!
Before we jump into the details, let’s start with Infographic first and then I’ll share more:
A’ight, I hope that was a bit more amusing than a dry thought of Metadata? :)
Now before we embark on the journey of this post, I really want to emphasize that ILDASM.exe (Intermediate Language Disassembler) is really a tool that you want to have handy. It’s surely lying somewhere in your .NET folder so just go and search for it (btw, I use a tool called “Everything” which is this blazing fast indexer that just rocks):
Next, I want to look into MSCorLib.dll, which, from my very modest search, seems to stand for Microsoft Common Object Runtime Library (there’s some history behind WHY is that, and the WHY seems to be that before it was named .NET, it was meant as improvement of COM). MSCorLib.dll is a core runtime library for .NET and what I want to do is see what it’s Manifest can tell me about it:
That’s quite a biggie right there :) And what I actually find amusing is that, in certain scenarios, your DLL’s metadata overhead could be way bigger than the actual code that it contains :) DLL’s and EXEs are really chatty!
So, in a nutshell, what are Metadata Tables? Well, just like with any meta data, their purpose is to DESCRIBE the Assembly (DLL or EXE; I guess I’m becoming boring by repeating this all the time?). And to tell you the truth, it’s not just meant for you, but it’s actually meant for CLR (Common Language Runtime - the runtime engine of .NET). It tells CLR which objects are inside, which are required to be imported, how much memory is needed, etc.
If you really stop and think about it - I guess there’s simply no other way to have an architecture-agnostic binaries without Metadata. Like, you either compile the binaries for specific architecture (e.g. Windows and x64) or you have some way of communicating HOW to go from “intermediate language” to a native CPU opcodes. And the latter is communicated by Metadata. I never checked it but I’d guess Java and it’s JVM works the same way.
So what I’m going to do now is paste some random excerpts of Metadata from the gigantic file I’ve shown you above. Then I’m going to discuss each of.
So what we see here are two TypeDefs, shorthand for Type Definition. As you could imagine, this means that these are these two types that exist inside this assembly - EmptyArray and FXAssembly.
Inside each of those TypeDefs, we see Fields and Methods, which I guess goes without saying that it represents the fields and methods inside those types.
“Flags” represent the info for JIT and CLR on how to interpret these Types and Methods. For example, “[Private]” flag above the “.cctor” method means that Constructor (.cctor is a shorthand for constructor) is Private.
There is a total of 2992 types defined inside this assembly and the last one is the one shown below:
Aside from TypeDefs, what we also see if we keep scrolling this gigantic piece of DLL, is the following:
Bunch of ModuleRefs (16 in total). As you could imagine, these are external assemblies that are needed in order for this assembly to function properly.
Then we have this:
Bunch of attributes about the assembly itself. Some of these you could actually override (e.g. Company Name, Version, etc.).
Then we have FIVE additional files that are inside this assembly:
If you remember the article on Assembly Manifest, I mentioned that you might have more than one file packed inside Assembly. In this case, there are five .nlp files which, to tell you the truth, I have no clue what they are :)
Finally, last one interesting to me was this one:
All the Strings that show up in your code will be stored under “User Strings” metadata table (btw, “L” stands for “Long” meaning that each character takes 2-bytes).
From my research, there appears to be around 40+ Metadata Tables, but sadly, the only resource where I could find this list was a “CLR via C#” book :/ I’m sure there’s a full list somewhere as part of CIL specification, but I haven’t found it yet. Once I do, I will update this article.
And there you have it :) I think knowing what your assembly holds is really valuable as you can do all kinds of cool stuff with it (e.g. analyze the dependency tree or ensure that code isn’t doing anything it’s not supposed to be doing).
This also marks the end of me talking about assemblies only (so far I dedicated past three articles on it; you can find them below). Next article will shift focus towards memory management, Stacks and Heaps and differences between Managed and Unmanaged languages.
Until then, if you haven’t already, I’d appreciate if you subscribe. I tend to publish these deep-dives at least twice a week and I make sure they are fun to read:
You may also help this article reach wider audience by sharing it with your network (which I’d also appreciate!):
Thanks for reading and see you next time!
Other articles from the CLR series: