In Windows XP and above, the OS loader knows natively what to do with .NET executable assemblies, and fires up an instance of the CLR. However, .NET also runs on Windows 98, ME, NT 4.0, and 2000. When you run a .NET assembly on the older operating systems, the CLR has to be loaded somehow. This is the job of the CLR loader stub; a section of native code within a .NET assembly.
Executing a PE file
Unlike the DOS stub I discussed in my previous post, PE executables don't have full access to the entire physical memory. Instead, they are loaded into virtual memory, split into pages, that the OS maps onto physical memory as required. In the header of each PE file is information telling the loader how to map each section of a PE file into a page, and what access permissions to apply to each page.
Within a normal PE file the executable code can execute jumps and calls to functions in other dlls, such as the Windows API. These dlls are loaded (imported) into the process' virtual memory address space as required by the OS loader. However, this loading into virtual memory causes several problems.
Firstly, you need some way of storing function calls to imported functions in a PE file that isn't a direct jmp <memory address>, as the memory address of the function is not known until the dll is loaded into memory.
Secondly, the memory address that the PE file itself is loaded is not known until load time. This means that internal function calls can't use a direct call either!
Within a PE file, there are two structures that solve these problems; the import table, and relocations.
Import Table
Each entry in the import table specifies the information for a single imported dll. Along with the ASCII name of the dll, the entry contains the RVA of two identical structures, the Import Address Table (IAT) and Import Lookup Table (ILT). The IAT and ILT each contain an entry for every function imported from the dll, in the form of a two-byte hint and an ASCII function name. The import table and IAT are referenced from the 2nd and 13th data directory entries respectively, at the top of the file.
Read more: Simple-talk