/// <summary> /// Process a PE executable header /// </summary> private ExecutableType ProcessPe(ref bool searchAgainAtEnd) { inputFile.Seek(dataBase + currentFormat.ExecutableOffset + 4); IMAGE_FILE_HEADER ifh = IMAGE_FILE_HEADER.Deserialize(inputFile); IMAGE_OPTIONAL_HEADER ioh = IMAGE_OPTIONAL_HEADER.Deserialize(inputFile); // Read sections until we have the ones we need IMAGE_SECTION_HEADER temp = null; IMAGE_SECTION_HEADER resource = null; for (int i = 0; i < ifh.NumberOfSections; i++) { IMAGE_SECTION_HEADER sectionHeader = IMAGE_SECTION_HEADER.Deserialize(inputFile); string headerName = Encoding.ASCII.GetString(sectionHeader.Name, 0, 8); // .text if (headerName.StartsWith(".text")) { currentFormat.CodeSectionLength = sectionHeader.VirtualSize; } // .rdata else if (headerName.StartsWith(".rdata")) { // No-op } // .data else if (headerName.StartsWith(".data")) { currentFormat.DataSectionLength = sectionHeader.VirtualSize; if ((ifh.Characteristics & (1 << 0)) == 0) { temp = sectionHeader; } } // .rsrc else if (headerName.StartsWith(".rsrc")) { resource = sectionHeader; if ((ifh.Characteristics & (1 << 0)) != 0) { temp = sectionHeader; } } } // the unpacker of the self-extractor does not use any resource functions either. if (temp.SizeOfRawData > 20000) { for (int f = 0; f <= 20000 - 0x80; f++) { inputFile.Seek(dataBase + temp.PointerToRawData + f); IMAGE_DOS_HEADER exeHdr = IMAGE_DOS_HEADER.Deserialize(inputFile); if ((exeHdr.Magic == Constants.IMAGE_NT_SIGNATURE || exeHdr.Magic == Constants.IMAGE_DOS_SIGNATURE) && exeHdr.HeaderParagraphSize >= 4 && exeHdr.NewExeHeaderAddr >= 0x40 && (exeHdr.Relocations == 0 || exeHdr.Relocations == 3)) { currentFormat.ExecutableOffset = (int)temp.PointerToRawData + f; fileEnd = (int)(dataBase + temp.PointerToRawData + ioh.DataDirectory[2].Size); searchAgainAtEnd = true; break; } } } currentFormat.ExecutableOffset = (int)(resource.PointerToRawData + resource.SizeOfRawData); return(ExecutableType.PE); }