Пример #1
0
ULONG _detectAndSkipVASentinel(PCCOR_SIGNATURE sig)
{
    ULONG cb = 0;
    ULONG elementType = ELEMENT_TYPE_MAX;

    cb += CorSigUncompressData(sig, &elementType);

    if (CorIsModifierElementType((CorElementType)elementType) &&
               (elementType == ELEMENT_TYPE_SENTINEL))
    {
        return cb;
    }
    else
    {
        return 0;
    }
}
Пример #2
0
HRESULT _CountBytesOfOneArg(
    PCCOR_SIGNATURE pbSig,
    ULONG       *pcbTotal)  // Initially, *pcbTotal contains the remaining size of the sig blob
{
    ULONG       cb;
    ULONG       cbTotal=0;
    ULONG       cbTotalMax;
    CorElementType ulElementType;
    ULONG       ulData;
    ULONG       ulTemp;
    int         iData;
    mdToken     tk;
    ULONG       cArg;
    ULONG       callingconv;
    ULONG       cArgsIndex;
    HRESULT     hr = NOERROR;

    if(pcbTotal==NULL) return E_FAIL;
    cbTotalMax = *pcbTotal;

    CHECK_REMAINDER;
    cbTotal = CorSigUncompressElementType(pbSig, &ulElementType);
    while (CorIsModifierElementType((CorElementType) ulElementType))
    {
        CHECK_REMAINDER;
        cbTotal += CorSigUncompressElementType(&pbSig[cbTotal], &ulElementType);
    }
    switch (ulElementType)
    {
        case ELEMENT_TYPE_SZARRAY:
        case 0x1e /* obsolete */:
            // skip over base type
            CHECK_REMAINDER;
            cb = cbTotalMax - cbTotal;
            IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) );
            cbTotal += cb;
            break;

        case ELEMENT_TYPE_FNPTR:
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData (&pbSig[cbTotal], &callingconv);

            // remember number of bytes to represent the arg counts
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData (&pbSig[cbTotal], &cArg);

            // how many bytes to represent the return type
            CHECK_REMAINDER;
            cb = cbTotalMax - cbTotal;
            IfFailGo( _CountBytesOfOneArg( &pbSig[cbTotal], &cb) );
            cbTotal += cb;

            // loop through argument
            for (cArgsIndex = 0; cArgsIndex < cArg; cArgsIndex++)
            {
                CHECK_REMAINDER;
                cb = cbTotalMax - cbTotal;
                IfFailGo( _CountBytesOfOneArg( &pbSig[cbTotal], &cb) );
                cbTotal += cb;
            }

            break;

        case ELEMENT_TYPE_ARRAY:
            // syntax : ARRAY BaseType <rank> [i size_1... size_i] [j lowerbound_1 ... lowerbound_j]

            // skip over base type
            CHECK_REMAINDER;
            cb = cbTotalMax - cbTotal;
            IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) );
            cbTotal += cb;

            // Parse for the rank
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData);

            // if rank == 0, we are done
            if (ulData == 0)
                break;

            // any size of dimension specified?
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData);
            while (ulData--)
            {
                CHECK_REMAINDER;
                cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulTemp);
            }

            // any lower bound specified?
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressData(&pbSig[cbTotal], &ulData);

            while (ulData--)
            {
                CHECK_REMAINDER;
                cbTotal += CorSigUncompressSignedInt(&pbSig[cbTotal], &iData);
            }

            break;
        case ELEMENT_TYPE_VALUETYPE:
        case ELEMENT_TYPE_CLASS:
        case ELEMENT_TYPE_CMOD_REQD:
        case ELEMENT_TYPE_CMOD_OPT:
            // count the bytes for the token compression
            CHECK_REMAINDER;
            cbTotal += CorSigUncompressToken(&pbSig[cbTotal], &tk);
            if ( ulElementType == ELEMENT_TYPE_CMOD_REQD ||
                 ulElementType == ELEMENT_TYPE_CMOD_OPT)
            {
                // skip over base type
                CHECK_REMAINDER;
                cb = cbTotalMax - cbTotal;
                IfFailGo( _CountBytesOfOneArg(&pbSig[cbTotal], &cb) );
                cbTotal += cb;
            }
            break;
        default:
            break;
    }

    *pcbTotal = cbTotal;
ErrExit:
    return hr;
}
Пример #3
0
//*****************************************************************************
// walk one type and mark tokens embedded in the signature
//*****************************************************************************
HRESULT FilterManager::MarkFieldSignature(
    PCCOR_SIGNATURE pbSig,              // [IN] point to the current byte to visit in the signature
    ULONG       cbSig,                  // [IN] count of bytes available.
    ULONG       *pcbUsed)               // [OUT] count of bytes consumed.
{
    HRESULT     hr = NOERROR;           // A result.
    ULONG       cb;                     // Bytes in one signature element.
    ULONG       cbUsed = 0;             // Total bytes consumed from signature.
    CorElementType ulElementType;       // ELEMENT_TYPE_xxx from signature.
    ULONG       ulData;                 // Some data (like a count) from the signature.
    ULONG       ulTemp;                 // Unused data.
    mdToken     token;                  // A token from the signature.
    int         iData;                  // Integer data from signature.

    VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) );

    // Skip the modifiers...
    while (CorIsModifierElementType((CorElementType) ulElementType))
    {
        VALIDATE_SIGNATURE_LEN( CorSigUncompressElementType(pbSig, &ulElementType) );
    }

    // Examine the signature element
    switch (ulElementType)
    {
        case ELEMENT_TYPE_SZARRAY:
            // syntax: SZARRAY <BaseType>

            // conver the base type for the SZARRAY or GENERICARRAY
            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );
            break;

        case ELEMENT_TYPE_CMOD_REQD:
        case ELEMENT_TYPE_CMOD_OPT:
            // syntax: {CMOD_REQD|CMOD_OPT} <token> <signature>

            // now get the embedded token
            VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) );

            // Mark the token
            IfFailGo( Mark(token) );

            // mark the base type
            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );
            break;

        case ELEMENT_TYPE_VAR:
        case ELEMENT_TYPE_MVAR:
            // syntax: VAR <index>
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );
            break;

        case ELEMENT_TYPE_ARRAY:
            // syntax: ARRAY BaseType <rank> [i size_1... size_i] [j lowerbound_1 ... lowerbound_j]

            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );

            // Parse for the rank
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // if rank == 0, we are done
            if (ulData == 0)
                break;

            // Any size of dimension specified?
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // Consume sizes of dimension.
            while (ulData--)
            {
                VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulTemp) );
            }

            // Any lower bounds specified?
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // Consume lower bounds.
            while (ulData--)
            {
                VALIDATE_SIGNATURE_LEN( CorSigUncompressSignedInt(pbSig, &iData) );
            }

            break;

        case ELEMENT_TYPE_FNPTR:
            // function pointer is followed by another complete signature
            VALIDATE_SIGNATURE_LEN_HR( MarkSignature(pbSig, cbSig - cbUsed, &cb) );
            break;

        case ELEMENT_TYPE_VALUETYPE:
        case ELEMENT_TYPE_CLASS:
            // syntax: {CLASS | VALUECLASS} <token>
            VALIDATE_SIGNATURE_LEN( CorSigUncompressToken(pbSig, &token) );

            // Mark it.
            IfFailGo( Mark(token) );
            break;

        case ELEMENT_TYPE_GENERICINST:
            // syntax:  ELEMENT_TYPE_GEENRICINST <ELEMENT_TYPE_CLASS | ELEMENT_TYPE_VALUECLASS> <token> <n> <n params>
            VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );

            // Get the number of generic parameters
            VALIDATE_SIGNATURE_LEN( CorSigUncompressData(pbSig, &ulData) );

            // Get the generic parameters
            while (ulData--)
            {
                VALIDATE_SIGNATURE_LEN_HR( MarkFieldSignature(pbSig, cbSig - cbUsed, &cb) );
            }
            break;

        default:
            // If valid element (I4, etc), great.  Otherwise, return error.
            if ((ulElementType >= ELEMENT_TYPE_MAX) || 
                (ulElementType == ELEMENT_TYPE_PTR) || 
                (ulElementType == ELEMENT_TYPE_BYREF) || 
                (ulElementType == ELEMENT_TYPE_VALUEARRAY_UNSUPPORTED))
            {
                IfFailGo(META_E_BAD_SIGNATURE);
            }
            break;
    }

ErrExit:
    *pcbUsed = cbUsed;
    return hr;
} // HRESULT FilterManager::MarkFieldSignature()