shuai 的个人资料娱乐精神照片日志 工具 帮助
2007/11/29

强暴.Net程序集 之十 (FieldDef 和 MethodDef 表结构)

 

警告:本系列文章为本人原创,只作技术研究之用,您可以引用链接传播,禁止其它的转载方式,禁止用于商业或非法目的, 对于造成的一切后果本人概不负责

FieldDef非常的简单, Partition II Metadata中描述为:

22.15    Field : 0x04
The Field table has the following columns:
•    Flags (a 2-byte bitmask of type FieldAttributes, §23.1.5)
•    Name (an index into the String heap)
•    Signature (an index into the Blob heap)

其中Flags 字段是一个位掩码, 描述了字段的属性
corhdl.h中有它的定义
typedef enum CorFieldAttr
{
    // member access mask - Use this mask to retrieve accessibility information.
    fdFieldAccessMask           =   0x0007,
    fdPrivateScope              =   0x0000,     // Member not referenceable.
    fdPrivate                   =   0x0001,     // Accessible only by the parent type.
    fdFamANDAssem               =   0x0002,     // Accessible by sub-types only in this Assembly.
    fdAssembly                  =   0x0003,     // Accessibly by anyone in the Assembly.
    fdFamily                    =   0x0004,     // Accessible only by type and sub-types.
    fdFamORAssem                =   0x0005,     // Accessibly by sub-types anywhere, plus anyone in assembly.
    fdPublic                    =   0x0006,     // Accessibly by anyone who has visibility to this scope.
    // end member access mask

    // field contract attributes.
    fdStatic                    =   0x0010,     // Defined on type, else per instance.
    fdInitOnly                  =   0x0020,     // Field may only be initialized, not written to after init.
    fdLiteral                   =   0x0040,     // Value is compile time constant.
    fdNotSerialized             =   0x0080,     // Field does not have to be serialized when type is remoted.

    fdSpecialName               =   0x0200,     // field is special.  Name describes how.

    // interop attributes
    fdPinvokeImpl               =   0x2000,     // Implementation is forwarded through pinvoke.

    // Reserved flags for runtime use only.
    fdReservedMask              =   0x9500,
    fdRTSpecialName             =   0x0400,     // Runtime(metadata internal APIs) should check name encoding.
    fdHasFieldMarshal           =   0x1000,     // Field has marshalling information.
    fdHasDefault                =   0x8000,     // Field has default.
    fdHasFieldRVA               =   0x0100,     // Field has RVA.
} CorFieldAttr;

可以通过如下程序得到所有Field的属性, t为FieldDef表

for(DWORD i = 0; i < t.Rows; ++i)
{
    row = t.Address + t.RowSize * index;

    // Flags
    flags = *((USHORT *)row);
    row += 2;

    // Name
    if(t.HeapSizes & 0x01)
    {
        name = *((ULONG *)row);
        row += 4;
    }
    else
    {
        name = *((USHORT *)row);
        row += 2;
    }

    // Signature
    if(t.HeapSizes & 0x04)
    {
        signature = *((ULONG *)row);
        row += 4;
    }
    else
    {
        signature = *((USHORT *)row);
        row += 2;
    }
}

MethodDef 表在Partition II Metadata中描述为:
22.26    MethodDef : 0x06
The MethodDef table has the following columns:
•    RVA (a 4-byte constant)
•    ImplFlags (a 2-byte bitmask of type MethodImplAttributes, §23.1.10)
•    Flags (a 2-byte bitmask of type MethodAttributes, §23.1.10)
•    Name (an index into the String heap)
•    Signature (an index into the Blob heap)
•    ParamList (an index into the Param table).  It marks the first of a contiguous run of Parameters owned by this method.  The run continues to the smaller of:
o    the last row of the Param table
o    the next run of Parameters, found by inspecting the ParamList of the next row in the MethodDef  table

对了, 别忘了Property(属性实际上就是get_和set_方法)
其中Flags标记保存Method的一些可访问性及其它属性
corhdr.h 中有它的定义
typedef enum CorMethodAttr
{
    // member access mask - Use this mask to retrieve accessibility information.
    mdMemberAccessMask          =   0x0007,
    mdPrivateScope              =   0x0000,     // Member not referenceable.
    mdPrivate                   =   0x0001,     // Accessible only by the parent type.
    mdFamANDAssem               =   0x0002,     // Accessible by sub-types only in this Assembly.
    mdAssem                     =   0x0003,     // Accessibly by anyone in the Assembly.
    mdFamily                    =   0x0004,     // Accessible only by type and sub-types.
    mdFamORAssem                =   0x0005,     // Accessibly by sub-types anywhere, plus anyone in assembly.
    mdPublic                    =   0x0006,     // Accessibly by anyone who has visibility to this scope.
    // end member access mask

    // method contract attributes.
    mdStatic                    =   0x0010,     // Defined on type, else per instance.
    mdFinal                     =   0x0020,     // Method may not be overridden.
    mdVirtual                   =   0x0040,     // Method virtual.
    mdHideBySig                 =   0x0080,     // Method hides by name+sig, else just by name.

    // vtable layout mask - Use this mask to retrieve vtable attributes.
    mdVtableLayoutMask          =   0x0100,
    mdReuseSlot                 =   0x0000,     // The default.
    mdNewSlot                   =   0x0100,     // Method always gets a new slot in the vtable.
    // end vtable layout mask

    // method implementation attributes.
    mdCheckAccessOnOverride     =   0x0200,     // Overridability is the same as the visibility.
    mdAbstract                  =   0x0400,     // Method does not provide an implementation.
    mdSpecialName               =   0x0800,     // Method is special.  Name describes how.

    // interop attributes
    mdPinvokeImpl               =   0x2000,     // Implementation is forwarded through pinvoke.
    mdUnmanagedExport           =   0x0008,     // Managed method exported via thunk to unmanaged code.

    // Reserved flags for runtime use only.
    mdReservedMask              =   0xd000,
    mdRTSpecialName             =   0x1000,     // Runtime should check name encoding.
    mdHasSecurity               =   0x4000,     // Method has security associate with it.
    mdRequireSecObject          =   0x8000,     // Method calls another method containing security code.

} CorMethodAttr;

值得说明的是ParamList字段
它记录了Param表的记录索引,  指明所属方法的参数的开始位置, 结束于下一个方法参数的开始
程序如下, t为MethodDef表
for(DWORD i = 0; i < t.Rows; ++i)
{
    row = t.Address + t.RowSize * index;

    // RVA
    rva = *((DWORD *)row);
    row += 4;

    // ImplFlags
    implFlags = *((USHORT *)row);
    row += 2;

    // Flags
    flags = *((USHORT *)row);
    row += 2;

    // Name
    if(t.HeapSizes & 0x01)
    {
        nameIndex = *((ULONG *)row);
        row += 4;
        wcscpy(lBuffer, pView->StringTableEntry(nameIndex).c_str());
    }
    else
    {
        nameIndex = *((USHORT *)row);
        row += 2;
        wcscpy(lBuffer, pView->StringTableEntry(nameIndex).c_str());
    }


    // Signature
    if(t.HeapSizes & 0x04)
    {
        signature = *((DWORD *)row);
        row += 4;
    }
    else
    {
        signature = *((USHORT *)row);
        row += 2;
    }

    // ParamList
    if(t.IndexSizes & 0x10)
    {
        params = *((DWORD *)row);

        if(index < t.Rows - 1)
            endparams = *((DWORD *)(row + t.RowSize));
        else
            endparams = 0;
        row += 4;
    }
    else
    {
        params = *((USHORT *)row);

        if(index < t.Rows - 1)
            endparams = *((USHORT *)(row + t.RowSize));
        else
            endparams = 0;
        row += 2;
    }
}

评论

请稍候...
很抱歉,您输入的评论太长。请缩短您的评论。
您没有输入任何内容,请重试。
很抱歉,我们当前无法添加您的评论。请稍后重试。
若要添加评论,需要您的家长授予您相应权限。请求权限
您的家长禁用了评论功能。
很抱歉,我们当前无法删除您的评论。请稍后重试。
您已超过了一天之内允许提供的评论数上限。请在 24 小时后重试。
因为我们的系统表明您可能在向其他用户提供垃圾评论,您的帐户已禁用了评论功能。如果您认为我们错误地禁用了您的帐户,请联系 Windows Live 支持部门
完成下面的安全检查,您提供评论的过程才能完成。
您在安全检查中键入的字符必须与图片或音频中的字符一致。

若要添加评论,请使用您的 Windows Live ID 登录(如果您使用过 Hotmail、Messenger 或 Xbox LIVE,您就拥有 Windows Live ID)。登录


还没有 Windows Live ID 吗?请注册

引用通告

此日志的引用通告 URL 是:
http://iauhsgnay.spaces.live.com/blog/cns!C7C5DB6D46321CDD!437.trak
引用此项的网络日志