コード例 #1
0
        public void WritePortableExecutable(BinaryWriter writer)
        {
            writer.BaseStream.Seek(0, SeekOrigin.Begin);
            m_dosHeader.Write(writer);
            writer.Write(m_dosStubBytes);
            m_coffHeader.Write(writer);
            m_peHeaderOffset = (uint)writer.BaseStream.Position;
            m_peHeader.Write(writer);
            for (int i = 0; i < m_coffHeader.NumberOfSections; i++)
            {
                m_sectionHeaders[i].Write(writer);
            }

            writer.Write(m_filler);
            for (int i = 0; i < m_coffHeader.NumberOfSections; i++)
            {
                writer.Write(m_sections[i]);
            }

            writer.Write(m_remainingBytes);

            // Write Import Directory:
            PEDataDirectory importDirectoryEntry = m_peHeader.DataDirectories[(int)DataDirectoryName.Import];

            if (importDirectoryEntry.VirtualAddress > 0)
            {
                uint importDirectoryFileOffset = GetOffsetFromRVA(importDirectoryEntry.VirtualAddress);
                writer.Seek((int)importDirectoryFileOffset, SeekOrigin.Begin);
                m_importDirectory.Write(writer);
            }

            // Update PE checksum:
            writer.Seek(0, SeekOrigin.Begin);
            byte[] fileBytes = new byte[writer.BaseStream.Length];
            writer.BaseStream.Read(fileBytes, 0, (int)writer.BaseStream.Length);
            uint checksumOffset = m_peHeaderOffset + PEHeader.ChecksumRelativeAddress;
            uint checksum       = PortableExecutableUtils.CalculcateChecksum(fileBytes, checksumOffset);

            writer.Seek((int)checksumOffset, SeekOrigin.Begin);
            writer.Write(checksum);
            writer.Flush();
        }
コード例 #2
0
        public static void RenameDependencyFileName(string filePath, string oldFileName, string newFileName)
        {
            if (oldFileName.Length != newFileName.Length)
            {
                throw new NotImplementedException("when renaming dependencies, old file name must have the same size as new file name");
            }

            PortableExecutableInfo peInfo = new PortableExecutableInfo(filePath);
            uint            oldNameRVA    = 0;
            PESectionHeader header        = null;
            int             sectionIndex  = -1;

            foreach (ImageImportDescriptor descriptor in peInfo.ImportDirectory.Descriptors)
            {
                uint nameRVA = descriptor.NameRVA;
                header = peInfo.FindSectionByRVA(nameRVA);
                if (header != null)
                {
                    sectionIndex = peInfo.SectionHeaders.IndexOf(header);

                    uint fileNameAddressInSection = peInfo.GetAddressInSectionFromRVA(header, nameRVA);

                    string fileName = PortableExecutableUtils.ReadNullTerminatedAsciiString(peInfo.Sections[sectionIndex], fileNameAddressInSection);
                    if (fileName.Equals(oldFileName, StringComparison.InvariantCultureIgnoreCase))
                    {
                        oldNameRVA = nameRVA;
                    }
                }
            }

            if (oldNameRVA > 0)
            {
                byte[] newFileNameAsciiBytes = ASCIIEncoding.ASCII.GetBytes(newFileName);
                uint   addressInSection      = peInfo.GetAddressInSectionFromRVA(header, oldNameRVA);
                byte[] section = peInfo.Sections[sectionIndex];
                Buffer.BlockCopy(newFileNameAsciiBytes, 0, section, (int)addressInSection, newFileNameAsciiBytes.Length);
            }
            PortableExecutableInfo.WritePortableExecutable(peInfo, filePath);
        }