How CRT dependency is added to manifest file.

Well, the dependency information is added to manifest file by a tool known as mt.exe. But this information is provided to mt.exe by linker. And linker gets this information from linker directives.

Now these linker directives are present in two places.

1) Headers: To be precise Crtdefs.h contains these linker directives

#ifdef _M_IX86

#ifdef _DEBUG

#pragma comment(linker,"/manifestdependency:\"type='win32' " \

        "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".DebugCRT' " \

        "version='" _CRT_ASSEMBLY_VERSION "' " \

        "processorArchitecture='x86' " \

        "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")

#else

#pragma comment(linker,"/manifestdependency:\"type='win32' " \

        "name='" __LIBRARIES_ASSEMBLY_NAME_PREFIX ".CRT' " \

        "version='" _CRT_ASSEMBLY_VERSION "' " \

        "processorArchitecture='x86' " \

        "publicKeyToken='" _VC_ASSEMBLY_PUBLICKEYTOKEN "'\"")

#endif

#endif

We do not directly include this header but it gets included indirectly in our source through other crt headers.

2) The other place where these linker directives are present is msvcrt.lib file. If we do a dumpbin on msvcrt.lib we will be able to see those directives in the lib file, as shown below in wcrtexe/crtexe/wcrtdll/crtdll.obj sections of msvcrt.lib file.

 

Archive member name at 123CC0: /28237 f:\dd\vctools\crt_bld\SELF_X86\crt\src\build\INTEL\dll_obj\crtexe.obj

RAW DATA #1

  00000000: 20 20 20 2F 6D 61 6E 69 66 65 73 74 64 65 70 65 /manifestdepe

  00000010: 6E 64 65 6E 63 79 3A 22 74 79 70 65 3D 27 77 69 ndency:"type='wi

  00000020: 6E 33 32 27 20 6E 61 6D 65 3D 27 4D 69 63 72 6F n32' name='Micro

  00000030: 73 6F 66 74 2E 56 43 39 30 2E 43 52 54 27 20 76 soft.VC90.CRT' v

  00000040: 65 72 73 69 6F 6E 3D 27 39 2E 30 2E 32 31 30 32 ersion='9.0.2102

  00000050: 32 2E 38 27 20 70 72 6F 63 65 73 73 6F 72 41 72 2.8' processorAr

  00000060: 63 68 69 74 65 63 74 75 72 65 3D 27 78 38 36 27 chitecture='x86'

  00000070: 20 70 75 62 6C 69 63 4B 65 79 54 6F 6B 65 6E 3D publicKeyToken=

  00000080: 27 31 66 63 38 62 33 62 39 61 31 65 31 38 65 33 '1fc8b3b9a1e18e3

  00000090: 62 27 22 20 b'"

 

   Linker Directives

   -----------------

   /manifestdependency:"type='win32'

   name='Microsoft.VC90.CRT'

   version='9.0.21022.8'

   processorArchitecture='x86'

   publicKeyToken='1fc8b3b9a1e18e3b'"

If we link to msvcrt.lib file, but we do not refer to any symbol present in any of these obj files (wcrtexe/crtexe/crtdll/wcrtdll). These directives would not be taken by linker as input. To understand exactly what happens we need some background on how .lib files are processed by linker.

A .lib file is nothing but a collection of obj files.

1) In case of static libraries the contents of these obj files is actual function code.

2) In case of import libraries the contents of these obj files is not code of actual function but data necessary to put into the import table of final exe (also linker directives as shown above).

When linker processes the lib file, it adds only the specific obj files (put of this collection) that are referred to by our application in final exe.

Now as shown above msvcrt.lib contains Crtexe.obj. It is the obj file that contains the linker directive to add crt dependency in manifest file. Interesting thing is that this particular obj file becomes a part of our exe, it is not a part of crt DLL. (Which means that msvcrt.lib is not a pure import library).

 Crtexe.obj consists of startup code that initializes C Runtime ( functions like mainCRTStartup) as well as it consists of our default entry point function(mainCRTStartup).

 

Thus two things to check if a corrupt manifest is getting generated are

1) Are we including correct headers and library files?

2) Am I linking to startup code provided by c runtime or am I providing my own startup routine.

 

- Manish Jawa.

Developer Support VC++ and C#