Example #1
0
        /// <summary>
        /// Get section object from name
        /// </summary>
        /// <param name="name">section name</param>
        /// <returns>the result section object, return null if not found</returns>
        public SectionEntry getSection(string name)
        {
            SectionEntry result = null;

            this.sectionEntries.ForEach(s => { if (s.header.name.ToString() == name)
                                               {
                                                   result = s;
                                               }
                                        });

            return(result);
        }
Example #2
0
        /// <summary>
        /// Get section object from ordinal
        /// </summary>
        /// <param name="ordinal">section ordinal</param>
        /// <returns>the result section object, return null if not found</returns>
        public SectionEntry getSection(int ordinal)
        {
            SectionEntry result = null;

            this.sectionEntries.ForEach(s => { if (s.sectionId == ordinal)
                                               {
                                                   result = s;
                                               }
                                        });

            return(result);
        }
Example #3
0
        /*
         * // I keep it for later
         * // TODO : clean the code
         * private int calcVirtualAddressDynamic(SectionTypes type)
         * {
         *  List<SectionEntry> selectedSections = type == SectionTypes.CODE_SECTION ? getCodeSections() : getDataSections();
         *
         *  SectionEntry lastSection = selectedSections[selectedSections.Count - 1];
         *
         *  return lastSection.header.virtualAddress.getValue() + calcVirtualAddressPadding(type);
         * }
         */

        /// <summary>
        /// Set the entrypoint in the executable
        /// </summary>
        /// <param name="codeSection"></param>
        /// <param name="entrypointOffsetInSection"></param>
        public void setEntrypoint(SectionEntry codeSection, int entrypointOffsetInSection)
        {
            if (codeSection.type != SectionTypes.CODE_SECTION)
            {
                throw new Exception("Trying to set the entrypoint on a section that is not a code section");
            }

            int entrypointVirtual = codeSection.header.virtualAddress.getValue() + entrypointOffsetInSection;

            // set the entrypoint
            this.header.optionalHeader.AddressOfEntryPoint.setValue(entrypointVirtual);
        }
Example #4
0
        /// <summary>
        /// Get a section from a file offset
        /// </summary>
        /// <param name="address">The file address</param>
        /// <returns>The section that contain this address, return null if not found</returns>
        public SectionEntry getSectionFromFileAddress(int address)
        {
            SectionEntry section = null;

            this.sectionEntries.ForEach(s => {
                if (address >= s.header.pointerToRawData.getValue() &&
                    address < (s.header.pointerToRawData.getValue() + s.header.sizeOfRawData.getValue()))
                {
                    section = s;
                }
            });

            return(section);
        }
Example #5
0
        /// <summary>
        /// Get a section from a vitual address that is in the mapped virtual memory
        /// </summary>
        /// <param name="address">The virtual address</param>
        /// <returns>The section that contain this address, return null if not found</returns>
        public SectionEntry getSectionFromVirtualAddress(int address)
        {
            SectionEntry section = null;

            this.sectionEntries.ForEach(s => {
                if (address >= s.header.virtualAddress.getValue() &&
                    address < (s.header.virtualAddress.getValue() + s.header.virtualSize.getValue()))
                {
                    section = s;
                }
            });

            return(section);
        }
Example #6
0
        /// <summary>
        /// Export all the data of the section block
        /// </summary>
        /// <returns>Array of byte that represent the sections</returns>
        public List <byte> exportSectionsData()
        {
            if (this.header.peHeader.NumberOfSection.getValue() < 1)
            {
                throw new Exception("Trying to export sections without sections");
            }

            List <byte> section = new List <byte>();

            int sectionHeaderSize = exportHeaders().Count;

            // 16 bytes before sections
            Utils.addArrayToList <byte>(section, new byte[16]);

            int sectionStartAddress = this.header.sectionHeaderBaseAddress + section.Count + sectionHeaderSize;

            SectionEntry lastSection = this.getLastEntry();

            int sectionBufferEndAddress = (int)lastSection.header.pointerToRawData.getValue() + (int)lastSection.header.sizeOfRawData.getValue();

            int sectionBufferSize = sectionBufferEndAddress - sectionStartAddress;

            // a buffer to write all sections intro it
            byte[] sectionBuffers = new byte[sectionBufferSize];

            // sections
            foreach (SectionEntry item in sectionEntries)
            {
                byte[] sectionBuffer = item.getSectionBuffer();

                // the raw address already respect the file alignment
                int rawAddress = item.header.pointerToRawData.getValue() - sectionStartAddress;

                // write section in the right address
                for (int i = 0; i < sectionBuffer.Length; i++)
                {
                    sectionBuffers[rawAddress + i] = sectionBuffer[i];
                }
            }

            // add the sections buffer
            Utils.addArrayToList <byte>(section, sectionBuffers);

            return(section);
        }
Example #7
0
        // TODO
        private void removeSection(SectionEntry section)
        {
            this.sectionEntries.Remove(section);

            // this.header.peHeader.NumberOfSection - 1
        }
Example #8
0
        /// <summary>
        /// Add a new section to executable
        /// NOTE : if is the first section the user has to handle the virtualAddress
        /// </summary>
        /// <param name="name"></param>
        /// <param name="data"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public SectionEntry addSection(string name, byte[] data, SectionTypes type)
        {
            // setup the virtual address of the section
            int virtualAddressBase = this.header.optionalHeader.BaseOfCode.getValue();

            // BaseOfData doesn't exist in x64
            if (this.header.is32Bit)
            {
                virtualAddressBase = type == SectionTypes.CODE_SECTION ? this.header.optionalHeader.BaseOfCode.getValue() : this.header.optionalHeader.BaseOfData.getValue();
            }

            // create the section
            SectionEntry section = new SectionEntry(this.entries, this.header);

            // set the name
            section.header.setName(name);

            bool isFirstSection = this.header.peHeader.NumberOfSection.getValue() < 1;

            // there is already a section
            if (!isFirstSection)
            {
                SectionEntry lastSection = this.getLastEntry();

                int newSectionAddress = lastSection.header.pointerToRawData.getValue()
                                        + lastSection.header.sizeOfRawData.getValue();

                // set the new section address
                section.header.pointerToRawData.setValue(newSectionAddress);
            }

            // the PE is empty
            else
            {
                // 16 bytes of padding before section's data
                int newSectionAddress = this.sectionHeaderBaseAddress + section.header.export().Count + 16;

                // set the new section address
                section.header.pointerToRawData.setValue(newSectionAddress);
            }

            // set the section size
            section.header.sizeOfRawData.setValue(data.Length);

            // zero if there is no relocation
            section.header.pointerToRelocations.setValue(0);
            section.header.numberOfRelocations.setValue(0);
            section.header.numberOfLinenumbers.setValue(0);

            // set the virtual address
            if (!isFirstSection)
            {
                SectionEntry lastSection = this.getLastEntry();

                int virtualAddress = calcVirtualAddress(lastSection.header.virtualAddress.getValue(), lastSection.header.virtualSize.getValue(), this.header.optionalHeader.SectionAlignment.getValue());

                section.header.virtualAddress.setValue(virtualAddress);
            }
            else
            {
                // set the virtualAddressBase to BaseOfCode or BaseOfData by default
                section.header.virtualAddress.setValue(virtualAddressBase);
            }

            // set the section virtual size as the same as raw size
            // not optimized but I can't find an accurate size without analysing the data
            section.header.virtualSize.setValue(data.Length);

            // set characteristics
            // TODO : fix uint

            // the section should be read by default
            section.header.characteristics += (int)SectionFlags.IMAGE_SCN_MEM_READ;

            // flag related to code sections
            if (type == SectionTypes.CODE_SECTION)
            {
                section.header.characteristics += (int)SectionFlags.IMAGE_SCN_CNT_CODE;
                section.header.characteristics += (int)SectionFlags.IMAGE_SCN_MEM_EXECUTE;
            }

            // flag related to "data" sections (not specificly ".data" sections)
            else
            {
                section.header.characteristics += (int)SectionFlags.IMAGE_SCN_CNT_INITIALIZED_DATA;
            }

            // set the type
            // TODO : fix order characteristics check (see how it handle .data dir)
            section.type = type;

            // set the data of the section
            section.rawData = data;

            // adding the section to the list
            this.sectionEntries.Add(section);

            // increase number of section
            this.header.peHeader.NumberOfSection += 1;

            // header fixing part
            updateHeader(type);

            // return the section object
            return(section);
        }
Example #9
0
 /// <summary>
 /// Checks if a memory offset is in the section
 /// NOTE : useless if ASLR
 /// </summary>
 /// <param name="offset"></param>
 /// <param name="section"></param>
 /// <returns></returns>
 public bool isVirtualAddressInSection(int offset, SectionEntry section)
 {
     return(offset >= section.header.virtualAddress.getValue() && offset <= (section.header.virtualAddress.getValue() + section.header.virtualSize.getValue()));
 }
Example #10
0
 /// <summary>
 /// Checks if a file offset is in the section
 /// </summary>
 /// <param name="offset"></param>
 /// <param name="section"></param>
 /// <returns></returns>
 public bool isFileOffsetInSection(int offset, SectionEntry section)
 {
     return(offset >= section.header.pointerToRawData.getValue() && offset <= (section.header.pointerToRawData.getValue() + section.header.sizeOfRawData.getValue()));
 }