public RelocationTypeOffsetItem(ulong address,
                                 RelocationTypeOffset relocationTypeOffset,
                                 object tag)
 {
     Address = address;
     RelocationTypeOffset = relocationTypeOffset;
     Tag = tag;
 }
 private static bool IsOffsetInInstruction(IInstruction instruction,
                                           RelocationTypeOffset relocationOffset, ulong codeVirtualAddress)
 {
     return(instruction.Offset + codeVirtualAddress <= relocationOffset.Offset &&
            instruction.PC + codeVirtualAddress > relocationOffset.Offset);
 }
        public static List <RelocationTypeOffsetItem> GetAddressesOfCodeInData(
            this PeFile peFile,
            IMAGE_SECTION_HEADER codeSectionHeader)
        {
            ulong startOfCodeAddress = codeSectionHeader.VirtualAddress;
            ulong endOfCodeAddress   = startOfCodeAddress + codeSectionHeader.VirtualSize;
            List <RelocationTypeOffsetItem> relocationTypeOffsetList = new List <RelocationTypeOffsetItem>();

            if (peFile.ImageRelocationDirectory == null)
            {
                return(relocationTypeOffsetList);
            }

            foreach (var relocationDirectoryInfo in peFile.ImageRelocationDirectory)
            {
                //for code section do not check for addresses in data.
                if (relocationDirectoryInfo.VirtualAddress >= startOfCodeAddress &&
                    relocationDirectoryInfo.VirtualAddress <= endOfCodeAddress)
                {
                    continue;
                }

                foreach (var sectionHeader in peFile.ImageSectionHeaders)
                {
                    ulong endOfSection = sectionHeader.VirtualAddress + sectionHeader.VirtualSize;

                    //this section header contains the whole relocation directory entry
                    if (relocationDirectoryInfo.VirtualAddress >= sectionHeader.VirtualAddress &&
                        relocationDirectoryInfo.VirtualAddress < endOfSection)
                    {
                        foreach (var typeOffset in relocationDirectoryInfo.TypeOffsets)
                        {
                            if (typeOffset.Type == 0)
                            {
                                continue;
                            }

                            //calculate the offset of the relocation directory info from the begining of section
                            var reloationDirectroryOffsetFromSectionBegining =
                                relocationDirectoryInfo.VirtualAddress - sectionHeader.VirtualAddress;

                            //read the address from buffer
                            uint bufferOffset = sectionHeader.PointerToRawData +
                                                typeOffset.Offset + reloationDirectroryOffsetFromSectionBegining;

                            //the address that appears in the data section - in term of RVA address
                            //that sums also the image base. i.e. 0x411212
                            ulong addressInData = peFile.Buff.BytesToUInt32(bufferOffset);

                            //in case relocation info is 0
                            if (addressInData == 0)
                            {
                                continue;
                            }

                            //the relative address in term of virtual address like 0x11212
                            ulong relativeAddressInData = addressInData - peFile.ImageNtHeaders.OptionalHeader.ImageBase;

                            //the address of code in data as intruction offset (like 0x212)
                            ulong addressInDataAsInstructionOffset = relativeAddressInData - codeSectionHeader.VirtualAddress;

                            //if the address in the data section is in code section,
                            //then create an item and add it to list
                            if (relativeAddressInData >= startOfCodeAddress &&
                                relativeAddressInData <= endOfCodeAddress)
                            {
                                var relocationOffsetType = new RelocationTypeOffset()
                                {
                                    Offset = relocationDirectoryInfo.VirtualAddress +
                                             typeOffset.Offset,
                                    Type = typeOffset.Type,
                                };

                                relocationTypeOffsetList.Add(new RelocationTypeOffsetItem(
                                                                 addressInDataAsInstructionOffset,
                                                                 relocationOffsetType, sectionHeader));
                            }
                        }

                        //continue examine next relocation directory info entry
                        break;
                    }
                }
            }
            return(relocationTypeOffsetList);
        }
 /// <summary>
 /// is instruction before relocation offset
 /// </summary>
 /// <param name="instruction"></param>
 /// <param name="relocationOffset"></param>
 /// <param name="codeVirtualAddress"></param>
 /// <returns></returns>
 private static bool IsInstructionBeforeOffset(IInstruction instruction,
                                               RelocationTypeOffset relocationOffset, ulong codeVirtualAddress)
 {
     return(instruction.PC + codeVirtualAddress <= relocationOffset.Offset);
 }