diff --git a/exeinfo/Program.cs b/exeinfo/Program.cs index 69fd4d9..21925c0 100644 --- a/exeinfo/Program.cs +++ b/exeinfo/Program.cs @@ -109,6 +109,20 @@ namespace exeinfo Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value); } } + + if(((NE)neExe).ResidentNames != null) + { + Console.WriteLine("\tResident names:"); + foreach(NE.ResidentName name in ((NE)neExe).ResidentNames) + Console.WriteLine("\t\t{0} at index {1}", name.name, name.entryTableIndex); + } + + if(((NE)neExe).NonResidentNames != null) + { + Console.WriteLine("\tNon-resident names:"); + foreach(NE.ResidentName name in ((NE)neExe).NonResidentNames) + Console.WriteLine("\t\t{0} at index {1}", name.name, name.entryTableIndex); + } } else if(lxExe.Recognized) { diff --git a/libexeinfo/NE/Info.cs b/libexeinfo/NE/Info.cs index 0ff8ebf..55ee205 100644 --- a/libexeinfo/NE/Info.cs +++ b/libexeinfo/NE/Info.cs @@ -213,6 +213,40 @@ namespace libexeinfo return sb.ToString(); } + static ResidentName[] GetResidentStrings(Stream stream, uint neStart, ushort tableOff, ushort upperLimit) + { + if(tableOff >= upperLimit) return null; + + List names = new List(); + byte stringSize; + byte[] nameString; + byte[] DW = new byte[2]; + + long oldPosition = stream.Position; + + stream.Position = neStart + tableOff; + while(stream.Position < upperLimit + neStart) + { + stringSize = (byte)stream.ReadByte(); + + if(stringSize == 0) break; + + nameString = new byte[stringSize]; + stream.Read(nameString, 0, stringSize); + stream.Read(DW, 0, 2); + + names.Add(new ResidentName + { + name = Encoding.ASCII.GetString(nameString), + entryTableIndex = BitConverter.ToUInt16(DW, 0) + }); + } + + stream.Position = oldPosition; + + return names.Count > 0 ? names.ToArray() : null; + } + public static ResourceTable GetResources(Stream stream, uint neStart, ushort tableOff, ushort upperLimit) { long oldPosition = stream.Position; diff --git a/libexeinfo/NE/NE.cs b/libexeinfo/NE/NE.cs index 31868f7..8b38025 100644 --- a/libexeinfo/NE/NE.cs +++ b/libexeinfo/NE/NE.cs @@ -43,6 +43,8 @@ namespace libexeinfo public NEHeader Header; public ResourceTable Resources; public Version[] Versions; + public ResidentName[] ResidentNames; + public ResidentName[] NonResidentNames; /// /// Initializes a new instance of the class. @@ -194,11 +196,35 @@ namespace libexeinfo if(Header.imported_names_offset >= Header.resource_table_offset && Header.imported_names_offset <= resourceUpperLimit) resourceUpperLimit = Header.imported_names_offset; - if(Header.resource_table_offset >= resourceUpperLimit || Header.resource_table_offset == 0) return; + if(Header.resource_table_offset < resourceUpperLimit && Header.resource_table_offset != 0) + { + Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Header.resource_table_offset, + resourceUpperLimit); + Versions = GetVersions().ToArray(); + } + + resourceUpperLimit = ushort.MaxValue; - Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Header.resource_table_offset, - resourceUpperLimit); - Versions = GetVersions().ToArray(); + if(Header.entry_table_offset >= Header.resident_names_offset && + Header.entry_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.entry_table_offset; + if(Header.segment_table_offset >= Header.resident_names_offset && + Header.segment_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.segment_table_offset; + if(Header.module_reference_offset >= Header.resident_names_offset && + Header.module_reference_offset <= resourceUpperLimit) + resourceUpperLimit = Header.module_reference_offset; + if(Header.nonresident_names_offset >= Header.resident_names_offset && + Header.nonresident_names_offset <= resourceUpperLimit) + resourceUpperLimit = (ushort)Header.nonresident_names_offset; + if(Header.imported_names_offset >= Header.resident_names_offset && + Header.imported_names_offset <= resourceUpperLimit) resourceUpperLimit = Header.imported_names_offset; + + if(Header.resource_table_offset < resourceUpperLimit && Header.resource_table_offset != 0) + ResidentNames = GetResidentStrings(BaseStream, BaseExecutable.Header.new_offset, + Header.resident_names_offset, resourceUpperLimit); + + if(Header.nonresident_table_size > 0) + NonResidentNames = GetResidentStrings(BaseStream, Header.nonresident_names_offset, + 0, (ushort)(Header.nonresident_names_offset + Header.nonresident_table_size)); } /// diff --git a/libexeinfo/NE/Structs.cs b/libexeinfo/NE/Structs.cs index 247e3e9..4966d31 100644 --- a/libexeinfo/NE/Structs.cs +++ b/libexeinfo/NE/Structs.cs @@ -141,5 +141,17 @@ namespace libexeinfo public uint dwSignature; public uint dwStrucVersion; } + + public struct ResidentName + { + /// + /// Text of string + /// + public string name; + /// + /// Index in the entry table this string refers to + /// + public ushort entryTableIndex; + } } } \ No newline at end of file