/// <summary> /// 读取映像文件头部. /// </summary> void ReadHeaders() { FileStream fs = null; BinaryReader binReader = null; try { fs = new FileStream(ExeFilePath, FileMode.Open, FileAccess.Read); binReader = new BinaryReader(fs); // 读取PE头部开始偏移量. fs.Position = 0x3C; UInt32 headerOffset = binReader.ReadUInt32(); // 核对偏移量是否有效 if (headerOffset > fs.Length - 5) { throw new ApplicationException("无效映像格式"); } // 读取PE文件签名 fs.Position = headerOffset; UInt32 signature = binReader.ReadUInt32(); // 0x00004550 表示字母“PE”,其后有两个终止符0. if (signature != 0x00004550) { throw new ApplicationException("无效映像格式"); } // 读取映像文件头部. this.imageFileHeader.Machine = binReader.ReadUInt16(); this.imageFileHeader.NumberOfSections = binReader.ReadUInt16(); this.imageFileHeader.TimeDateStamp = binReader.ReadUInt32(); this.imageFileHeader.PointerToSymbolTable = binReader.ReadUInt32(); this.imageFileHeader.NumberOfSymbols = binReader.ReadUInt32(); this.imageFileHeader.SizeOfOptionalHeader = binReader.ReadUInt16(); this.imageFileHeader.Characteristics = (IMAGE.IMAGE_FILE_Flag)binReader.ReadUInt16(); // 判断是否是32位程序集. UInt16 magic = binReader.ReadUInt16(); if (magic != 0x010B && magic != 0x020B) { throw new ApplicationException("无效映像格式"); } // 对32应用程序读取 IMAGE_OPTIONAL_HEADER32 字段. if (magic == 0x010B) { this.Is32bitImage = true; this.optinalHeader32.Magic = magic; this.optinalHeader32.MajorLinkerVersion = binReader.ReadByte(); this.optinalHeader32.MinorImageVersion = binReader.ReadByte(); this.optinalHeader32.SizeOfCode = binReader.ReadUInt32(); this.optinalHeader32.SizeOfInitializedData = binReader.ReadUInt32(); this.optinalHeader32.SizeOfUninitializedData = binReader.ReadUInt32(); this.optinalHeader32.AddressOfEntryPoint = binReader.ReadUInt32(); this.optinalHeader32.BaseOfCode = binReader.ReadUInt32(); this.optinalHeader32.BaseOfData = binReader.ReadUInt32(); this.optinalHeader32.ImageBase = binReader.ReadUInt32(); this.optinalHeader32.SectionAlignment = binReader.ReadUInt32(); this.optinalHeader32.FileAlignment = binReader.ReadUInt32(); this.optinalHeader32.MajorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader32.MinorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader32.MajorImageVersion = binReader.ReadUInt16(); this.optinalHeader32.MinorImageVersion = binReader.ReadUInt16(); this.optinalHeader32.MajorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader32.MinorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader32.Win32VersionValue = binReader.ReadUInt32(); this.optinalHeader32.SizeOfImage = binReader.ReadUInt32(); this.optinalHeader32.SizeOfHeaders = binReader.ReadUInt32(); this.optinalHeader32.CheckSum = binReader.ReadUInt32(); this.optinalHeader32.Subsystem = binReader.ReadUInt16(); this.optinalHeader32.DllCharacteristics = binReader.ReadUInt16(); this.optinalHeader32.SizeOfStackReserve = binReader.ReadUInt32(); this.optinalHeader32.SizeOfStackCommit = binReader.ReadUInt32(); this.optinalHeader32.SizeOfHeapReserve = binReader.ReadUInt32(); this.optinalHeader32.SizeOfHeapCommit = binReader.ReadUInt32(); this.optinalHeader32.LoaderFlags = binReader.ReadUInt32(); this.optinalHeader32.NumberOfRvaAndSizes = binReader.ReadUInt32(); } // 对64位应用程序读取 IMAGE_OPTIONAL_HEADER64 字段. else { this.Is32bitImage = false; this.optinalHeader64.Magic = magic; this.optinalHeader64.MajorLinkerVersion = binReader.ReadByte(); this.optinalHeader64.MinorImageVersion = binReader.ReadByte(); this.optinalHeader64.SizeOfCode = binReader.ReadUInt32(); this.optinalHeader64.SizeOfInitializedData = binReader.ReadUInt32(); this.optinalHeader64.SizeOfUninitializedData = binReader.ReadUInt32(); this.optinalHeader64.AddressOfEntryPoint = binReader.ReadUInt32(); this.optinalHeader64.BaseOfCode = binReader.ReadUInt32(); this.optinalHeader64.ImageBase = binReader.ReadUInt64(); this.optinalHeader64.SectionAlignment = binReader.ReadUInt32(); this.optinalHeader64.FileAlignment = binReader.ReadUInt32(); this.optinalHeader64.MajorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader64.MinorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader64.MajorImageVersion = binReader.ReadUInt16(); this.optinalHeader64.MinorImageVersion = binReader.ReadUInt16(); this.optinalHeader64.MajorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader64.MinorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader64.Win32VersionValue = binReader.ReadUInt32(); this.optinalHeader64.SizeOfImage = binReader.ReadUInt32(); this.optinalHeader64.SizeOfHeaders = binReader.ReadUInt32(); this.optinalHeader64.CheckSum = binReader.ReadUInt32(); this.optinalHeader64.Subsystem = binReader.ReadUInt16(); this.optinalHeader64.DllCharacteristics = binReader.ReadUInt16(); this.optinalHeader64.SizeOfStackReserve = binReader.ReadUInt64(); this.optinalHeader64.SizeOfStackCommit = binReader.ReadUInt64(); this.optinalHeader64.SizeOfHeapReserve = binReader.ReadUInt64(); this.optinalHeader64.SizeOfHeapCommit = binReader.ReadUInt64(); this.optinalHeader64.LoaderFlags = binReader.ReadUInt32(); this.optinalHeader64.NumberOfRvaAndSizes = binReader.ReadUInt32(); } // 读取数据目录. this.directoryValues = new IMAGE.IMAGE_DATA_DIRECTORY_Values(); for (int i = 0; i < 16; i++) { directoryValues.Values[i].VirtualAddress = binReader.ReadUInt32(); directoryValues.Values[i].Size = binReader.ReadUInt32(); } } finally { // 释放IO资源. if (binReader != null) { binReader.Close(); } if (fs != null) { fs.Close(); } } }
/// <summary> /// Read the headers from the image file. /// </summary> void ReadHeaders() { FileStream fs = null; BinaryReader binReader = null; try { fs = new FileStream(ExeFilePath, FileMode.Open, FileAccess.Read); binReader = new BinaryReader(fs); // Read the PE Header start offset. fs.Position = 0x3C; UInt32 headerOffset = binReader.ReadUInt32(); // Check if the offset is invalid if (headerOffset > fs.Length - 5) { throw new ApplicationException("Invalid Image Format"); } // Read the PE file signature fs.Position = headerOffset; UInt32 signature = binReader.ReadUInt32(); // 0x00004550 is the letters "PE" followed by two terminating zeroes. if (signature != 0x00004550) { throw new ApplicationException("Invalid Image Format"); } // Read the image file header. this.imageFileHeader.Machine = binReader.ReadUInt16(); this.imageFileHeader.NumberOfSections = binReader.ReadUInt16(); this.imageFileHeader.TimeDateStamp = binReader.ReadUInt32(); this.imageFileHeader.PointerToSymbolTable = binReader.ReadUInt32(); this.imageFileHeader.NumberOfSymbols = binReader.ReadUInt32(); this.imageFileHeader.SizeOfOptionalHeader = binReader.ReadUInt16(); this.imageFileHeader.Characteristics = (IMAGE.IMAGE_FILE_Flag)binReader.ReadUInt16(); // Determine whether this is a 32bit assembly. UInt16 magic = binReader.ReadUInt16(); if (magic != 0x010B && magic != 0x020B) { throw new ApplicationException("Invalid Image Format"); } // Read the IMAGE_OPTIONAL_HEADER32 for 32bit application. if (magic == 0x010B) { this.Is32bitImage = true; this.optinalHeader32.Magic = magic; this.optinalHeader32.MajorLinkerVersion = binReader.ReadByte(); this.optinalHeader32.MinorImageVersion = binReader.ReadByte(); this.optinalHeader32.SizeOfCode = binReader.ReadUInt32(); this.optinalHeader32.SizeOfInitializedData = binReader.ReadUInt32(); this.optinalHeader32.SizeOfUninitializedData = binReader.ReadUInt32(); this.optinalHeader32.AddressOfEntryPoint = binReader.ReadUInt32(); this.optinalHeader32.BaseOfCode = binReader.ReadUInt32(); this.optinalHeader32.BaseOfData = binReader.ReadUInt32(); this.optinalHeader32.ImageBase = binReader.ReadUInt32(); this.optinalHeader32.SectionAlignment = binReader.ReadUInt32(); this.optinalHeader32.FileAlignment = binReader.ReadUInt32(); this.optinalHeader32.MajorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader32.MinorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader32.MajorImageVersion = binReader.ReadUInt16(); this.optinalHeader32.MinorImageVersion = binReader.ReadUInt16(); this.optinalHeader32.MajorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader32.MinorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader32.Win32VersionValue = binReader.ReadUInt32(); this.optinalHeader32.SizeOfImage = binReader.ReadUInt32(); this.optinalHeader32.SizeOfHeaders = binReader.ReadUInt32(); this.optinalHeader32.CheckSum = binReader.ReadUInt32(); this.optinalHeader32.Subsystem = binReader.ReadUInt16(); this.optinalHeader32.DllCharacteristics = binReader.ReadUInt16(); this.optinalHeader32.SizeOfStackReserve = binReader.ReadUInt32(); this.optinalHeader32.SizeOfStackCommit = binReader.ReadUInt32(); this.optinalHeader32.SizeOfHeapReserve = binReader.ReadUInt32(); this.optinalHeader32.SizeOfHeapCommit = binReader.ReadUInt32(); this.optinalHeader32.LoaderFlags = binReader.ReadUInt32(); this.optinalHeader32.NumberOfRvaAndSizes = binReader.ReadUInt32(); } // Read the IMAGE_OPTIONAL_HEADER64 for 64bit application. else { this.Is32bitImage = false; this.optinalHeader64.Magic = magic; this.optinalHeader64.MajorLinkerVersion = binReader.ReadByte(); this.optinalHeader64.MinorImageVersion = binReader.ReadByte(); this.optinalHeader64.SizeOfCode = binReader.ReadUInt32(); this.optinalHeader64.SizeOfInitializedData = binReader.ReadUInt32(); this.optinalHeader64.SizeOfUninitializedData = binReader.ReadUInt32(); this.optinalHeader64.AddressOfEntryPoint = binReader.ReadUInt32(); this.optinalHeader64.BaseOfCode = binReader.ReadUInt32(); this.optinalHeader64.ImageBase = binReader.ReadUInt64(); this.optinalHeader64.SectionAlignment = binReader.ReadUInt32(); this.optinalHeader64.FileAlignment = binReader.ReadUInt32(); this.optinalHeader64.MajorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader64.MinorOperatingSystemVersion = binReader.ReadUInt16(); this.optinalHeader64.MajorImageVersion = binReader.ReadUInt16(); this.optinalHeader64.MinorImageVersion = binReader.ReadUInt16(); this.optinalHeader64.MajorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader64.MinorSubsystemVersion = binReader.ReadUInt16(); this.optinalHeader64.Win32VersionValue = binReader.ReadUInt32(); this.optinalHeader64.SizeOfImage = binReader.ReadUInt32(); this.optinalHeader64.SizeOfHeaders = binReader.ReadUInt32(); this.optinalHeader64.CheckSum = binReader.ReadUInt32(); this.optinalHeader64.Subsystem = binReader.ReadUInt16(); this.optinalHeader64.DllCharacteristics = binReader.ReadUInt16(); this.optinalHeader64.SizeOfStackReserve = binReader.ReadUInt64(); this.optinalHeader64.SizeOfStackCommit = binReader.ReadUInt64(); this.optinalHeader64.SizeOfHeapReserve = binReader.ReadUInt64(); this.optinalHeader64.SizeOfHeapCommit = binReader.ReadUInt64(); this.optinalHeader64.LoaderFlags = binReader.ReadUInt32(); this.optinalHeader64.NumberOfRvaAndSizes = binReader.ReadUInt32(); } // Read the data directories. this.directoryValues = new IMAGE.IMAGE_DATA_DIRECTORY_Values(); for (int i = 0; i < 16; i++) { directoryValues.Values[i].VirtualAddress = binReader.ReadUInt32(); directoryValues.Values[i].Size = binReader.ReadUInt32(); } } finally { // Release the IO resource. if (binReader != null) { binReader.Close(); } if (fs != null) { fs.Close(); } } }