Example #1
0
        public void Load(string file)
        {
            FileStream   fs = new FileStream(file, FileMode.Open, FileAccess.Read);
            BinaryReader br = new BinaryReader(fs);

            try {
                buffer           = br.ReadBytes((int)fs.Length);
                dosHeader        = ReadDosHeader(buffer, 0);
                ntHeader         = ReadNTHeader(buffer, dosHeader.lfanew);
                sectionAlignment = ntHeader.NTOptionalHeader.SectionAlignment;
                uint pos = dosHeader.lfanew + IMAGE_NT_HEADERS.StructSize;
                uint va  = ntHeader.NTOptionalHeader.DataDirectory.runtimeHeader.VirtualAddress;
                sectHeaders = new IMAGE_SECTION_HEADER[ntHeader.NTFileHeader.NumberOfSections];
                for (uint i = 0; i < ntHeader.NTFileHeader.NumberOfSections; i++)
                {
                    IMAGE_SECTION_HEADER sectHeader = ReadSectionHeader(buffer, pos);
                    pos += IMAGE_SECTION_HEADER.StructSize;

                    sectHeaders[i] = sectHeader;
                }
                newSectHeaderPos = pos;
                pos       = GetFileOffset(va);
                corHeader = ReadCor20Header(buffer, pos);
                uint metadataRVA  = corHeader.MetaData.VirtualAddress;
                uint metadataSize = corHeader.MetaData.Size;
                pos      = GetFileOffset(metadataRVA);
                metadata = ReadMetadataTables(buffer, pos, metadataSize);
            } finally {
                br.Close();
                fs.Close();
                fs.Dispose();
            }
        }
Example #2
0
        public void Save(string file, IMAGE_SECTION_HEADER header, byte[] newSection)
        {
            FileStream   fs = new FileStream(file, FileMode.Create, FileAccess.Write);
            BinaryWriter bw = new BinaryWriter(fs);

            try {
                uint   size = header.PointerToRawData + header.SizeOfRawData;
                byte[] buf  = new byte[size];
                buf.Initialize();

                WriteDosHeader(buf, 0, dosHeader);
                uint pos = dosHeader.lfanew;
                WriteNTHeader(buf, pos, ntHeader);
                pos = dosHeader.lfanew + IMAGE_NT_HEADERS.StructSize;
                for (uint i = 0; i < newSectHeaders.Length; i++)
                {
                    WriteSectionHeader(buf, pos, newSectHeaders[i]);
                    pos += IMAGE_SECTION_HEADER.StructSize;
                }
                WriteSectionHeader(buf, newSectHeaderPos, header);

                for (uint i = 0; i < newSectHeaders.Length; i++)
                {
                    Array.Copy(buffer, sectHeaders[i].PointerToRawData, buf, newSectHeaders[i].PointerToRawData, sectHeaders[i].SizeOfRawData);
                }
                Array.Copy(newSection, 0, buf, header.PointerToRawData, newSection.Length);

                bw.Write(buf);
            } finally {
                bw.Close();
                fs.Close();
                fs.Dispose();
            }
        }
Example #3
0
        private static unsafe void WriteSectionHeader(byte[] buffer, uint pos, IMAGE_SECTION_HEADER header)
        {
            fixed(byte *p = buffer)
            {
                IMAGE_SECTION_HEADER *ptr = (IMAGE_SECTION_HEADER *)(p + pos);

                *ptr = header;
            }
        }
Example #4
0
        private static unsafe IMAGE_SECTION_HEADER ReadSectionHeader(byte[] buffer, uint pos)
        {
            IMAGE_SECTION_HEADER dosHeader = new IMAGE_SECTION_HEADER();

            fixed(byte *p = buffer)
            {
                IMAGE_SECTION_HEADER *ptr = (IMAGE_SECTION_HEADER *)(p + pos);

                dosHeader = *ptr;
            }

            return(dosHeader);
        }
Example #5
0
        public IMAGE_SECTION_HEADER PrepareNewSectionHeader(string name, uint sectSize, bool forMetadata)
        {
            uint curRVA = Alignment.Calc(newSectHeaderPos + IMAGE_SECTION_HEADER.StructSize, sectionAlignment);

            ntHeader.NTFileHeader.NumberOfSections++;
            ntHeader.NTOptionalHeader.FileAlignment = sectionAlignment;//必须让文件对齐与段对齐一样,这样才能保证跨段偏移对文件与对内存一致
            ntHeader.NTOptionalHeader.SizeOfHeaders = curRVA;

            newSectHeaders = new IMAGE_SECTION_HEADER[sectHeaders.Length];
            for (uint i = 0; i < newSectHeaders.Length; i++)
            {
                newSectHeaders[i] = sectHeaders[i];

                newSectHeaders[i].VirtualAddress   = curRVA;
                newSectHeaders[i].SizeOfRawData    = Alignment.Calc(newSectHeaders[i].SizeOfRawData, sectionAlignment);
                newSectHeaders[i].PointerToRawData = curRVA;

                curRVA = Alignment.Calc(curRVA + newSectHeaders[i].SizeOfRawData, sectionAlignment);
            }
            //添加新段
            IMAGE_SECTION_HEADER header = new IMAGE_SECTION_HEADER();

            header.Name                 = name;
            header.VirtualSize          = sectSize;
            header.VirtualAddress       = curRVA;
            header.SizeOfRawData        = Alignment.Calc(sectSize, sectionAlignment);
            header.PointerToRawData     = curRVA;
            header.PointerToRelocations = 0;
            header.PointerToLinenumbers = 0;
            header.NumberOfRelocations  = 0;
            header.NumberOfLinenumbers  = 0;
            header.Characteristics      = 0x60000020;

            ntHeader.NTOptionalHeader.SizeOfImage = Alignment.Calc(header.VirtualAddress + header.SizeOfRawData, sectionAlignment);

            if (forMetadata)
            {
                corHeader.MetaData.VirtualAddress = header.VirtualAddress;
                corHeader.MetaData.Size           = sectSize;
                uint va  = ntHeader.NTOptionalHeader.DataDirectory.runtimeHeader.VirtualAddress;
                uint pos = GetFileOffset(va);
                WriteCor20Header(buffer, pos, corHeader);//改写原映像数据中的Cor20头,这些修改在Save时会随着所属段一起拷贝到新映像数据中
            }
            return(header);
        }
Example #6
0
        public uint GetFileOffset(uint va)
        {
            int  n    = sectHeaders.Length;
            uint sva  = 0;
            uint addr = 0;

            for (uint i = 0; i < n; i++)
            {
                IMAGE_SECTION_HEADER sectHeader = sectHeaders[i];
                if (sectHeader.VirtualAddress <= va)
                {
                    if (sva <= sectHeader.VirtualAddress)
                    {
                        sva  = sectHeader.VirtualAddress;
                        addr = sectHeader.PointerToRawData;
                    }
                }
            }
            return(va - sva + addr);
        }