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); } } }
public ResourceTable(Stream stream, long rsrcSectionRVA, long?rsrcSectionFileAddress = null) { #if COVERAGE_TEST && USE_SIZE if (rsrcSectionFileAddress == null) { Init(stream.Position, stream.Length); } #endif SectionRVA = rsrcSectionRVA; var SectionPA = rsrcSectionFileAddress ?? stream.Position; using (var br = new BinaryReader(stream, Encoding.Default, true)) { Header = br.ReadStruct <IMAGE_RESOURCE_DIRECTORY>(); #if COVERAGE_TEST && USE_SIZE RemoveBack(br.BaseStream.Position, typeof(IMAGE_RESOURCE_DIRECTORY)); #endif void InitEntries(ref List <ResourceDirectoryEntry> entryPointers, ref List <object> entryValues, int count) { entryPointers = new List <ResourceDirectoryEntry>(count); entryValues = new List <object>(count); for (int i = 0; i < count; i++) { entryPointers.Add(new ResourceDirectoryEntry(br.BaseStream, SectionPA)); } } InitEntries(ref NamedEntryPointers, ref NamedEntries, Header.NumberOfNameEntries); InitEntries(ref IDEntryPointers, ref IDEntries, Header.NumberOfIDEntries); void ReadEntries(ref List <ResourceDirectoryEntry> entryPointers, ref List <object> entryValues) { foreach (var pointer in entryPointers) { br.BaseStream.Seek(SectionPA + pointer.header.DataOffset, SeekOrigin.Begin); if (pointer.header.IsTable) { entryValues.Add(new ResourceTable(br.BaseStream, SectionRVA, SectionPA)); } else { entryValues.Add(new ResourceDataEntry(br.BaseStream, SectionRVA, SectionPA)); } } } ReadEntries(ref NamedEntryPointers, ref NamedEntries); ReadEntries(ref IDEntryPointers, ref IDEntries); #if COVERAGE_TEST && USE_SIZE if (rsrcSectionFileAddress == null) { System.Diagnostics.Debug.Write(Report()); } #endif } }
public static IMAGE_RESOURCE_DIRECTORY Deserialize(MultiPartFile file) { IMAGE_RESOURCE_DIRECTORY ird = new IMAGE_RESOURCE_DIRECTORY(); ird.Characteristics = file.ReadUInt32(); ird.TimeDateStamp = file.ReadUInt32(); ird.MajorVersion = file.ReadUInt16(); ird.MinorVersion = file.ReadUInt16(); ird.NumberOfNamedEntries = file.ReadUInt16(); ird.NumberOfIdEntries = file.ReadUInt16(); return(ird); }
public void ImageResourceDirectoryConstructorWorks_Test() { var resourceDirectory = new IMAGE_RESOURCE_DIRECTORY(RawStructures.RawResourceDirectory, 2, 2); Assert.Equal((uint)0x33221100, resourceDirectory.Characteristics); Assert.Equal((uint)0x77665544, resourceDirectory.TimeDateStamp); Assert.Equal((ushort)0x9988, resourceDirectory.MajorVersion); Assert.Equal((ushort)0xbbaa, resourceDirectory.MinorVersion); Assert.Equal((ushort)0x0001, resourceDirectory.NumberOfNameEntries); Assert.Equal((ushort)0x0001, resourceDirectory.NumberOfIdEntries); Assert.Equal((uint)0x44332211, resourceDirectory.DirectoryEntries[0].Name); Assert.Equal(0x88776655, resourceDirectory.DirectoryEntries[0].OffsetToData); Assert.Equal((uint)0x44332222 & 0xFFFF, resourceDirectory.DirectoryEntries[1].ID); Assert.Equal(0x88776622, resourceDirectory.DirectoryEntries[1].OffsetToData); }
private static void DoResourceDirectoryRead(BlobReader resourceReaderExternal, uint startOffset, Action <object, uint, bool> entry) { // Create a copy of the Mu, so that we don't allow the delegate to affect its state BlobReader resourceReader = resourceReaderExternal; resourceReader.Offset = checked ((int)startOffset); IMAGE_RESOURCE_DIRECTORY directory = new IMAGE_RESOURCE_DIRECTORY(ref resourceReader); for (uint i = 0; i < directory.NumberOfNamedEntries + directory.NumberOfIdEntries; i++) { IMAGE_RESOURCE_DIRECTORY_ENTRY directoryEntry = new IMAGE_RESOURCE_DIRECTORY_ENTRY(ref resourceReader); object name; if ((directoryEntry.Name & 0x80000000) != 0) { int oldPosition = resourceReader.Offset; // This is a named entry, read the string uint nameOffset = directoryEntry.Name & ~0x80000000; resourceReader.Offset = checked ((int)nameOffset); ushort stringLen = resourceReader.ReadUInt16(); char[] newStringData = new char[stringLen]; for (int iStr = 0; iStr < stringLen; iStr++) { newStringData[iStr] = (char)resourceReader.ReadUInt16(); } name = new string(newStringData); // And then reset back to read more things. resourceReader.Offset = oldPosition; } else { name = checked ((ushort)directoryEntry.Name); } uint offset = directoryEntry.OffsetToData; bool isDirectory = false; if ((offset & 0x80000000) != 0) { offset &= ~0x80000000; isDirectory = true; } entry(name, offset, isDirectory); } }
// ************************************** // this is a re-entrant procedure // ird must always arrive pointing to a resource directory // For now, this assumes all offsets are relative to the start // of the resource section (opinions seem to differ on this) #if NO int GetResource( string cs, IMAGE_RESOURCE_DIRECTORY ird, uint de, // value to subtract from ".link" offsets// s uint ss, // section size uint offset // offset to resource section ) { int n; uint p; IMAGE_RESOURCE_DATA_ENTRY Ptr pirde; IMAGE_RESOURCE_DIRECTORY_ENTRY Ptr irde; IMAGE_RESOURCE_DIRECTORY_STRING ids; Static fResult As Long; Static lvl As Long; // recursion level Static rp As Dword; // resource pointer Static rid As Dword; Static typ As Dword; Static ns As String; if (lvl = 0) { rp = StrPtr(cs); } // = ird // save pointer to start of resource section ++lvl; irde = ird + SizeOf(IMAGE_RESOURCE_DIRECTORY); // The named entries are case insensitive strings, sorted in ascending order. // The entries with 16-bit IDs follow these and are also sorted in ascending order. For n = 1 To @ird.NumberOfNamedEntries + @ird.NumberOfIdEntries if ((n <= @ird.NumberOfNamedEntries)And(@irde.NameID And % IMAGE_RESOURCE_NAME_IS_STRING)) { // the name is a string p = rp + (@irde.NameID And & H7FFFFFFF) // offset is relative to start of resource section rid = 0 // assign invalid value as a flag ns = Remove$(Peek$(p + 2, CvWrd(Peek$(p, 2)) * 2), $Nul) // unicode string if (UCase$(ns) = "TYPELIB") { fResult = 1 // found TypeLib data }
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 }
// ************************************** // this is a re-entrant procedure // ird must always arrive pointing to a resource directory // For now, this assumes all offsets are relative to the start // of the resource section (opinions seem to differ on this) int GetResource( string cs, IMAGE_RESOURCE_DIRECTORY ird, uint de, // value to subtract from ".link" offsets// s uint ss , // section size uint offset // offset to resource section ) { Long n; Dword p; IMAGE_RESOURCE_DATA_ENTRY Ptr pirde; IMAGE_RESOURCE_DIRECTORY_ENTRY Ptr irde; IMAGE_RESOURCE_DIRECTORY_STRING ids; Static fResult As Long ; Static lvl As Long ;// recursion level Static rp As Dword ;// resource pointer Static rid As Dword ; Static typ As Dword ; Static ns As String; if (lvl = 0) { rp = StrPtr(cs); } // = ird // save pointer to start of resource section Incr lvl irde = ird + SizeOf(IMAGE_RESOURCE_DIRECTORY); // The named entries are case insensitive strings, sorted in ascending order. // The entries with 16-bit IDs follow these and are also sorted in ascending order. For n = 1 To @ird.NumberOfNamedEntries + @ird.NumberOfIdEntries if ((n <= @ird.NumberOfNamedEntries) And (@irde.NameID And %IMAGE_RESOURCE_NAME_IS_STRING)) { // the name is a string p = rp + (@irde.NameID And &H7FFFFFFF) // offset is relative to start of resource section rid = 0 // assign invalid value as a flag ns = Remove$(Peek$(p + 2, CvWrd(Peek$(p, 2)) * 2), $Nul) // unicode string if (UCase$(ns) = "TYPELIB") { fResult = 1 // found TypeLib data } else if ((n > @ird.NumberOfNamedEntries) And (@irde.NameID And %IMAGE_RESOURCE_NAME_IS_STRING) = 0) { // it// s a 16-bit ID number p = LoWrd(@irde.NameID) if (lvl = 1) { typ = p } else if (lvl = 2) { ns = "" rid = p } else if (lvl = 3) { } } p = (@irde.Offset And &H7FFFFFFF) if ((@irde.Offset And %IMAGE_RESOURCE_DATA_IS_DIRECTORY)) { // it// s a subdirectory p = GetResource(cs, rp + p, de, ss, Offset) } else { // it// s actual resource data // get offset in PE file to ImageResourceDirectoryEntry structure pirde = rp + p if (fResult = 1) { Incr fResult // @pirde.OffsetToData is the RVA to the resource data cs = Mid$(cs, @pirde.OffsetToData - de - Offset + 1, @pirde.Size) } } if (fResult == 2) break; irde = irde + SizeOf(IMAGE_RESOURCE_DIRECTORY_ENTRY); Next n -- lvl; if (lvl) { Function = ird; } else { Function = fResult; fResult = 0; } } // GetResource // *************************************** // gets TypeLib data from a PE file// s resource section int GetTypeLibData(string cs, string fs) { //#Register All FileStream ff;// file handle Long n; Long fTlb; DosHeader DosHdr; PEHeader pPH; SectionInfo si; OptHeader pOH; SectionHeader pSH; DataDir pDD; // -------------------------------------- // get the Typelib data try { ff = FreeFile(); ff = new FileStream(fs, FileMode.Open, FileAccess.Read, FileShare.Read); byte[] cs = new byte[2048]; ff.Read(cs, 0, cs.Length); // ---------------------------------- // get PE signature if present LSet DosHdr = cs; if ((Left$(cs, 2) = $PeMZ) && (Mid$(cs, DosHdr.lfanew + 1, 4) = $PePE32)) { Decr fTlb // disable loading the file below pPH = StrPtr(cs) + DosHdr.lfanew + 4; pOH = pPH + SizeOf(PEHeader); // "pOH.NumberOfRvaAndSizes" is the number of entries, not the size of the array, as someone once wrote if (ResourceSection > @pOH.NumberOfRvaAndSizes) return; pDD = pOH + SizeOf(OptHeader) + ((ResourceSection - 1) * SizeOf(DataDir)); si.dRVA = @pDD.RVA ; si.dSize = @pDD.DirSize ; // find the section which matches si.dRVA in the section table pSH = pOH + SizeOf(OptHeader) + (@pOH.NumberOfRvaAndSizes * SizeOf(DataDir)); For (int n = 1; n <= @pPH.NumberOfSections; ++n) { if ((si.dRVA => @pSH.RVA) && (si.dRVA < @pSH.RVA + @pSH.SizeOfRawData)) { si.SectName = @pSH.SectName; si.VirtSize = @pSH.VirtSize; // size of unpadded section si.RVA = @pSH.RVA; // @pSH.RVA is the offset to section when loaded si.RamAdd = @pOH.ImageBase + @pSH.RVA; // section// s RAM address (for example: &H401000) si.SizeOfRawData = @pSH.SizeOfRawData; // size after padding to section alignment si.PtrToRawData = @pSH.PtrToRawData; // zero-based file offset to section si.StrPos = @pSH.PtrToRawData + 1; // one-based file offset to section si.EndPos = si.StrPos + si.SizeOfRawData; si.Delta = si.RVA - si.PtrToRawData; // value to subtract from RVAs to get file offsets si.Characteristics = @pSH.Characteristics; break; } pSH = pSH + SizeOf(SectionHeader); // advance pSH to next section header } // get TypeLib resource ff.Position = si.StrPos; cs = new byte[si.SizeOfRawData]; ff.Read(cs, 0, cs.Length); if (GetResource(cs, StrPtr(cs), si.Delta, si.SizeOfRawData, si.PtrToRawData) = 0) { Reset cs UpdateLog( "No TypeLib data found in: " + fs); } } if (Left$(cs, 4) == "MSFT") { // it's a "tlb" (TypeLib) file ++fTlb Function = 1 } else if (Left$(cs, 4) = "SLTG") { Incr fTlb Function = 2 } if (fTlb > 0) { Seek# ff, 1 Get$ #ff, Lof(ff), cs } ff.Close (); } catch { UpdateLog ("Error opening input file: " + fs); return; } } // GetTypeLibData
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; } } } }