.NET Framework gives us a good development platform. Have a good class, you can cross language, cross-platform, and so on. But what is his internal implementation details? The EXE file compiled by .NET is not a machine code. How is it combined with CLR? Let us unveil this small secret.
First do a simple .NET application, compile it into an EXE file. Then open it with the tool depends with Visual Studio 6.0. As shown below:
Here you can see a very strange phenomenon, my .NET application only relies on a DLL-Mscoree.dll. And this DLL output is only available in the multi-function of _corexemain. I also used one of the .NET components you did in this appendline.exe, can't see here.
Let us analyze this EXE file with some PE view tools. What is the result of this step? A unique assembled statement can be seen on the entrance function of this PE file:
JMP DS: _COREXEMAIN
After the above steps, we can clearly determine all the .NET compiled EXE files once run, perform a function of Mscoree.dll output _COREXEMAIN. Some external components we use during the development process, the control is compiled into an intermediate code by the .NET compiler, which is not seen in Depends, all the procedures for using an external component are processed by the CLR.
Fortunately, Microsoft announced a CLI implementation code, we can see it. I didn't find _Corexemain in the code I downloaded, I only found a _corexemain2. There are 5 parameters:
PBYTE PUNMAPPEDPE, / / -> Memory Mapped Code
DWORD CUNMAPPE, / / SIZE OF MEMORY MAPPED CODE
LPWSTR PIMAGENAMEIN, / / -> EXECUTABLE NAME
LPWSTR PLOADERSFILENAME, / / -> Loaders Name
LPWSTR PCMDLINE
At a glance, punmapped and cunmappedpe are the memory buffer and length of the intermediate code after .NET compile. PimageNamein is the name of this EXE, ploadersFileName is the name of the loader, and PCMDLINE is the command parameter. With these parameters, we can guess that .NET compiles the middle code to the PE file, then add a code directly to execute the Mscoree.dll's _COREXEMAIN, the parameter is the memory pointer of the intermediate code. JIT compiles this intermediate code into machine code execution.
_COREXEMAIN2 code is not long, simple summary, did the following 5 steps:
1. Verify the signature.
2. Initialize the CLR environment
3. Created a PEFILE object on behalf of the exe file
4. Execute this Pefile using the static method of SystemDomain.
5. After execution, do some clear work and exit.
Obviously, the most important, the most important thing above is the fourth step, what did you do? Interested friends can go to the Microsoft's CLI code, and I will also further analyze in future articles.