Example #1
0
        /// <summary>Получить информацию по импорту</summary>
        /// <param name="offset">Сдвиг по PE файлу</param>
        /// <param name="isRva">Получить импорт по Relative Virtual Address адресу. В противном случае передаётся Virtual Address</param>
        /// <returns>Структура</returns>
        private WinNT.IMAGE_IMPORT_BY_NAME GetImageImport(UInt32 offset, Boolean isRva)
        {
            PEHeader header = this.Directory.Parent.Header;
            UInt64   forwarderString;

            if (header.Is64Bit)
            {
                WinNT.IMAGE_THUNK_DATA64 thunk64 = header.PtrToStructure <WinNT.IMAGE_THUNK_DATA64>(offset);
                forwarderString = thunk64.ForwarderString;                //TODO: Вот тут может быть ошибка
            }
            else
            {
                WinNT.IMAGE_THUNK_DATA32 thunk32 = header.PtrToStructure <WinNT.IMAGE_THUNK_DATA32>(offset);
                forwarderString = thunk32.ForwarderString;
            }

            WinNT.IMAGE_IMPORT_BY_NAME result;
            if ((forwarderString & 0x80000000) != 0)
            {
                result = new WinNT.IMAGE_IMPORT_BY_NAME()
                {
                    Hint = (UInt16)(forwarderString & 0x7FFFFFFF),
                    Name = null,
                };
            }
            else if ((forwarderString & 0x8000000000000000) != 0)
            {
                result = new WinNT.IMAGE_IMPORT_BY_NAME()
                {
                    Hint = (UInt16)(forwarderString & 0x7FFFFFFFFFFFFFFF),
                    Name = null,
                };
            }
            else
            {
                if (!isRva)
                {
                    UInt64 imageBase;
                    if (header.Is64Bit)
                    {
                        imageBase = header.HeaderNT64.OptionalHeader.ImageBase;
                    }
                    else
                    {
                        imageBase = header.HeaderNT32.OptionalHeader.ImageBase;
                    }

                    forwarderString -= imageBase;
                }

                result = header.PtrToStructure <WinNT.IMAGE_IMPORT_BY_NAME>((UInt32)forwarderString);
            }
            return(result);
        }
Example #2
0
        /// <summary>Get fat method header sections</summary>
        /// <returns>Method header sections</returns>
        public IEnumerable <MethodSection> GetSections()
        {
            UInt32 padding      = this.Row.RVA + this.Header.HeaderSize;
            UInt32 methodLength = this.Header.CodeSize;

            if ((this.Header.Format & Cor.CorILMethod.FatFormat) == Cor.CorILMethod.FatFormat &&
                (this.Header.Format & Cor.CorILMethod.MoreSects) == Cor.CorILMethod.MoreSects)
            {
                padding += methodLength;
                PEHeader header       = this.Row.Row.Table.Root.Parent.Parent.Parent.Header;
                Boolean  moreSections = true;

                while (moreSections)
                {
                    //Each section should start on a 4 byte boundary
                    //so let's read from the stream until we find the next boundary.
                    padding = NativeMethods.AlignToInt(padding);
                    Cor.CorILMethodSection section = header.PtrToStructure <Cor.CorILMethodSection>(padding);
                    padding += MethodBody.SizeOfMethodSection;

                    //I have never seen anything else than an exception handling section...
                    //According to the documentation "Currently, the method data sections
                    //are only used for exception tables."
                    if ((section.Kind & Cor.CorILMethod_Sect.EHTable) != Cor.CorILMethod_Sect.EHTable)
                    {
                        throw new NotImplementedException("Only exception table supported");
                    }

                    //Check whether more sections follow after this one.
                    moreSections = section.HasMoreSections;

                    Cor.CorILMethodExceptionFat[]   fat   = new Cor.CorILMethodExceptionFat[section.IsFatFormat ? section.ClauseNumber : 0];
                    Cor.CorILMethodExceptionSmall[] small = new Cor.CorILMethodExceptionSmall[section.IsFatFormat ? 0 : section.ClauseNumber];
                    //Let's read the clauses...
                    for (Int32 clauseIndex = 0; clauseIndex < section.ClauseNumber; clauseIndex++)
                    {
                        //The structure of the clauses are the same in both Fat and
                        //Small format, only the sizes are different.
                        if (section.IsFatFormat)
                        {
                            fat[clauseIndex] = header.PtrToStructure <Cor.CorILMethodExceptionFat>(padding);
                            padding         += MethodBody.SizeOfMethodExceptionFat;
                        }
                        else
                        {
                            small[clauseIndex] = header.PtrToStructure <Cor.CorILMethodExceptionSmall>(padding);
                            padding           += MethodBody.SizeOfMethodExceptionSmall;
                        }
                    }
                    yield return(new MethodSection(section, fat, small));
                }
            }
        }