private void ReadStringTable(BinaryReader reader, uint offset, uint rsrcStart) { reader.BaseStream.Seek((long)((offset & 0x7FFFFFFF) + rsrcStart), SeekOrigin.Begin); IMAGE_RESOURCE_DIRECTORY rootDir = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> (); int num = (int)(rootDir.NumberOfIdEntries + rootDir.NumberOfNamedEntries); IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries = new IMAGE_RESOURCE_DIRECTORY_ENTRY[num]; for (int i = 0; i < num; i++) { entries [i] = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> (); } for (int i = 0; i < num; i++) { uint dirOffset = entries [i].OffsetToData & 0x7FFFFFFF; reader.BaseStream.Seek((long)(dirOffset + rsrcStart), SeekOrigin.Begin); reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> (); IMAGE_RESOURCE_DIRECTORY_ENTRY languageEntry = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> (); reader.BaseStream.Seek((long)(languageEntry.OffsetToData + rsrcStart), SeekOrigin.Begin); IMAGE_RESOURCE_DATA_ENTRY dataEntry = reader.ReadStruct <IMAGE_RESOURCE_DATA_ENTRY> (); reader.BaseStream.Seek((long)dataEntry.OffsetToData, SeekOrigin.Begin); int blockId = (int)((entries [i].Name - 1u) * 16); for (int j = 0; j < 16; j++) { int length = (int)(reader.ReadUInt16() * 2); if (length != 0) { byte[] bytes = reader.ReadBytes(length); string str = Encoding.Unicode.GetString(bytes); Strings.Add(blockId + j, str); } } } }
private void ReadXML(BinaryReader reader, uint offset, uint rsrcStart) { reader.BaseStream.Seek((long)((offset & 0x7FFFFFFF) + rsrcStart), SeekOrigin.Begin); IMAGE_RESOURCE_DIRECTORY rootDir = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> (); int num = (int)(rootDir.NumberOfIdEntries + rootDir.NumberOfNamedEntries); IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries = new IMAGE_RESOURCE_DIRECTORY_ENTRY[num]; for (int i = 0; i < num; i++) { entries [i] = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> (); } for (int j = 0; j < num; j++) { uint dirOffset = entries [j].OffsetToData & 0x7FFFFFFF; reader.BaseStream.Seek((long)(dirOffset + rsrcStart), SeekOrigin.Begin); reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY> (); IMAGE_RESOURCE_DIRECTORY_ENTRY languageEntry = reader.ReadStruct <IMAGE_RESOURCE_DIRECTORY_ENTRY> (); reader.BaseStream.Seek((long)(languageEntry.OffsetToData + rsrcStart), SeekOrigin.Begin); IMAGE_RESOURCE_DATA_ENTRY dataEntry = reader.ReadStruct <IMAGE_RESOURCE_DATA_ENTRY> (); reader.BaseStream.Seek((long)dataEntry.OffsetToData, SeekOrigin.Begin); byte[] xmlBytes = reader.ReadBytes((int)dataEntry.Size); int idx = 0; int count = xmlBytes.Length; if (xmlBytes[0] == 0xFF && xmlBytes[1] == 0xFE) //Skip BOM { idx = 2; count -= 2; } try { Infocards.Add((int)entries [j].Name, Encoding.Unicode.GetString(xmlBytes, idx, count)); } catch (Exception) { FLLog.Error("Infocards", "Infocard Corrupt: " + entries[j].Name); } } }
private void ReadResourceData(BlobReader resourceReader, PEReader peFile, Func <object, object, ushort, bool> resourceFilter) { DoResourceDirectoryRead(resourceReader, 0, ProcessOuterResource); return; void ProcessOuterResource(object typeName, uint offset, bool isTypeDictionaryEntry) { if (!isTypeDictionaryEntry) { throw new ArgumentException(); } DoResourceDirectoryRead(resourceReader, offset, ProcessNameList); return; void ProcessNameList(object name, uint offsetOfLanguageList, bool isNameListDictionaryEntry) { if (!isNameListDictionaryEntry) { throw new ArgumentException(); } DoResourceDirectoryRead(resourceReader, offsetOfLanguageList, ProcessLanguageList); return; void ProcessLanguageList(object languageName, uint offsetOfLanguageListEntry, bool isLanguageListEntryIsDictionaryEntry) { if (languageName is string) { throw new ArgumentException(); } if (isLanguageListEntryIsDictionaryEntry) { throw new ArgumentException(); } resourceReader.Offset = checked ((int)offsetOfLanguageListEntry); IMAGE_RESOURCE_DATA_ENTRY resourceData = new IMAGE_RESOURCE_DATA_ENTRY(ref resourceReader); // The actual resource data offset is relative to the start address of the file BlobReader resourceDataBlob = peFile.GetSectionData(checked ((int)resourceData.OffsetToData)).GetReader(0, checked ((int)resourceData.Size)); byte[] data = resourceDataBlob.ReadBytes((int)resourceData.Size); if (resourceFilter != null) { // If the filter returns false, don't add this resource to the model if (!resourceFilter(typeName, name, (ushort)languageName)) { return; } } AddResource(typeName, name, (ushort)languageName, data); } } } }
public void ImageResourceDataEntryConstructorWorks_Test() { var resourceDataEntry = new IMAGE_RESOURCE_DATA_ENTRY(RawStructures.RawResourceDataEntry, 2); Assert.Equal((uint)0x33221100, resourceDataEntry.OffsetToData); Assert.Equal((uint)0x77665544, resourceDataEntry.Size1); Assert.Equal(0xbbaa9988, resourceDataEntry.CodePage); Assert.Equal(0xffeeddcc, resourceDataEntry.Reserved); }
public static IMAGE_RESOURCE_DATA_ENTRY Deserialize(MultiPartFile file) { IMAGE_RESOURCE_DATA_ENTRY irde = new IMAGE_RESOURCE_DATA_ENTRY(); irde.OffsetToData = file.ReadUInt32(); irde.Size = file.ReadUInt32(); irde.CodePage = file.ReadUInt32(); irde.Reserved = file.ReadUInt32(); return(irde); }
public ResourceDataEntry(Stream stream, long rsrcSectionRVA, long rsrcSectionPA) { using (var br = new BinaryReader(stream, Encoding.Default, true)) { //read struct and record position entry = br.ReadStruct <IMAGE_RESOURCE_DATA_ENTRY>(); var temp = Encoding.GetEncoding((int)entry.Codepage); #if COVERAGE_TEST && USE_SIZE RemoveBack(br.BaseStream.Position, entry.GetType()); #endif var pos = br.BaseStream.Position; //go to the actual data and read it br.BaseStream.Seek(rsrcSectionPA + entry.DataRVA - rsrcSectionRVA, SeekOrigin.Begin); data = br.ReadBytes(entry.Size); #if COVERAGE_TEST && USE_SIZE RemoveBack(br.BaseStream.Position, data.Length); #endif //jump back br.BaseStream.Position = pos; } }
public void WriteResources(ISymbolNode nodeAssociatedWithDataBuilder, ref ObjectDataBuilder dataBuilder) { Debug.Assert(dataBuilder.CountBytes == 0); SortedDictionary <string, List <ObjectDataBuilder.Reservation> > nameTable = new SortedDictionary <string, List <ObjectDataBuilder.Reservation> >(); Dictionary <ResLanguage, int> dataEntryTable = new Dictionary <ResLanguage, int>(); List <Tuple <ResType, ObjectDataBuilder.Reservation> > resTypes = new List <Tuple <ResType, ObjectDataBuilder.Reservation> >(); List <Tuple <ResName, ObjectDataBuilder.Reservation> > resNames = new List <Tuple <ResName, ObjectDataBuilder.Reservation> >(); List <Tuple <ResLanguage, ObjectDataBuilder.Reservation> > resLanguages = new List <Tuple <ResLanguage, ObjectDataBuilder.Reservation> >(); IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, checked ((ushort)_resTypeHeadName.Count), checked ((ushort)_resTypeHeadID.Count)); foreach (KeyValuePair <string, ResType> res in _resTypeHeadName) { resTypes.Add(new Tuple <ResType, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key, nameTable))); } foreach (KeyValuePair <ushort, ResType> res in _resTypeHeadID) { resTypes.Add(new Tuple <ResType, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key))); } foreach (Tuple <ResType, ObjectDataBuilder.Reservation> type in resTypes) { dataBuilder.EmitUInt(type.Item2, (uint)dataBuilder.CountBytes | 0x80000000); IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, checked ((ushort)type.Item1.NameHeadName.Count), checked ((ushort)type.Item1.NameHeadID.Count)); foreach (KeyValuePair <string, ResName> res in type.Item1.NameHeadName) { resNames.Add(new Tuple <ResName, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key, nameTable))); } foreach (KeyValuePair <ushort, ResName> res in type.Item1.NameHeadID) { resNames.Add(new Tuple <ResName, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key))); } } foreach (Tuple <ResName, ObjectDataBuilder.Reservation> type in resNames) { dataBuilder.EmitUInt(type.Item2, (uint)dataBuilder.CountBytes | 0x80000000); IMAGE_RESOURCE_DIRECTORY.Write(ref dataBuilder, 0, checked ((ushort)type.Item1.Languages.Count)); foreach (KeyValuePair <ushort, ResLanguage> res in type.Item1.Languages) { resLanguages.Add(new Tuple <ResLanguage, ObjectDataBuilder.Reservation>(res.Value, IMAGE_RESOURCE_DIRECTORY_ENTRY.Write(ref dataBuilder, res.Key))); } } // Emit name table dataBuilder.PadAlignment(2); // name table is 2 byte aligned foreach (KeyValuePair <string, List <ObjectDataBuilder.Reservation> > name in nameTable) { foreach (ObjectDataBuilder.Reservation reservation in name.Value) { dataBuilder.EmitUInt(reservation, (uint)dataBuilder.CountBytes | 0x80000000); } dataBuilder.EmitUShort(checked ((ushort)name.Key.Length)); foreach (char c in name.Key) { dataBuilder.EmitUShort((ushort)c); } } // Emit byte arrays of resource data, capture the offsets foreach (Tuple <ResLanguage, ObjectDataBuilder.Reservation> language in resLanguages) { dataBuilder.PadAlignment(4); // Data in resource files is 4 byte aligned dataEntryTable.Add(language.Item1, dataBuilder.CountBytes); dataBuilder.EmitBytes(language.Item1.DataEntry); } dataBuilder.PadAlignment(4); // resource data entries are 4 byte aligned foreach (Tuple <ResLanguage, ObjectDataBuilder.Reservation> language in resLanguages) { dataBuilder.EmitInt(language.Item2, dataBuilder.CountBytes); IMAGE_RESOURCE_DATA_ENTRY.Write(ref dataBuilder, nodeAssociatedWithDataBuilder, dataEntryTable[language.Item1], language.Item1.DataEntry.Length); } dataBuilder.PadAlignment(4); // resource data entries are 4 byte aligned }
public PEReader(string filePath) { // Read in the DLL or EXE and get the timestamp using (FileStream stream = new FileStream(filePath, System.IO.FileMode.Open, System.IO.FileAccess.Read)) { BinaryReader reader = new BinaryReader(stream); dosHeader = FromBinaryReader <IMAGE_DOS_HEADER>(reader); // Add 4 bytes to the offset stream.Seek(dosHeader.e_lfanew, SeekOrigin.Begin); UInt32 ntHeadersSignature = reader.ReadUInt32(); fileHeader = FromBinaryReader <IMAGE_FILE_HEADER>(reader); if (this.Is32BitHeader) { optionalHeader32 = FromBinaryReader <IMAGE_OPTIONAL_HEADER32>(reader); } else { optionalHeader64 = FromBinaryReader <IMAGE_OPTIONAL_HEADER64>(reader); } // image data directory int numberOfRvaAndSizes = (int)((this.Is32BitHeader) ? optionalHeader32.NumberOfRvaAndSizes : optionalHeader64.NumberOfRvaAndSizes); imageDataDirectory = new IMAGE_DATA_DIRECTORY[numberOfRvaAndSizes]; for (int i = 0; i < numberOfRvaAndSizes; i++) { IMAGE_DATA_DIRECTORY direc = FromBinaryReader <IMAGE_DATA_DIRECTORY>(reader); imageDataDirectory[i] = direc; } // image section header, optionalHeader offset 18h = 24 uint optionSize = fileHeader.SizeOfOptionalHeader; stream.Seek(dosHeader.e_lfanew + 24 + optionSize, SeekOrigin.Begin); imageSectionHeader = new IMAGE_SECTION_HEADER[FileHeader.NumberOfSections]; for (int i = 0; i < FileHeader.NumberOfSections; i++) { IMAGE_SECTION_HEADER sectionHeader = FromBinaryReader <IMAGE_SECTION_HEADER>(reader); imageSectionHeader[i] = sectionHeader; } // read resource IMAGE_DATA_DIRECTORY resourceDataDirectory = imageDataDirectory[2]; uint resDataRVA = resourceDataDirectory.VirtualAddress; uint resDataSize = resourceDataDirectory.Size; uint resEndRVA = resDataRVA + resDataSize; resource_offset = 0; resource_rva = 0; resource_rawDataSize = 0; foreach (IMAGE_SECTION_HEADER sectionHeader in imageSectionHeader) { uint secRVA = sectionHeader.VirtualAddress; uint secEndRVA = secRVA + sectionHeader.SizeOfRawData; if (secRVA <= resDataRVA && resEndRVA > secRVA && secEndRVA >= resEndRVA) { resource_offset = sectionHeader.PointerToRawData; resource_rva = secRVA; resource_rawDataSize = sectionHeader.SizeOfRawData; } } if (resource_offset == 0) { ResourceEntry_ALL = new PEResourceEntries[0]; } else { stream.Seek(resource_offset, SeekOrigin.Begin); // resource level 1 IMAGE_RESOURCE_DIRECTORY d1 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader); int entriesCount1 = d1.NumberOfIdEntries + d1.NumberOfNamedEntries; IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries1 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount1]; ResourceEntry_ALL = new PEResourceEntries[entriesCount1]; for (int i = 0; i < entriesCount1; i++) { IMAGE_RESOURCE_DIRECTORY_ENTRY entry = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader); entries1[i] = entry; } for (int i = 0; i < entriesCount1; i++) { IMAGE_RESOURCE_DIRECTORY_ENTRY entry = entries1[i]; PEResourceEntries resEntries = new PEResourceEntries(); resEntries.level1Entry = entry; resEntries.level2Map3Entries = new Hashtable(); resEntries.level3DATA = new Hashtable(); // level 2 // type long offset_2 = resource_offset + entry.OffsetToData_l; stream.Seek(offset_2, SeekOrigin.Begin); if (PEUtil.ConvertIntToBin((int)entry.OffsetToData_h).StartsWith("1")) { IMAGE_RESOURCE_DIRECTORY d2 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader); int entriesCount2 = d2.NumberOfIdEntries + d2.NumberOfNamedEntries; IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries2 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount2]; for (int ii = 0; ii < entriesCount2; ii++) { IMAGE_RESOURCE_DIRECTORY_ENTRY entry2 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader); entries2[ii] = entry2; } resEntries.level2Entries = entries2; // level 3 for (int j = 0; j < entriesCount2; j++) { IMAGE_RESOURCE_DIRECTORY_ENTRY entry2 = entries2[j]; // type long offset_3 = resource_offset + entry2.OffsetToData_l; stream.Seek(offset_3, SeekOrigin.Begin); IMAGE_RESOURCE_DIRECTORY d3 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY>(reader); int entriesCount3 = d3.NumberOfIdEntries + d3.NumberOfNamedEntries; IMAGE_RESOURCE_DIRECTORY_ENTRY[] entries3 = new IMAGE_RESOURCE_DIRECTORY_ENTRY[entriesCount3]; for (int k = 0; k < entriesCount3; k++) { IMAGE_RESOURCE_DIRECTORY_ENTRY entry3 = FromBinaryReader <IMAGE_RESOURCE_DIRECTORY_ENTRY>(reader); entries3[k] = entry3; long offset_4 = resource_offset + entry3.OffsetToData_l; stream.Seek(offset_4, SeekOrigin.Begin); IMAGE_RESOURCE_DATA_ENTRY dataEntry = FromBinaryReader <IMAGE_RESOURCE_DATA_ENTRY>(reader); if (!resEntries.level3DATA.ContainsKey(entry3)) { resEntries.level3DATA.Add(entry3, dataEntry); } } resEntries.level2Map3Entries.Add(entry2, entries3); } } else { throw new Exception("Resource level 2 OffsetToData_h can not start with 0"); // IMAGE_RESOURCE_DATA_ENTRY dataEntry = FromBinaryReader<IMAGE_RESOURCE_DATA_ENTRY>(reader); } ResourceEntry_ALL[i] = resEntries; } } } }