none
Define TypeSpec from TypeRef for .Net IL RRS feed

  • Question

  • I have built custom IL Rewriter that inject custom code into some methods. Part of this injection, I want to instantiate the object of List<int>. I already found the mdTokenRef for List~1.

    From this mdTokenRef, how do I define or obtain TypeSpec? I could define the TypeSpecBlog as shown below for that. But, looking for an ICorProfiler API to find the TypeSpec.

    COR_SIGNATURE sigListInt[] = { ELEMENT_TYPE_GENERICINST, ELEMENT_TYPE_CLASS, tdList, 0x01, ELEMENT_TYPE_I1 };
    


    Hitesh

    Tuesday, December 19, 2017 5:41 PM

Answers

All replies

  • You probably need to use IMetaDataEmit::GetTokenFromTypeSpec to create the TypeSpec token. You can request the IMetaDataEmit using ICorProfilerInfo::GetModuleMetaData, but you will need to make such metadata changes from the ICorProfilerCallback::ModuleLoadFinished callback.

    https://blogs.msdn.microsoft.com/davbr/2007/03/06/creating-an-il-rewriting-profiler/

    By the way, metadata tokens are encoded in signatures using a variable width, so using tdList directly in the signature probably isn't going to work.

    Tuesday, December 19, 2017 11:42 PM
  • Hi Hitesh Kesharia,

    Thank you for posting here.

    For your question, what does the TypeSpaceBlog mean?

    The code your used below, COR_SIGNATURE is defined by yourself. 

    COR_SIGNATURE sigListInt[] = { ELEMENT_TYPE_GENERICINST, ELEMENT_TYPE_CLASS, tdList, 0x01, ELEMENT_TYPE_I1 };
    // ELEMENT_TYPE_GENERICINST    = 0x15, 
    // ELEMENT_TYPE_CLASS	=0x12,.
    // ELEMENT_TYPE_I1             = 0x4,

    Based on my search, I find how to get TypeDef from TypeSpec. I will do more research.

    Here are the articles about IL Rewriting for your reference.

    https://www.codeproject.com/Articles/12585/The-NET-File-Format#Methods

    https://www.codeproject.com/Articles/453065/ILRewriting-for-beginners

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Wednesday, December 20, 2017 6:02 AM
    Moderator
  • Thanks Brian & Wendy for the response.

    I am able to obtain the TypeSpec. But using it, I am not able to find the method. All I am trying is to create a new object of List<byte>. To do so,

    • I need to first find the token for List~1.
    • Obtain the TypeSpec 
    • Find the .ctor for the given TypeSpec

    But, I am not able to find the token for .ctor. 

    Here my sample code. 

    // Find List~1 Token mdTypeRef trList; IfFailRet(pImport->FindTypeDefByName(L"System.Collections.Generic.List`1", mdTypeDefNil, &trList)); // Find List<byte> TypeSpec // First generate a sig //COR_SIGNATURE sigListByte[] = { ELEMENT_TYPE_GENERICINST, ELEMENT_TYPE_CLASS, trList, 0x01, ELEMENT_TYPE_U1 }; // Since we need to compress token, above sig won't work. COR_SIGNATURE* sigListByte = new COR_SIGNATURE[16]; COR_SIGNATURE* startSigListByte = sigListByte; int i = 0; startSigListByte[i++] = ELEMENT_TYPE_GENERICINST; startSigListByte[i++] = ELEMENT_TYPE_CLASS; sigListByte += i; ULONG sigLen = CorSigCompressToken(trList, sigListByte); i += sigLen; startSigListByte[i++] = 0x01; startSigListByte[i++] = ELEMENT_TYPE_U1; // Get TypeSpec mdTypeSpec tsListByte; IfFailRet(pEmit->GetTokenFromTypeSpec(sigListByte, i, &tsListByte)); // Find List<byte> construcotr token COR_SIGNATURE sigListCtor[] = { IMAGE_CEE_CS_CALLCONV_HASTHIS, 0, ELEMENT_TYPE_VOID }; mdMethodDef mdListConstructor = NULL;

    HRESULT hr = pImport->FindMemberRef(tsListByte, L".ctor", sigListCtor, sizeof(sigListCtor), &mdListConstructor);

    I tried with FindMethod and FindMemberRef, but no luck in any of them. Any suggestion what's wrong with this code? How do I find method token for the constructor?


    Hitesh

    Wednesday, December 20, 2017 5:48 PM
  • Hi Hitesh Kesharia,

    Thank you for feedback.

    Do you want to use it in C#? Or C++?

    Based on my search, I do not find the article about this method directly.

    For C++, you would like to check the following link.

    https://gist.github.com/eruffaldi/05b69afefee58634f180

    To further help you about this issue, I am trying to discuss with someone experienced to help look into this thread, this may take some time and as soon as we get any result, we will post back.

    Best Regards,

    Wendy


    MSDN Community Support
    Please remember to click "Mark as Answer" the responses that resolved your issue, and to click "Unmark as Answer" if not. This can be beneficial to other community members reading this thread. If you have any compliments or complaints to MSDN Support, feel free to contact MSDNFSF@microsoft.com.

    Tuesday, December 26, 2017 8:41 AM
    Moderator
  • You don't need the TypeSpec to access the method, instead use the open generic type to find the method you want then create a MethodSpec with that MethodDef or MemberRef and providing the type arguments for both the type and method (though constructors don't have type arguments of their own so you only need to provide them for the type itself).

    IMetaDataEmit2::DefineMethodSpec

    The format of the signature passed into DefineMethodSpec is described in ECMA-335 Partition II section 23.2.15.



    Thursday, December 28, 2017 2:03 AM
  • Yes, Brain. If method reference is not already defined, we need to first define it as shown below - 

    HRESULT hr = pImport->FindMemberRef(*typeDef, memberName, sig, sizeof(sig), mdMember);
    if (hr == 0x80131130 || *mdMember == 167772160)
    {
       hr = pEmit->DefineMemberRef(*typeDef, memberName, sig, sizeof(sig), mdMember);
    }
    

    Thanks.


    Hitesh

    Tuesday, January 2, 2018 4:50 AM