public void Deserialize(Stream input) { this.DosHeader = input.ReadStructure <Image.DosHeader>(); if (this.DosHeader.Magic != 0x5A4D) // MZ { throw new FormatException("dos header has bad magic"); } input.Seek(this.DosHeader.NewExeOffset, SeekOrigin.Begin); this.NTHeaders32 = input.ReadStructure <Image.NTHeaders32>(); if (this.NTHeaders32.Signature != 0x4550 || this.NTHeaders32.FileHeader.SizeOfOptionalHeader != 0xE0) // PE { throw new FormatException("nt header has bad signature"); } else if (this.NTHeaders32.OptionalHeader.Magic != 0x10B) // IMAGE_NT_OPTIONAL_HDR32_MAGIC { throw new FormatException("optional header has bad magic"); } this.Directories = new List <Image.DataDirectory>(); for (int i = 0; i < this.NTHeaders32.OptionalHeader.NumberOfRvaAndSizes; i++) { this.Directories.Add(input.ReadStructure <Image.DataDirectory>()); } this.Sections = new List <Image.SectionHeader>(); for (int i = 0; i < this.NTHeaders32.FileHeader.NumberOfSections; i++) { this.Sections.Add(input.ReadStructure <Image.SectionHeader>()); } this.Exports = new Dictionary <UInt32, UInt32>(); this.ExportNames = new Dictionary <string, UInt32>(); if ( this.Directories.Count >= 1 && this.Directories[0].VirtualAddress != 0 && this.Directories[0].Size != 0) { var fileOffset = this.GetFileOffset(this.Directories[0].VirtualAddress, true); input.Seek(fileOffset, SeekOrigin.Begin); Image.ExportDirectory exportDirectory = input.ReadStructure <Image.ExportDirectory>(); if (exportDirectory.NumberOfNames > 0) { var nameOffsets = new UInt32[exportDirectory.NumberOfNames]; var names = new string[exportDirectory.NumberOfNames]; var ordinals = new UInt16[exportDirectory.NumberOfNames]; input.Seek(this.GetFileOffset(exportDirectory.AddressOfNames, true), SeekOrigin.Begin); for (uint i = 0; i < exportDirectory.NumberOfNames; i++) { nameOffsets[i] = input.ReadValueU32(); } input.Seek(this.GetFileOffset(exportDirectory.AddressOfNameOrdinals, true), SeekOrigin.Begin); for (uint i = 0; i < exportDirectory.NumberOfNames; i++) { ordinals[i] = input.ReadValueU16(); } for (uint i = 0; i < exportDirectory.NumberOfNames; i++) { input.Seek(this.GetFileOffset(nameOffsets[i], true), SeekOrigin.Begin); var name = input.ReadStringZ(Encoding.ASCII); this.ExportNames.Add(name, exportDirectory.Base + ordinals[i]); } } if (exportDirectory.NumberOfFunctions > 0) { input.Seek(this.GetFileOffset(exportDirectory.AddressOfFunctions, true), SeekOrigin.Begin); for (uint i = 0; i < exportDirectory.NumberOfFunctions; i++) { var address = input.ReadValueU32(); if (address == 0) { continue; } this.Exports.Add(exportDirectory.Base + i, address); } } } }
public void Deserialize(Stream input) { this.DosHeader = input.ReadStructure<Image.DosHeader>(); if (this.DosHeader.Magic != 0x5A4D) // MZ { throw new FormatException("dos header has bad magic"); } input.Seek(this.DosHeader.NewExeOffset, SeekOrigin.Begin); this.NTHeaders32 = input.ReadStructure<Image.NTHeaders32>(); if (this.NTHeaders32.Signature != 0x4550 || this.NTHeaders32.FileHeader.SizeOfOptionalHeader != 0xE0) // PE { throw new FormatException("nt header has bad signature"); } else if (this.NTHeaders32.OptionalHeader.Magic != 0x10B) // IMAGE_NT_OPTIONAL_HDR32_MAGIC { throw new FormatException("optional header has bad magic"); } this.Directories = new List<Image.DataDirectory>(); for (int i = 0; i < this.NTHeaders32.OptionalHeader.NumberOfRvaAndSizes; i++) { this.Directories.Add(input.ReadStructure<Image.DataDirectory>()); } this.Sections = new List<Image.SectionHeader>(); for (int i = 0; i < this.NTHeaders32.FileHeader.NumberOfSections; i++) { this.Sections.Add(input.ReadStructure<Image.SectionHeader>()); } this.Exports = new Dictionary<UInt32, UInt32>(); this.ExportNames = new Dictionary<string, UInt32>(); if ( this.Directories.Count >= 1 && this.Directories[0].VirtualAddress != 0 && this.Directories[0].Size != 0) { var fileOffset = this.GetFileOffset(this.Directories[0].VirtualAddress, true); input.Seek(fileOffset, SeekOrigin.Begin); Image.ExportDirectory exportDirectory = input.ReadStructure<Image.ExportDirectory>(); if (exportDirectory.NumberOfNames > 0) { var nameOffsets = new UInt32[exportDirectory.NumberOfNames]; var names = new string[exportDirectory.NumberOfNames]; var ordinals = new UInt16[exportDirectory.NumberOfNames]; input.Seek(this.GetFileOffset(exportDirectory.AddressOfNames, true), SeekOrigin.Begin); for (uint i = 0; i < exportDirectory.NumberOfNames; i++) { nameOffsets[i] = input.ReadValueU32(); } input.Seek(this.GetFileOffset(exportDirectory.AddressOfNameOrdinals, true), SeekOrigin.Begin); for (uint i = 0; i < exportDirectory.NumberOfNames; i++) { ordinals[i] = input.ReadValueU16(); } for (uint i = 0; i < exportDirectory.NumberOfNames; i++) { input.Seek(this.GetFileOffset(nameOffsets[i], true), SeekOrigin.Begin); var name = input.ReadStringZ(Encoding.ASCII); this.ExportNames.Add(name, exportDirectory.Base + ordinals[i]); } } if (exportDirectory.NumberOfFunctions > 0) { input.Seek(this.GetFileOffset(exportDirectory.AddressOfFunctions, true), SeekOrigin.Begin); for (uint i = 0; i < exportDirectory.NumberOfFunctions; i++) { var address = input.ReadValueU32(); if (address == 0) { continue; } this.Exports.Add(exportDirectory.Base + i, address); } } } }