Quantcast
Channel: Common Language Runtime Internals and Architecture forum
Viewing all articles
Browse latest Browse all 1710

Problem with IMetaDataEmit::Merge()

$
0
0

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





Viewing all articles
Browse latest Browse all 1710

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>