none
Problem with IMetaDataEmit::Merge() RRS feed

  • Question

  • Hi,
    I am trying to instrument methods in mscorlib.dll and put method calls into my own proxy methods into them. Now, I know I cannot add AssemblyRefs from mscorlib.dll to my proxy.dll because mscorlib does not like that in SingleDomain mode.
    So, I want to merge all the content of proxy.dll (all typedefs, methods, methodbodies, ect) into mscorlib.dll. It is very similar to what has been discussed in http://social.msdn.microsoft.com/Forums/en-US/0338c6bf-81b5-44ff-8e43-8bdb9a44feb7/modify-systemexception-in-setilfunctionbody

    I tried IMetaDataEmit::Merge() to inject all metadata into mscorlib.dll (at ModuleLoadStarted/Finished profiler callback). However, I could not get it to work yet. Documentation is very sparse on that topic. My problem is that I get a AccessViolation when I call MergeEnd:

      clr.dll!CMiniMdRW::GetFilterTable(void)     Unknown
      clr.dll!NEWMERGER::Merge(enum MergeFlags,enum CorRefToDefCheck)     Unknown
      clr.dll!RegMeta::MergeEnd(void)     Unknown

    Here is the disassebly from the debugger:

    CMiniMdRW::GetFilterTable:
        000007FEE8A7FA5C  mov         qword ptr [rsp+8],rbx 
        000007FEE8A7FA61  push        rdi 
        000007FEE8A7FA62  sub         rsp,20h 
        000007FEE8A7FA66  xor         ebx,ebx 
        000007FEE8A7FA68  mov         rdi,rcx 
    --> 000007FEE8A7FA6B  cmp         qword ptr [rcx+18A0h],rbx 
        000007FEE8A7FA72  je          CMiniMdRW::GetFilterTable+0C5Eh (07FEE8A806BAh) 
        000007FEE8A7FA78  mov         rax,qword ptr [rdi+18A0h] 
        000007FEE8A7FA7F  mov         rbx,qword ptr [rsp+30h] 
        000007FEE8A7FA84  add         rsp,20h 
        000007FEE8A7FA88  pop         rdi 
        000007FEE8A7FA89  ret 
        000007FEE8A7FA8A  nop 
        000007FEE8A7FA8B  nop 

    rcx is 0. That means that the this-pointer is NULL, if I interpret it correctly.

    This is what I do in ModuleLoadFinished callback (simplified):

    // open scope and IMetaDataImport for proxy.dll which is loaded as raw file
    IMetaDataDispenserEx *pDisp;
    CoCreateInstance(CLSID_CorMetaDataDispenser, NULL, CLSCTX_INPROC_SERVER, IID_IMetaDataDispenserEx, (void **)&pDisp);
    IMetaDataImport   *pImport;
    pDisp->OpenScopeOnMemory(pFileInMemory, fileSize, ofRead, IID_IMetaDataImport, (LPUNKNOWN*)&pImport);
    
    // get IMetaDataEmit for mscorlib.dll
    IMetaDataEmit2 * pEmit2;
    corProfilerInfo->GetModuleMetaData(moduleId, ( DWORD)( ofWrite | ofRead), IID_IMetaDataEmit2, (IUnknown **) &pEmit2);
    
    // do the merge
    MyTokenMapper mapper; // dummy mapper which implements IMapToken
    MyErrorHandler handler; // implements IUnknown, not sure what this one is supposed to do
    emit->Merge(import, &mapper, &handler);
    emit->MergeEnd(); // here, the crash happens

    Can anyone tell me:
     1. Why does it crash? What can I do differently?
     2. I implemented IMapToken myself, but I do not get any callbacks to ::Map(). Isn't it supposed to give me a callback for each merge?
     3. Is it recommended to use ::Merge() at all? Or would it be more wise to use IMetaDataEmit::Define...() and do the merge one by one?

    Thanks!
    -Christoph




    Friday, July 12, 2013 7:03 AM

Answers

  • Merge does not work the way you would expect - it is tool for compilers and could move tokens of mscorlib.dll which you don't want.

    Using Define* methods is the right way to do it here.

    -Karel

    Tuesday, August 20, 2013 11:13 PM
    Moderator

All replies

  • Hi Christoph,

    I am trying to involve someone familiar with this topic to further look at this issue. There might be some time delay. Appreciate your patience.
     
    Thank you for your understanding and support.


    Min Zhu
    MSDN Community Support | Feedback to us
    Develop and promote your apps in Windows Store
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Monday, July 15, 2013 8:38 AM
    Moderator
  • Merge does not work the way you would expect - it is tool for compilers and could move tokens of mscorlib.dll which you don't want.

    Using Define* methods is the right way to do it here.

    -Karel

    Tuesday, August 20, 2013 11:13 PM
    Moderator
  • Alright, thanks for your answer!
    Wednesday, August 21, 2013 5:47 AM