none
Recompiling pure C++/CLI assembly from disassembled IL RRS feed

  • Question

  • Hi all,

    I'm trying to disassemble a C++/CLI CLR assembly (compiled with /clr:pure, only managed classes). I can generate the IL file sucessfully with ildasm and recompile it with ilasm (I don't change anything in the IL code at the moment) but when I try to load the recompiled assemly I get an exception at DLL initialization. The error probably originates from the CRT init code but I'm not an expert on this.

    Any tips?

    Here's the exception stack I get from .net:

    Unhandled Exception: System.TypeInitializationException: The type initializer fo
    r '<Module>' threw an exception. ---> <CrtImplementationDetails>.ModuleLoadExcep
    tion: The C++ module failed to load during appdomain initialization.
     ---> System.ArgumentOutOfRangeException: Token c is not valid in the scope of m
    odule System.ModuleHandle.
    Parameter name: metadataToken
      at System.ModuleHandle.ResolveMethodHandle(Int32 methodToken, RuntimeTypeHand
    le[] typeInstantiationContext, RuntimeTypeHandle[] methodInstantiationContext)
      at <CrtImplementationDetails>.ThisModule.ResolveMethod<void const * __clrcall
    (void)>(IntPtr methodToken) in C:\Users\dobos\Documents\Visual Studio 2008\Proje
    cts\UDTTestCSharp\Test\bin\x64\Debug\UDTTest.il:line 2840
      at _initterm_m((fnptr)* pfbegin, (fnptr)* pfend) in C:\Users\dobos\Documents\
    Visual Studio 2008\Projects\UDTTestCSharp\Test\bin\x64\Debug\UDTTest.il:line 280
    8
      at <CrtImplementationDetails>.LanguageSupport.InitializePerAppDomain(Language
    Support* A_0) in C:\Users\dobos\Documents\Visual Studio 2008\Projects\UDTTestCSh
    arp\Test\bin\x64\Debug\UDTTest.il:line 1320
      at <CrtImplementationDetails>.LanguageSupport._Initialize(LanguageSupport* A_
    0) in C:\Users\dobos\Documents\Visual Studio 2008\Projects\UDTTestCSharp\Test\bi
    n\x64\Debug\UDTTest.il:line 1387
      at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* A_0
    ) in C:\Users\dobos\Documents\Visual Studio 2008\Projects\UDTTestCSharp\Test\bin
    \x64\Debug\UDTTest.il:line 1516
      --- End of inner exception stack trace ---
      at <CrtImplementationDetails>.ThrowModuleLoadException(String errorMessage, E
    xception innerException) in f:\dd\vctools\crt_bld\self_64_amd64\crt\src\minterna
    l.h:line 224
      at <CrtImplementationDetails>.ThrowModuleLoadException(String A_0, Exception
    A_1)
      at <CrtImplementationDetails>.LanguageSupport.Initialize(LanguageSupport* A_0
    ) in C:\Users\dobos\Documents\Visual Studio 2008\Projects\UDTTestCSharp\Test\bin
    \x64\Debug\UDTTest.il:line 1531
      at .cctor() in C:\Users\dobos\Documents\Visual Studio 2008\Projects\UDTTestCS
    harp\Test\bin\x64\Debug\UDTTest.il:line 1570
      --- End of inner exception stack trace ---
      at Test.Program.Main(String[] args)

    And this is what windbg says:

    Executable search path is: 
    ModLoad: 00000000`01290000 00000000`01296000  Test.exe
    ModLoad: 00000000`77350000 00000000`774fb000  ntdll.dll
    ModLoad: 000007fe`f9690000 000007fe`f96ff000  C:\Windows\SYSTEM32\MSCOREE.DLL
    ModLoad: 00000000`77130000 00000000`7724f000  C:\Windows\system32\KERNEL32.dll
    ModLoad: 000007fe`fd610000 000007fe`fd67b000  C:\Windows\system32\KERNELBASE.dll
    (1028.15a8): Break instruction exception - code 80000003 (first chance)
    ntdll!LdrpDoDebuggerBreak+0x30:
    00000000`77401220 cc       int   3
    0:000> g
    ModLoad: 000007fe`ff430000 000007fe`ff50b000  C:\Windows\system32\ADVAPI32.dll
    ModLoad: 000007fe`ff5c0000 000007fe`ff65f000  C:\Windows\system32\msvcrt.dll
    ModLoad: 000007fe`fefa0000 000007fe`fefbf000  C:\Windows\SYSTEM32\sechost.dll
    ModLoad: 000007fe`ff090000 000007fe`ff1be000  C:\Windows\system32\RPCRT4.dll
    ModLoad: 000007fe`f9600000 000007fe`f9690000  C:\Windows\Microsoft.NET\Framework64\v4.0.30319\mscoreei.dll
    ModLoad: 000007fe`fe9a0000 000007fe`fea11000  C:\Windows\system32\SHLWAPI.dll
    ModLoad: 000007fe`fee00000 000007fe`fee67000  C:\Windows\system32\GDI32.dll
    ModLoad: 00000000`77250000 00000000`7734a000  C:\Windows\system32\USER32.dll
    ModLoad: 000007fe`ff1c0000 000007fe`ff1ce000  C:\Windows\system32\LPK.dll
    ModLoad: 000007fe`fefc0000 000007fe`ff08a000  C:\Windows\system32\USP10.dll
    ModLoad: 000007fe`fd990000 000007fe`fd9be000  C:\Windows\system32\IMM32.DLL
    ModLoad: 000007fe`fee70000 000007fe`fef79000  C:\Windows\system32\MSCTF.dll
    ModLoad: 000007fe`f8c50000 000007fe`f95fe000  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorwks.dll
    ModLoad: 00000000`74fb0000 00000000`75079000  C:\Windows\WinSxS\amd64_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4927_none_88dce9872fb18caf\MSVCR80.dll
    ModLoad: 000007fe`fdb90000 000007fe`fe916000  C:\Windows\system32\shell32.dll
    ModLoad: 000007fe`fea20000 000007fe`fec21000  C:\Windows\system32\ole32.dll
    ModLoad: 000007fe`fd180000 000007fe`fd18f000  C:\Windows\system32\profapi.dll
    ModLoad: 000007fe`f7d20000 000007fe`f8bfb000  C:\Windows\assembly\NativeImages_v2.0.50727_64\mscorlib\9a017aa8d51322f18a40f414fa35872d\mscorlib.ni.dll
    ModLoad: 000007fe`fce80000 000007fe`fce8f000  C:\Windows\system32\CRYPTBASE.dll
    ModLoad: 000007fe`f5640000 000007fe`f57c4000  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\mscorjit.dll
    ModLoad: 00000000`65d50000 00000000`65d64000  UDTTest.dll
    ModLoad: 00000000`00840000 00000000`00854000  UDTTest.dll
    ModLoad: 00000000`65d50000 00000000`65d64000  C:\Users\dobos\Documents\Visual Studio 2008\Projects\UDTTestCSharp\Test\bin\x64\Debug\UDTTest.dll
    ModLoad: 00000005`16f00000 00000005`16fc6000  C:\Windows\Microsoft.NET\Framework64\v2.0.50727\diasymreader.dll
    ModLoad: 00000000`00970000 00000000`00984000  UDTTest.dll
    ModLoad: 00000000`62890000 00000000`629df000  C:\Windows\WinSxS\amd64_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_e29f88eb40dc93cd\MSVCR90D.dll
    ModLoad: 00000000`65ce0000 00000000`65d46000  C:\Windows\WinSxS\amd64_microsoft.vc90.debugcrt_1fc8b3b9a1e18e3b_9.0.30729.4148_none_e29f88eb40dc93cd\msvcm90d.dll
    ModLoad: 00000000`009a0000 00000000`00a06000  msvcm90d.dll
    ModLoad: 00000000`00b30000 00000000`00b96000  msvcm90d.dll
    ModLoad: 000007fe`fc880000 000007fe`fc897000  C:\Windows\system32\CRYPTSP.dll
    ModLoad: 000007fe`fc660000 000007fe`fc6a7000  C:\Windows\system32\rsaenh.dll
    ModLoad: 000007fe`f7110000 000007fe`f7b2e000  C:\Windows\assembly\NativeImages_v2.0.50727_64\System\247913fa7ae6fcf04ea33d28d24ab611\System.ni.dll
    (1028.15a8): CLR exception - code e0434f4d (first chance)
    (1028.15a8): CLR exception - code e0434f4d (first chance)
    (1028.15a8): CLR exception - code e0434f4d (first chance)
    (1028.15a8): C++ EH exception - code e06d7363 (first chance)
    (1028.15a8): CLR exception - code e0434f4d (first chance)
    (1028.15a8): CLR exception - code e0434f4d (first chance)
    (1028.15a8): C++ EH exception - code e06d7363 (first chance)
    (1028.15a8): CLR exception - code e0434f4d (first chance)
    (1028.15a8): C++ EH exception - code e06d7363 (first chance)
    (1028.15a8): CLR exception - code e0434f4d (first chance)
    (1028.15a8): CLR exception - code e0434f4d (!!! second chance !!!)
    KERNELBASE!RaiseException+0x39:
    000007fe`fd61aa7d 4881c4c8000000 add   rsp,0C8h
    

     

     

    Tuesday, July 13, 2010 7:22 PM

Answers

  • Ok, so I've found the solution on the mono site:

    http://www.mono-project.com/CPlusPlus

    The problem was indeed caused by the CRT libs that the compiler links with the assembly by default. Ignoring all default libs doesn't help in itself because it causes an unresolved external to the module initializer. Creating a fake entry point works:

    #pragma warning(disable:4483)
     
     void __clrcall __identifier(".cctor")()
     {
     }
    
    

    After this, the pure CLR assembly can be disassembled into IL and compiled back after changing the IL code.

    The reason I actually needed this because templated classes are not accessible from c# due to some reasons I don't know. (Well, they're named inconsistently with the CLR naming convention at least, as the classes will have names like 'matrix<double>'.) Anyway, disassembling the DLL into IL, renaming the templated classes to something simple and recompiling the IL into an assembly adds templates to CLR in a relatively easy way. I would give myself an A figuring this out in two days considering my not too firm C++ background :)

    • Marked as answer by SamAgain Wednesday, July 14, 2010 6:02 AM
    Tuesday, July 13, 2010 9:14 PM