MSBuild源码中记录的PE结构相关的东西

来源:互联网 发布:数据库手机号码类型 编辑:程序博客网 时间:2024/05/16 18:03

MSBuild中记录的PE结构,C#的,可能有用贴出来,完整代码在github上

        #region NT header stuff        internal const uint IMAGE_NT_OPTIONAL_HDR32_MAGIC = 0x10b;        internal const uint IMAGE_NT_OPTIONAL_HDR64_MAGIC = 0x20b;        internal const uint IMAGE_DIRECTORY_ENTRY_COMHEADER = 14;        internal const uint COMIMAGE_FLAGS_STRONGNAMESIGNED = 0x08;        [StructLayout(LayoutKind.Sequential)]        internal struct IMAGE_FILE_HEADER        {            internal ushort Machine;            internal ushort NumberOfSections;            internal uint TimeDateStamp;            internal uint PointerToSymbolTable;            internal uint NumberOfSymbols;            internal ushort SizeOfOptionalHeader;            internal ushort Characteristics;        }        [StructLayout(LayoutKind.Sequential)]        internal struct IMAGE_DATA_DIRECTORY        {            internal uint VirtualAddress;            internal uint Size;        }        [StructLayout(LayoutKind.Sequential)]        internal struct IMAGE_OPTIONAL_HEADER32        {            internal ushort Magic;            internal byte MajorLinkerVersion;            internal byte MinorLinkerVersion;            internal uint SizeOfCode;            internal uint SizeOfInitializedData;            internal uint SizeOfUninitializedData;            internal uint AddressOfEntryPoint;            internal uint BaseOfCode;            internal uint BaseOfData;            internal uint ImageBase;            internal uint SectionAlignment;            internal uint FileAlignment;            internal ushort MajorOperatingSystemVersion;            internal ushort MinorOperatingSystemVersion;            internal ushort MajorImageVersion;            internal ushort MinorImageVersion;            internal ushort MajorSubsystemVersion;            internal ushort MinorSubsystemVersion;            internal uint Win32VersionValue;            internal uint SizeOfImage;            internal uint SizeOfHeaders;            internal uint CheckSum;            internal ushort Subsystem;            internal ushort DllCharacteristics;            internal uint SizeOfStackReserve;            internal uint SizeOfStackCommit;            internal uint SizeOfHeapReserve;            internal uint SizeOfHeapCommit;            internal uint LoaderFlags;            internal uint NumberOfRvaAndSizes;            // should be:            // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] internal IMAGE_DATA_DIRECTORY[] DataDirectory;            // but fixed size arrays only work with simple types, so I have to use ulongs and convert them to IMAGE_DATA_DIRECTORY structs            // Fortunately, IMAGE_DATA_DIRECTORY is only 8 bytes long... (whew)            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]            internal ulong[] DataDirectory;        }        [StructLayout(LayoutKind.Sequential)]        internal struct IMAGE_OPTIONAL_HEADER64        {            internal ushort Magic;            internal byte MajorLinkerVersion;            internal byte MinorLinkerVersion;            internal uint SizeOfCode;            internal uint SizeOfInitializedData;            internal uint SizeOfUninitializedData;            internal uint AddressOfEntryPoint;            internal uint BaseOfCode;            internal ulong ImageBase;            internal uint SectionAlignment;            internal uint FileAlignment;            internal ushort MajorOperatingSystemVersion;            internal ushort MinorOperatingSystemVersion;            internal ushort MajorImageVersion;            internal ushort MinorImageVersion;            internal ushort MajorSubsystemVersion;            internal ushort MinorSubsystemVersion;            internal uint Win32VersionValue;            internal uint SizeOfImage;            internal uint SizeOfHeaders;            internal uint CheckSum;            internal ushort Subsystem;            internal ushort DllCharacteristics;            internal ulong SizeOfStackReserve;            internal ulong SizeOfStackCommit;            internal ulong SizeOfHeapReserve;            internal ulong SizeOfHeapCommit;            internal uint LoaderFlags;            internal uint NumberOfRvaAndSizes;            // should be:            // [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)] internal IMAGE_DATA_DIRECTORY[] DataDirectory;            // but fixed size arrays only work with simple types, so I have to use ulongs and convert them to IMAGE_DATA_DIRECTORY structs            // Fortunately, IMAGE_DATA_DIRECTORY is only 8 bytes long... (whew)            [MarshalAs(UnmanagedType.ByValArray, SizeConst = 16)]            internal ulong[] DataDirectory;        }        [StructLayout(LayoutKind.Sequential)]        internal struct IMAGE_NT_HEADERS32        {            internal uint signature;            internal IMAGE_FILE_HEADER fileHeader;            internal IMAGE_OPTIONAL_HEADER32 optionalHeader;        }        [StructLayout(LayoutKind.Sequential)]        internal struct IMAGE_NT_HEADERS64        {            internal uint signature;            internal IMAGE_FILE_HEADER fileHeader;            internal IMAGE_OPTIONAL_HEADER64 optionalHeader;        }        [StructLayout(LayoutKind.Sequential)]        internal struct IMAGE_COR20_HEADER        {            internal uint cb;            internal ushort MajorRuntimeVersion;            internal ushort MinorRuntimeVersion;            internal IMAGE_DATA_DIRECTORY MetaData;            internal uint Flags;            internal uint EntryPointTokenOrEntryPointRVA;            internal IMAGE_DATA_DIRECTORY Resources;            internal IMAGE_DATA_DIRECTORY StrongNameSignature;            internal IMAGE_DATA_DIRECTORY CodeManagerTable;            internal IMAGE_DATA_DIRECTORY VTableFixups;            internal IMAGE_DATA_DIRECTORY ExportAddressTableJumps;            internal IMAGE_DATA_DIRECTORY ManagedNativeHeader;        }        [StructLayout(LayoutKind.Sequential)]        internal struct CRYPTOAPI_BLOB        {            internal uint cbData;            internal IntPtr pbData;        }        #endregion
读元数据的函数

        #region Methods        /// <summary>        /// Given a pointer to a metadata blob, read the string parameter from it.  Returns true if         /// a valid string was constructed and false otherwise.          ///         /// Adapted from bizapps\server\designers\models\packagemodel\nativemethods.cs (TryReadStringArgument) and         /// the original ARD implementation in vsproject\compsvcspkg\enumcomplus.cpp (GetStringCustomAttribute)        /// This code was taken from the vsproject\ReferenceManager\Providers\NativeMethods.cs        /// </summary>        [HandleProcessCorruptedStateExceptions]        internal static unsafe bool TryReadMetadataString(string fullPath, IntPtr attrData, uint attrDataSize, out string strValue)        {            IntPtr attrDataPostProlog = IntPtr.Zero;            int attrDataOffset = 0;            int strLen = 0;            int i = 0;            strValue = null;            try            {                // Blob structure for an attribute with a constructor receiving one string                // and no named parameters:                //                //     [2 bytes] Prolog: unsigned int16 with value 0x0001                //     [1, 2 or 4 bytes] PackedLen: Number of bytes of string parameter                //     [PackedLen bytes] String parameter encoded as UTF8                //     [1 byte] Name Parameter Count: Named parameter count equal to 0                // Minimum size is 4-bytes (Prolog + PackedLen).  Prolog must be 0x0001.                if ((attrDataSize >= 4) && (Marshal.ReadInt16(attrData, attrDataOffset) == 1))                {                    int preReadOffset = 2; // pass the prolog                    attrDataPostProlog = attrData + preReadOffset;                    // Get the offset at which the uncompressed data starts, and the                     // length of the uncompressed data.                    attrDataOffset = CorSigUncompressData(attrDataPostProlog, out strLen);                    if (strLen != -1)                    {                        // the full size of the blob we were passed in should be sufficient to                         // cover the prolog, compressed string length, and actual string.                        if (attrDataSize >= preReadOffset + attrDataOffset + strLen)                        {                            // Read in the uncompressed data                            byte[] bytes = new byte[(int)strLen];                            for (i = 0; i < strLen; i++)                            {                                bytes[i] = Marshal.ReadByte(attrDataPostProlog, attrDataOffset + i);                            }                            // And convert it to the output string.                             strValue = new String(Encoding.UTF8.GetChars(bytes));                        }                        else                        {                            return false;                        }                    }                }                else                {                    return false;                }            }            catch (AccessViolationException)            {                // The Marshal.ReadXXXX functions throw AVs when they're fed an invalid pointer, and very occasionally,                 // for some reason, on what seem to be otherwise perfectly valid assemblies (it must be                 // intermittent given that otherwise the user would be completely unable to use the reference                // manager), the pointer that we generate to look up the AssemblyTitle is apparently invalid,                 // or for some reason Marshal.ReadByte thinks it is.                  //                return false;            }            return (strValue != null);        }        /// <summary>        /// Returns the number of bytes that compressed data -- the length of the uncompressed         /// data -- takes up, and has an out value of the length of the string.          ///         /// Decompression algorithm stolen from ndp\clr\src\toolbox\mdbg\corapi\metadata\cormetadata.cs, which         /// was translated from the base implementation in ndp\clr\src\inc\cor.h        /// This code was taken from the vsproject\ReferenceManager\Providers\NativeMethods.cs        /// </summary>        /// <param name="data">Pointer to the beginning of the data block</param>        /// <param name="uncompressedData">Length of the uncompressed data block</param>        internal static unsafe int CorSigUncompressData(IntPtr data, out int uncompressedDataLength)        {            // As described in bizapps\server\designers\models\packagemodel\nativemethods.cs:            // The maximum encodable integer is 29 bits long, 0x1FFFFFFF. The compression algorithm used is as follows (bit 0 is the least significant bit):            // - If the value lies between 0 (0x00) and 127 (0x7F), inclusive, encode as a one-byte integer (bit 7 is clear, value held in bits 6 through 0)            // - If the value lies between 2^8 (0x80) and 2^14 - 1 (0x3FFF), inclusive, encode as a 2-byte integer with bit 15 set, bit 14 clear (value held in bits 13 through 0)            // - Otherwise, encode as a 4-byte integer, with bit 31 set, bit 30 set, bit 29 clear (value held in bits 28 through 0)            // - A null string should be represented with the reserved single byte 0xFF, and no following data            int count = -1;            byte* bytes = (byte*)(data);            uncompressedDataLength = 0;            // Smallest.                if ((*bytes & 0x80) == 0x00)       // 0??? ????                {                uncompressedDataLength = *bytes;                count = 1;            }            // Medium.              else if ((*bytes & 0xC0) == 0x80)  // 10?? ????                {                uncompressedDataLength = (int)(((*bytes & 0x3f) << 8 | *(bytes + 1)));                count = 2;            }            else if ((*bytes & 0xE0) == 0xC0)      // 110? ????                {                uncompressedDataLength = (int)(((*bytes & 0x1f) << 24 | *(bytes + 1) << 16 | *(bytes + 2) << 8 | *(bytes + 3)));                count = 4;            }            return count;        }        #endregion




0 0
原创粉丝点击