public Image_Resource_Directory_Entry(byte[] buff, int offset, PEFileInfo fileInfo, long rootOffset) { NameString = null; ChildEntry = null; Name = (0xffffffff & buff[offset]) + ((0xffffffff & buff[offset + 1]) << 8) + ((0xffffffff & buff[offset + 2]) << 16) + ((0xffffffff & buff[offset + 3]) << 24); OffsetToData = (0xffffffff & buff[offset + 4]) + ((0xffffffff & buff[offset + 5]) << 8) + ((0xffffffff & buff[offset + 6]) << 16) + ((0xffffffff & buff[offset + 7]) << 24); if ((Name >> 31) == 1) //最高位为1 { long nameOffset = Name & 0x7fffffff; NameString = new IMAGE_RESOURCE_DIR_STRING_U(fileInfo.pFileStream, nameOffset, rootOffset); } if ((OffsetToData >> 31) == 1) { long entryOffset = rootOffset + (OffsetToData & 0x7fffffff); ChildEntry = new Image_Resource_Directory(fileInfo, entryOffset, rootOffset); } else { byte[] buffData = new byte[16]; fileInfo.pFileStream.Position = rootOffset + OffsetToData; int len = fileInfo.pFileStream.Read(buffData, 0, 16); ChildEntry = new Image_Resource_Data_Entry(buffData, fileInfo, rootOffset); } }
public Image_Resource_Directory_Entry(byte[] buff, int offset, PEFileInfo fileInfo, long rootOffset, int level, int resType, int id, int language) { NameString = null; ChildEntry = null; Name = (0xffffffff & buff[offset]) + ((0xffffffff & buff[offset + 1]) << 8) + ((0xffffffff & buff[offset + 2]) << 16) + ((0xffffffff & buff[offset + 3]) << 24); OffsetToData = (0xffffffff & buff[offset + 4]) + ((0xffffffff & buff[offset + 5]) << 8) + ((0xffffffff & buff[offset + 6]) << 16) + ((0xffffffff & buff[offset + 7]) << 24); if ((Name >> 31) == 1) //最高位为1 { long nameOffset = Name & 0x7fffffff; NameString = new IMAGE_RESOURCE_DIR_STRING_U(fileInfo.pFileStream, nameOffset, rootOffset); } else { if (level == 0) // 第一层的ID表示资源类型 { resType = (int)Name; } else if (level == 1) // 第二层的ID表示资源ID { id = (int)Name; } else if (level == 2) // 第三层的ID表示语言类型 { language = (int)Name; } } if ((OffsetToData >> 31) == 1) { long entryOffset = rootOffset + (OffsetToData & 0x7fffffff); ChildEntry = new Image_Resource_Directory(fileInfo, entryOffset, rootOffset, level + 1, resType, id, language); } else { byte[] buffData = new byte[16]; fileInfo.pFileStream.Position = rootOffset + OffsetToData; int len = fileInfo.pFileStream.Read(buffData, 0, 16); ChildEntry = new Image_Resource_Data_Entry(buffData, fileInfo, rootOffset, resType, id, language); } }
public Cursor_Direntry(byte[] buff, int offset, PEFileInfo peFile) { Width = buff[offset]; Height = buff[offset + 1]; ColorCount = buff[offset + 2]; Reserved = buff[offset + 3]; HotspotX = (UInt16)(((0xffff & buff[offset + 5]) << 8) + buff[offset + 4]); HotspotY = (UInt16)(((0xffff & buff[offset + 7]) << 8) + buff[offset + 6]); BytesInRes = (0xffffffff & buff[offset + 8]) + ((0xffffffff & buff[offset + 9]) << 8) + ((0xffffffff & buff[offset + 10]) << 16) + ((0xffffffff & buff[offset + 11]) << 24); ImageOffset = (0xffffffff & buff[offset + 12]) + ((0xffffffff & buff[offset + 13]) << 8) + ((0xffffffff & buff[offset + 14]) << 16) + ((0xffffffff & buff[offset + 15]) << 24); }
public Image_Resource_Directory(PEFileInfo fileInfo, long offset, long rootOffset) { byte[] buff = new byte[16]; fileInfo.pFileStream.Position = offset; int len = fileInfo.pFileStream.Read(buff, 0, 16); // 获取Directory的成员 Characteristics = (0xffffffff & buff[0]) + ((0xffffffff & buff[1]) << 8) + ((0xffffffff & buff[2]) << 16) + ((0xffffffff & buff[3]) << 24); TimeDateStamp = (0xffffffff & buff[4]) + ((0xffffffff & buff[5]) << 8) + ((0xffffffff & buff[6]) << 16) + ((0xffffffff & buff[7]) << 24); MajorVersion = (UInt16)(((0xffff & buff[9]) << 8) + buff[8]); MinorVersion = (UInt16)(((0xffff & buff[11]) << 8) + buff[10]); NumberOfNamedEntries = (UInt16)(((0xffff & buff[13]) << 8) + buff[12]); NumberOfIdEntries = (UInt16)(((0xffff & buff[15]) << 8) + buff[14]); // 获取后面的所有Entry //long currentCurrsor = offset + 16; int entryCount = 0; if (NumberOfNamedEntries > 0) { entryCount += NumberOfNamedEntries; } if (NumberOfIdEntries > 0) { entryCount += NumberOfIdEntries; } ImageResourceDirectoryEntries = new Image_Resource_Directory_Entry[entryCount]; if (entryCount > 0) { buff = new byte[8 * entryCount]; len = fileInfo.pFileStream.Read(buff, 0, 8 * entryCount); for (int i = 0; i < entryCount; i++) { ImageResourceDirectoryEntries[i] = new Image_Resource_Directory_Entry(buff, 8 * i, fileInfo, rootOffset); } } }
public Cursor_Direntry[] CursorDirectories; // 数组长度由CDCount决定 public RT_Cursor_Header(byte[] buff, PEFileInfo peFile) { CursorDirectories = null; CDReserved = (UInt16)(((0xffff & buff[1]) << 8) + buff[0]); CDType = (UInt16)(((0xffff & buff[3]) << 8) + buff[2]); CDCount = (UInt16)(((0xffff & buff[5]) << 8) + buff[4]); if (CDCount > 0) { CursorDirectories = new Cursor_Direntry[CDCount]; } int offset = 0; for (int i = 0; i < CDCount; i++) { offset = i * 16; CursorDirectories[i] = new Cursor_Direntry(buff, offset, peFile); } }
private UInt16 Architecture; // 0x20b is 64bit; public IMAGE_IMPORT_DESCRIPTOR(byte[] buff, PEFileInfo fileInfo) { Architecture = fileInfo.Architecture; Sinature = (0xffffffff & buff[0]) + ((0xffffffff & buff[1]) << 8) + ((0xffffffff & buff[2]) << 16) + ((0xffffffff & buff[3]) << 24); FileHeader = new IMAGE_FILE_HEADER(buff, 4); if (Architecture != 0x20B) { IMAGE_OPTIONAL_HEADER op = new IMAGE_OPTIONAL_HEADER(buff, 24); fileInfo.ImageBase = op.ImageBase; OptionalHeader = op; } else { IMAGE_OPTIONAL_HEADER_X64 op = new IMAGE_OPTIONAL_HEADER_X64(buff, 24); fileInfo.ImageBase = op.ImageBase; OptionalHeader = op; } }
public Image_Resource_Data_Entry(byte[] buff, PEFileInfo fileInfo, long rootOffset) { OffsetToData = (0xffffffff & buff[0]) + ((0xffffffff & buff[1]) << 8) + ((0xffffffff & buff[2]) << 16) + ((0xffffffff & buff[3]) << 24); Size = (0xffffffff & buff[4]) + ((0xffffffff & buff[5]) << 8) + ((0xffffffff & buff[6]) << 16) + ((0xffffffff & buff[7]) << 24); CodePage = (0xffffffff & buff[8]) + ((0xffffffff & buff[9]) << 8) + ((0xffffffff & buff[10]) << 16) + ((0xffffffff & buff[11]) << 24); Reversed = (0xffffffff & buff[12]) + ((0xffffffff & buff[13]) << 8) + ((0xffffffff & buff[14]) << 16) + ((0xffffffff & buff[15]) << 24); fileInfo.pFileStream.Position = rootOffset + OffsetToData - fileInfo.SectionVirtualAddress; Data = new byte[Size]; int len = fileInfo.pFileStream.Read(Data, 0, (int)Size); }
public Image_Resource_Data_Entry(byte[] buff, PEFileInfo fileInfo, long rootOffset, int resType, int id, int language) { Type = resType; ID = id; Language = language; OffsetToData = (0xffffffff & buff[0]) + ((0xffffffff & buff[1]) << 8) + ((0xffffffff & buff[2]) << 16) + ((0xffffffff & buff[3]) << 24); Size = (0xffffffff & buff[4]) + ((0xffffffff & buff[5]) << 8) + ((0xffffffff & buff[6]) << 16) + ((0xffffffff & buff[7]) << 24); CodePage = (0xffffffff & buff[8]) + ((0xffffffff & buff[9]) << 8) + ((0xffffffff & buff[10]) << 16) + ((0xffffffff & buff[11]) << 24); Reversed = (0xffffffff & buff[12]) + ((0xffffffff & buff[13]) << 8) + ((0xffffffff & buff[14]) << 16) + ((0xffffffff & buff[15]) << 24); fileInfo.pFileStream.Position = rootOffset + OffsetToData - fileInfo.SectionVirtualAddress; Data = new byte[Size]; int len = fileInfo.pFileStream.Read(Data, 0, (int)Size); switch (resType) { case 1: // 光标 { byte[] resHeader = new byte[16]; fileInfo.pFileStream.Position = rootOffset; len = fileInfo.pFileStream.Read(resHeader, 0, 16); int entryNumber = (Int32)(((0xffff & resHeader[13]) << 8) + resHeader[12]) + (Int32)(((0xffff & resHeader[15]) << 8) + resHeader[14]); byte[] entries = new byte[8 * entryNumber]; len = fileInfo.pFileStream.Read(entries, 0, 8 * entryNumber); UInt32 address = 0; for (int i = 0; i < entryNumber; i++) { UInt32 name = (0xffffffff & entries[8 * i]) + ((0xffffffff & entries[8 * i + 1]) << 8) + ((0xffffffff & entries[8 * i + 2]) << 16) + ((0xffffffff & entries[8 * i + 3]) << 24); if (name == 12) { address = (0xffffffff & entries[8 * i + 4]) + ((0xffffffff & entries[8 * i + 5]) << 8) + ((0xffffffff & entries[8 * i + 6]) << 16) + ((0xffffffff & entries[8 * i + 7]) << 24); break; } } Image_Resource_Directory iRD = new Image_Resource_Directory(fileInfo, (address & 0x7fffffff) + rootOffset, rootOffset, 1, 12, 0, 0); Instance = new IMAGE_CURSOR(Data, iRD, ID); break; } case 3: // 图标 { byte[] resHeader = new byte[16]; fileInfo.pFileStream.Position = rootOffset; len = fileInfo.pFileStream.Read(resHeader, 0, 16); int entryNumber = (Int32)(((0xffff & resHeader[13]) << 8) + resHeader[12]) + (Int32)(((0xffff & resHeader[15]) << 8) + resHeader[14]); byte[] entries = new byte[8 * entryNumber]; len = fileInfo.pFileStream.Read(entries, 0, 8 * entryNumber); UInt32 address = 0; for (int i = 0; i < entryNumber; i++) { UInt32 name = (0xffffffff & entries[8 * i]) + ((0xffffffff & entries[8 * i + 1]) << 8) + ((0xffffffff & entries[8 * i + 2]) << 16) + ((0xffffffff & entries[8 * i + 3]) << 24); if (name == 14) { address = (0xffffffff & entries[8 * i + 4]) + ((0xffffffff & entries[8 * i + 5]) << 8) + ((0xffffffff & entries[8 * i + 6]) << 16) + ((0xffffffff & entries[8 * i + 7]) << 24); break; } } Image_Resource_Directory iRD = new Image_Resource_Directory(fileInfo, rootOffset + (address & 0x7fffffff), rootOffset, 1, 14, 0, 0); Instance = new IMAGE_ICON(Data, iRD, ID); break; } case 12: // 组光标 { Instance = new GROUP_CURSOR(Data); break; } case 14: // 组图标 { Instance = new GROUP_ICON(Data); break; } default: { Instance = null; break; } } }
public Section(string name, PEFileInfo fileInfo, long offset) { Name = name; FileOffset = offset; string cmpName = name.ToLower(); if (cmpName == ".bss") { } else if (cmpName == ".cormeta") { } else if (cmpName == ".data") { } else if (cmpName == ".debug$f") { } else if (cmpName == ".debug$p") { } else if (cmpName == ".debug$s") { } else if (cmpName == ".debug$t") { } else if (cmpName == ".drectve") { } else if (cmpName == ".edata") { } else if (cmpName == ".idata") { } else if (cmpName == ".idlsym") { } else if (cmpName == ".pdata") { } else if (cmpName == ".rdata") { } else if (cmpName == ".reloc") { } else if (cmpName == ".rsrc") { SectionInstance = new Image_Resource_Directory(fileInfo, offset, offset, 0, 0, 0, 0); // 根节点的offset和和段的文件偏移相同 } else if (cmpName == ".sbss") { } else if (cmpName == ".sdata") { } else if (cmpName == ".srdata") { } else if (cmpName == ".sxdata") { } else if (cmpName == ".text") { } else if (cmpName == ".tls") { } else if (cmpName == ".tls$") { } else if (cmpName == ".vsdata") { } else if (cmpName == ".xdata") { } }
public PEFile(string fileName) { if (File.Exists(fileName)) { long streamCurrsor = 0; FileName = fileName; pFileStream = File.Open(fileName, FileMode.Open, FileAccess.Read); FileSize = pFileStream.Length; FileExtenstion = fileName.Substring(fileName.LastIndexOf('.')); if (!FileExtenstion.ToLower().Equals(".exe") && !FileExtenstion.ToLower().Equals(".dll") && !FileExtenstion.ToLower().Equals(".sys") && !FileExtenstion.ToLower().Equals(".ocx") && !FileExtenstion.ToLower().Equals(".com")) { throw new ArgumentException("Not supported file extension."); } PeFileInfo = new PEFileInfo(); PeFileInfo.pFileStream = pFileStream; PeFileInfo.FileType = FileExtenstion; //检查是否有DOS MZ头部 byte[] buff = new byte[2]; int len = pFileStream.Read(buff, 0, 2); if ((buff[0] != 'M') && (buff[1] != 'Z')) { HasDOSMZHeader = false; } // 获取 Image_Dos_Header pFileStream.Position = 0; if (HasDOSMZHeader) { buff = new byte[64]; len = pFileStream.Read(buff, 0, 64); ImageDosHeader = new IMAGE_DOS_HEADER(buff); // 获取 REAL_MODE_PROGRAM int length = (int)ImageDosHeader.e_lfanew - 64; buff = new byte[length]; len = pFileStream.Read(buff, 0, length); RealModeProgram = new REAL_MODE_PROGRAM(buff, length); // 根据是否有MZ头定位文件头起始位置 pFileStream.Position = ImageDosHeader.e_lfanew; } // 检查是否有PE标志 buff = new byte[4]; len = pFileStream.Read(buff, 0, 4); pFileStream.Position -= 4; if ((buff[0] != 'P') && (buff[1] != 'E') && (buff[2] != 0) && (buff[3] != 0)) { throw new FormatException("Target file is not PE file."); } streamCurrsor = pFileStream.Position; // 检测镜像是64位还是32位 buff = new byte[2]; pFileStream.Position += 24; len = pFileStream.Read(buff, 0, 2); Architecture = (UInt16)(((0xffff & buff[1]) << 8) + buff[0]); PeFileInfo.Architecture = Architecture; // 获取 IMAGE_IMPORT_DESCRIPTOR pFileStream.Position = streamCurrsor; // 因为Optional Header的长度,在64位文件中比32位多16字节 if (Architecture == 0x20b) { buff = new byte[264]; len = pFileStream.Read(buff, 0, 264); } else if (Architecture == 0x10b) { buff = new byte[248]; len = pFileStream.Read(buff, 0, 248); } else { throw new FormatException("Not supported image file architecture."); } ImageImportDescriptor = new IMAGE_IMPORT_DESCRIPTOR(buff, PeFileInfo); // 获取 IMAGE_SECTION_HEADER pSectionCount = ImageImportDescriptor.FileHeader.NumberOfSections; Sections = new Section[pSectionCount]; if (pSectionCount > 0) { ImageSectionHeaders = new IMAGE_SECTION_HEADER[pSectionCount]; //记录SectionHeader开始处位置 streamCurrsor = pFileStream.Position; buff = new byte[40]; for (int i = 0; i < pSectionCount; i++) { //实例化段数据会改变Stream光标位置,因此每次循环需要重设光标位置 pFileStream.Position = streamCurrsor + i * 40; len = pFileStream.Read(buff, 0, 40); ImageSectionHeaders[i] = new IMAGE_SECTION_HEADER(buff); //实例化各个段内容,注意,此后需要重定位pFileStream的Position属性。 PeFileInfo.SectionVirtualAddress = ImageSectionHeaders[i].VirtualAddress; Sections[i] = new Section(ImageSectionHeaders[i].GetName(), PeFileInfo, ImageSectionHeaders[i].PointerToRawData); } } } }