mirror of
https://github.com/claunia/libexeinfo.git
synced 2025-12-16 19:14:24 +00:00
Split resource types and id-to-name converters from NE to Windows/OS2 classes as they are used also by LX and PE formats.
This commit is contained in:
@@ -48,7 +48,7 @@ namespace libexeinfo
|
||||
public NE.ResidentName[] ImportNames;
|
||||
string ModuleDescription;
|
||||
string ModuleName;
|
||||
public NE.ResourceTable neFormatResourceTable;
|
||||
public NE.ResourceTable neFormatResourceTable;
|
||||
public NE.ResidentName[] NonResidentNames;
|
||||
ObjectPageTableEntry[] objectPageTableEntries;
|
||||
ObjectTableEntry[] objectTableEntries;
|
||||
@@ -367,7 +367,7 @@ namespace libexeinfo
|
||||
{
|
||||
neFormatResourceTable.types[counter].count = (ushort)kvp.Value.Count;
|
||||
neFormatResourceTable.types[counter].id = (ushort)kvp.Key;
|
||||
neFormatResourceTable.types[counter].name = NE.ResourceIdToNameOs2((ushort)kvp.Key);
|
||||
neFormatResourceTable.types[counter].name = Resources.IdToName((ushort)kvp.Key);
|
||||
neFormatResourceTable.types[counter].resources = kvp.Value.OrderBy(r => r.id).ToArray();
|
||||
counter++;
|
||||
}
|
||||
|
||||
@@ -24,8 +24,6 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using libexeinfo.Os2;
|
||||
|
||||
namespace libexeinfo
|
||||
{
|
||||
public partial class NE
|
||||
@@ -43,83 +41,10 @@ namespace libexeinfo
|
||||
/// </summary>
|
||||
const string STRING_FILE_INFO = "StringFileInfo";
|
||||
|
||||
const ushort SEGMENT_TYPE_MASK = 0x07;
|
||||
const ushort SEGMENT_FLAGS_MASK = 0x3F8;
|
||||
const ushort SEGMENT_DISCARD_MASK = 0xF000;
|
||||
const ushort SEGMENT_IOPRVL_MASK = 0xC00;
|
||||
const ushort SEGMENT_TYPE_MASK = 0x07;
|
||||
const ushort SEGMENT_FLAGS_MASK = 0x3F8;
|
||||
const ushort SEGMENT_DISCARD_MASK = 0xF000;
|
||||
const ushort SEGMENT_IOPRVL_MASK = 0xC00;
|
||||
public const ushort KNOWN_RSRC_FLAGS = 0x1070;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of a resource type according to its identifier
|
||||
/// </summary>
|
||||
/// <returns>The resource type name.</returns>
|
||||
/// <param name="id">Resource type identifier.</param>
|
||||
public static string ResourceIdToName(ushort id)
|
||||
{
|
||||
switch(id & 0x7FFF)
|
||||
{
|
||||
case (int)ResourceTypes.RT_ACCELERATOR: return "RT_ACCELERATOR";
|
||||
case (int)ResourceTypes.RT_ANICURSOR: return "RT_ANICURSOR";
|
||||
case (int)ResourceTypes.RT_ANIICON: return "RT_ANIICON";
|
||||
case (int)ResourceTypes.RT_BITMAP: return "RT_BITMAP";
|
||||
case (int)ResourceTypes.RT_CURSOR: return "RT_CURSOR";
|
||||
case (int)ResourceTypes.RT_DIALOG: return "RT_DIALOG";
|
||||
case (int)ResourceTypes.RT_DIALOGEX: return "RT_DIALOGEX";
|
||||
case (int)ResourceTypes.RT_DLGINCLUDE: return "RT_DLGINCLUDE";
|
||||
case (int)ResourceTypes.RT_DLGINIT: return "RT_DLGINIT";
|
||||
case (int)ResourceTypes.RT_FONT: return "RT_FONT";
|
||||
case (int)ResourceTypes.RT_FONTDIR: return "RT_FONTDIR";
|
||||
case (int)ResourceTypes.RT_GROUP_CURSOR: return "RT_GROUP_CURSOR";
|
||||
case (int)ResourceTypes.RT_GROUP_ICON: return "RT_GROUP_ICON";
|
||||
case (int)ResourceTypes.RT_HTML: return "RT_HTML";
|
||||
case (int)ResourceTypes.RT_ICON: return "RT_ICON";
|
||||
case (int)ResourceTypes.RT_MANIFEST: return "RT_MANIFEST";
|
||||
case (int)ResourceTypes.RT_MENU: return "RT_MENU";
|
||||
case (int)ResourceTypes.RT_MENUEX: return "RT_MENUEX";
|
||||
case (int)ResourceTypes.RT_MESSAGETABLE: return "RT_MESSAGETABLE";
|
||||
case (int)ResourceTypes.RT_NEWBITMAP: return "RT_NEWBITMAP";
|
||||
case (int)ResourceTypes.RT_PLUGPLAY: return "RT_PLUGPLAY";
|
||||
case (int)ResourceTypes.RT_RCDATA: return "RT_RCDATA";
|
||||
case (int)ResourceTypes.RT_STRING: return "RT_STRING";
|
||||
case (int)ResourceTypes.RT_TOOLBAR: return "RT_TOOLBAR";
|
||||
case (int)ResourceTypes.RT_VERSION: return "RT_VERSION";
|
||||
case (int)ResourceTypes.RT_VXD: return "RT_VXD";
|
||||
default: return $"{id & 0x7FFF}";
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the name of a resource type according to its identifier
|
||||
/// </summary>
|
||||
/// <returns>The resource type name.</returns>
|
||||
/// <param name="id">Resource type identifier.</param>
|
||||
public static string ResourceIdToNameOs2(ushort id)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case (int)Os2.ResourceTypes.RT_POINTER: return "RT_POINTER";
|
||||
case (int)Os2.ResourceTypes.RT_BITMAP: return "RT_BITMAP";
|
||||
case (int)Os2.ResourceTypes.RT_MENU: return "RT_MENU";
|
||||
case (int)Os2.ResourceTypes.RT_DIALOG: return "RT_DIALOG";
|
||||
case (int)Os2.ResourceTypes.RT_STRING: return "RT_STRING";
|
||||
case (int)Os2.ResourceTypes.RT_FONTDIR: return "RT_FONTDIR";
|
||||
case (int)Os2.ResourceTypes.RT_FONT: return "RT_FONT";
|
||||
case (int)Os2.ResourceTypes.RT_ACCELTABLE: return "RT_ACCELTABLE";
|
||||
case (int)Os2.ResourceTypes.RT_RCDATA: return "RT_RCDATA";
|
||||
case (int)Os2.ResourceTypes.RT_MESSAGE: return "RT_MESSAGE";
|
||||
case (int)Os2.ResourceTypes.RT_DLGINCLUDE: return "RT_DLGINCLUDE";
|
||||
case (int)Os2.ResourceTypes.RT_VKEYTBL: return "RT_VKEYTBL";
|
||||
case (int)Os2.ResourceTypes.RT_KEYTBL: return "RT_KEYTBL";
|
||||
case (int)Os2.ResourceTypes.RT_CHARTBL: return "RT_CHARTBL";
|
||||
case (int)Os2.ResourceTypes.RT_DISPLAYINFO: return "RT_DISPLAYINFO";
|
||||
case (int)Os2.ResourceTypes.RT_FKASHORT: return "RT_FKASHORT";
|
||||
case (int)Os2.ResourceTypes.RT_FKALONG: return "RT_FKALONG";
|
||||
case (int)Os2.ResourceTypes.RT_HELPTABLE: return "RT_HELPTABLE";
|
||||
case (int)Os2.ResourceTypes.RT_HELPSUBTABLE: return "RT_HELPSUBTABLE";
|
||||
case (int)Os2.ResourceTypes.RT_FDDIR: return "RT_FDDIR";
|
||||
case (int)Os2.ResourceTypes.RT_FD: return "RT_FD";
|
||||
default: return $"{id}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -73,40 +73,6 @@ namespace libexeinfo
|
||||
SegmentAligned = 0x8000
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resource types.
|
||||
/// </summary>
|
||||
public enum ResourceTypes : ushort
|
||||
{
|
||||
RT_ACCELERATOR = 9,
|
||||
RT_ANICURSOR = 21,
|
||||
RT_ANIICON = 22,
|
||||
RT_BITMAP = 2,
|
||||
RT_CURSOR = 1,
|
||||
RT_DIALOG = 5,
|
||||
RT_DIALOGEX = 18,
|
||||
RT_DLGINCLUDE = 17,
|
||||
RT_DLGINIT = 240,
|
||||
RT_FONT = 8,
|
||||
RT_FONTDIR = 7,
|
||||
RT_GROUP_CURSOR = 12,
|
||||
RT_GROUP_ICON = 14,
|
||||
RT_HTML = 23,
|
||||
RT_ICON = 3,
|
||||
RT_MANIFEST = 24,
|
||||
RT_MENU = 4,
|
||||
RT_MENUEX = 15,
|
||||
RT_MESSAGETABLE = 11,
|
||||
RT_NEWBITMAP = RT_NEW | RT_BITMAP,
|
||||
RT_PLUGPLAY = 19,
|
||||
RT_RCDATA = 10,
|
||||
RT_STRING = 6,
|
||||
RT_TOOLBAR = 241,
|
||||
RT_VERSION = 16,
|
||||
RT_VXD = 20,
|
||||
RT_NEW = 0x2000
|
||||
}
|
||||
|
||||
[Flags]
|
||||
public enum SegmentFlags : ushort
|
||||
{
|
||||
|
||||
@@ -44,8 +44,8 @@ namespace libexeinfo
|
||||
if(!string.IsNullOrEmpty(ModuleName)) sb.AppendFormat("\tModule name: {0}", ModuleName).AppendLine();
|
||||
if(!string.IsNullOrEmpty(ModuleDescription))
|
||||
sb.AppendFormat("\tModule description: {0}", ModuleDescription).AppendLine();
|
||||
sb.AppendFormat("\tFile's CRC: 0x{0:X8}", Header.crc).AppendLine();
|
||||
sb.AppendFormat("\tLinker version: {0}.{1}", Header.linker_major, Header.linker_minor).AppendLine();
|
||||
sb.AppendFormat("\tFile's CRC: 0x{0:X8}", Header.crc).AppendLine();
|
||||
sb.AppendFormat("\tLinker version: {0}.{1}", Header.linker_major, Header.linker_minor).AppendLine();
|
||||
if(Header.program_flags.HasFlag(ProgramFlags.SingleDGroup) &&
|
||||
!Header.program_flags.HasFlag(ProgramFlags.MultipleDGroup))
|
||||
sb.AppendLine("\tApplication uses a single shared DGroup");
|
||||
@@ -99,8 +99,7 @@ namespace libexeinfo
|
||||
Header.return_thunks_offset, Header.segment_reference_thunks).AppendLine();
|
||||
else
|
||||
{
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset)
|
||||
.AppendLine();
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset).AppendLine();
|
||||
sb.AppendFormat("\tSegment reference thunks are at: {0}", Header.segment_reference_thunks)
|
||||
.AppendLine();
|
||||
}
|
||||
@@ -142,8 +141,7 @@ namespace libexeinfo
|
||||
else if(Header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
|
||||
Header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
|
||||
sb.AppendLine("\tApplication uses Windows");
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset)
|
||||
.AppendLine();
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset).AppendLine();
|
||||
sb.AppendFormat("\tSegment reference thunks are at: {0}", Header.segment_reference_thunks)
|
||||
.AppendLine();
|
||||
break;
|
||||
@@ -160,8 +158,7 @@ namespace libexeinfo
|
||||
else if(Header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
|
||||
Header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
|
||||
sb.AppendLine("\tApplication uses Windows");
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset)
|
||||
.AppendLine();
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset).AppendLine();
|
||||
sb.AppendFormat("\tSegment reference thunks are at: {0}", Header.segment_reference_thunks)
|
||||
.AppendLine();
|
||||
break;
|
||||
@@ -178,18 +175,15 @@ namespace libexeinfo
|
||||
else if(Header.application_flags.HasFlag(ApplicationFlags.FullScreen) &&
|
||||
Header.application_flags.HasFlag(ApplicationFlags.GUICompatible))
|
||||
sb.AppendLine("\tApplication uses Windows");
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset)
|
||||
.AppendLine();
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset).AppendLine();
|
||||
sb.AppendFormat("\tSegment reference thunks are at: {0}", Header.segment_reference_thunks)
|
||||
.AppendLine();
|
||||
break;
|
||||
default:
|
||||
sb.AppendFormat("\tApplication for unknown OS {0}", (byte)Header.target_os)
|
||||
.AppendLine();
|
||||
sb.AppendFormat("\tApplication for unknown OS {0}", (byte)Header.target_os).AppendLine();
|
||||
sb.AppendFormat("\tApplication requires OS {0}.{1} to run", Header.os_major, Header.os_minor)
|
||||
.AppendLine();
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset)
|
||||
.AppendLine();
|
||||
sb.AppendFormat("\tReturn thunks are at: {0}", Header.return_thunks_offset).AppendLine();
|
||||
sb.AppendFormat("\tSegment reference thunks are at: {0}", Header.segment_reference_thunks)
|
||||
.AppendLine();
|
||||
break;
|
||||
@@ -201,12 +195,12 @@ namespace libexeinfo
|
||||
if(Header.application_flags.HasFlag(ApplicationFlags.DLL))
|
||||
sb.AppendLine("\tExecutable is a dynamic library or a driver");
|
||||
|
||||
sb.AppendFormat("\tMinimum code swap area: {0} bytes", Header.minimum_swap_area).AppendLine();
|
||||
sb.AppendFormat("\tFile alignment shift: {0}", 1 << Header.alignment_shift).AppendLine();
|
||||
sb.AppendFormat("\tMinimum code swap area: {0} bytes", Header.minimum_swap_area).AppendLine();
|
||||
sb.AppendFormat("\tFile alignment shift: {0}", 1 << Header.alignment_shift).AppendLine();
|
||||
sb.AppendFormat("\tInitial local heap should be {0} bytes", Header.initial_heap).AppendLine();
|
||||
sb.AppendFormat("\tInitial stack size should be {0} bytes", Header.initial_stack).AppendLine();
|
||||
sb.AppendFormat("\tCS:IP entry point: {0:X4}:{1:X4}", (Header.entry_point & 0xFFFF0000) >> 16,
|
||||
Header.entry_point & 0xFFFF).AppendLine();
|
||||
Header.entry_point & 0xFFFF).AppendLine();
|
||||
if(!Header.application_flags.HasFlag(ApplicationFlags.DLL))
|
||||
sb.AppendFormat("\tSS:SP initial stack pointer: {0:X4}:{1:X4}",
|
||||
(Header.stack_pointer & 0xFFFF0000) >> 16, Header.stack_pointer & 0xFFFF)
|
||||
@@ -300,7 +294,7 @@ namespace libexeinfo
|
||||
|
||||
long oldPosition = stream.Position;
|
||||
|
||||
stream.Position = neStart + tableOff;
|
||||
stream.Position = neStart + tableOff;
|
||||
while(stream.Position < upperLimit + neStart)
|
||||
{
|
||||
stringSize = (byte)stream.ReadByte();
|
||||
@@ -329,7 +323,7 @@ namespace libexeinfo
|
||||
byte[] DW = new byte[2];
|
||||
byte[] DD = new byte[4];
|
||||
|
||||
stream.Position = neStart + tableOff;
|
||||
stream.Position = neStart + tableOff;
|
||||
ResourceTable table = new ResourceTable();
|
||||
stream.Read(DW, 0, 2);
|
||||
table.alignment_shift = BitConverter.ToUInt16(DW, 0);
|
||||
@@ -374,27 +368,27 @@ namespace libexeinfo
|
||||
if((table.types[t].id & 0x8000) == 0)
|
||||
{
|
||||
stream.Position = neStart + tableOff + table.types[t].id;
|
||||
byte len = (byte)stream.ReadByte();
|
||||
byte[] str = new byte[len];
|
||||
byte len = (byte)stream.ReadByte();
|
||||
byte[] str = new byte[len];
|
||||
stream.Read(str, 0, len);
|
||||
table.types[t].name = Encoding.ASCII.GetString(str);
|
||||
}
|
||||
else table.types[t].name = ResourceIdToName(table.types[t].id);
|
||||
else table.types[t].name = Windows.Resources.IdToName(table.types[t].id);
|
||||
|
||||
for(int r = 0; r < table.types[t].resources.Length; r++)
|
||||
{
|
||||
if((table.types[t].resources[r].id & 0x8000) == 0)
|
||||
{
|
||||
stream.Position = neStart + tableOff + table.types[t].resources[r].id;
|
||||
byte len = (byte)stream.ReadByte();
|
||||
byte[] str = new byte[len];
|
||||
byte len = (byte)stream.ReadByte();
|
||||
byte[] str = new byte[len];
|
||||
stream.Read(str, 0, len);
|
||||
table.types[t].resources[r].name = Encoding.ASCII.GetString(str);
|
||||
}
|
||||
else table.types[t].resources[r].name = $"{table.types[t].resources[r].id & 0x7FFF}";
|
||||
|
||||
table.types[t].resources[r].data =
|
||||
new byte[table.types[t].resources[r].length * (1 << table.alignment_shift)];
|
||||
new byte[table.types[t].resources[r].length * (1 << table.alignment_shift)];
|
||||
stream.Position = table.types[t].resources[r].dataOffset * (1 << table.alignment_shift);
|
||||
stream.Read(table.types[t].resources[r].data, 0, table.types[t].resources[r].data.Length);
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace libexeinfo
|
||||
/// <summary>
|
||||
/// Header for this executable
|
||||
/// </summary>
|
||||
public NEHeader Header;
|
||||
public NEHeader Header;
|
||||
string[] ImportedNames;
|
||||
string ModuleDescription;
|
||||
string ModuleName;
|
||||
@@ -83,10 +83,10 @@ namespace libexeinfo
|
||||
Initialize();
|
||||
}
|
||||
|
||||
public Stream BaseStream { get; }
|
||||
public bool IsBigEndian => false;
|
||||
public bool Recognized { get; private set; }
|
||||
public string Type { get; private set; }
|
||||
public Stream BaseStream { get; }
|
||||
public bool IsBigEndian => false;
|
||||
public bool Recognized { get; private set; }
|
||||
public string Type { get; private set; }
|
||||
public IEnumerable<Architecture> Architectures =>
|
||||
new[]
|
||||
{
|
||||
@@ -120,8 +120,8 @@ namespace libexeinfo
|
||||
Marshal.FreeHGlobal(hdrPtr);
|
||||
if(Header.signature != SIGNATURE) return;
|
||||
|
||||
Recognized = true;
|
||||
Type = "New Executable (NE)";
|
||||
Recognized = true;
|
||||
Type = "New Executable (NE)";
|
||||
List<string> strings = new List<string>();
|
||||
|
||||
OperatingSystem reqOs = new OperatingSystem();
|
||||
@@ -174,9 +174,9 @@ namespace libexeinfo
|
||||
break;
|
||||
case TargetOS.DOS:
|
||||
case TargetOS.Borland:
|
||||
reqOs.Name = "DOS";
|
||||
reqOs.MajorVersion = Header.os_major;
|
||||
reqOs.MinorVersion = Header.os_minor;
|
||||
reqOs.Name = "DOS";
|
||||
reqOs.MajorVersion = Header.os_major;
|
||||
reqOs.MinorVersion = Header.os_minor;
|
||||
if(Header.target_os == TargetOS.Borland) reqOs.Subsystem = "Borland Operating System Services";
|
||||
break;
|
||||
default:
|
||||
@@ -204,10 +204,10 @@ namespace libexeinfo
|
||||
// Some executable indicates 0 entries, some indicate a table start and no limit, will need to explore till next item
|
||||
ushort resourceUpperLimit = ushort.MaxValue;
|
||||
|
||||
if(Header.entry_table_offset >= Header.resource_table_offset &&
|
||||
Header.entry_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.entry_table_offset;
|
||||
if(Header.segment_table_offset >= Header.resource_table_offset &&
|
||||
Header.segment_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.segment_table_offset;
|
||||
if(Header.entry_table_offset >= Header.resource_table_offset &&
|
||||
Header.entry_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.entry_table_offset;
|
||||
if(Header.segment_table_offset >= Header.resource_table_offset &&
|
||||
Header.segment_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.segment_table_offset;
|
||||
if(Header.module_reference_offset >= Header.resource_table_offset &&
|
||||
Header.module_reference_offset <= resourceUpperLimit)
|
||||
resourceUpperLimit = Header.module_reference_offset;
|
||||
@@ -220,8 +220,8 @@ namespace libexeinfo
|
||||
Header.imported_names_offset <= resourceUpperLimit) resourceUpperLimit = Header.imported_names_offset;
|
||||
|
||||
if(Header.resource_table_offset < resourceUpperLimit && Header.resource_table_offset != 0)
|
||||
if(Header.target_os == TargetOS.Windows || Header.target_os == TargetOS.Win32 ||
|
||||
Header.target_os == TargetOS.Unknown)
|
||||
if(Header.target_os == TargetOS.Windows || Header.target_os == TargetOS.Win32 ||
|
||||
Header.target_os == TargetOS.Unknown)
|
||||
{
|
||||
Resources = GetResources(BaseStream, BaseExecutable.Header.new_offset, Header.resource_table_offset,
|
||||
resourceUpperLimit);
|
||||
@@ -279,14 +279,12 @@ namespace libexeinfo
|
||||
length = resourceSegments[i].dwSegmentLength
|
||||
};
|
||||
|
||||
if(thisResource.length == 0)
|
||||
thisResource.length = 65536;
|
||||
if(thisResource.dataOffset == 0)
|
||||
thisResource.dataOffset = 65536;
|
||||
if(thisResource.length == 0) thisResource.length = 65536;
|
||||
if(thisResource.dataOffset == 0) thisResource.dataOffset = 65536;
|
||||
if((resourceSegments[i].dwFlags & (ushort)SegmentFlags.Huge) == (ushort)SegmentFlags.Huge)
|
||||
thisResource.length <<= Header.alignment_shift;
|
||||
thisResource.data = new byte[thisResource.length];
|
||||
BaseStream.Position = thisResource.dataOffset;
|
||||
thisResource.data = new byte[thisResource.length];
|
||||
BaseStream.Position = thisResource.dataOffset;
|
||||
BaseStream.Read(thisResource.data, 0, thisResource.data.Length);
|
||||
|
||||
thisResourceType.Add(thisResource);
|
||||
@@ -296,14 +294,14 @@ namespace libexeinfo
|
||||
|
||||
if(os2resources.Count > 0)
|
||||
{
|
||||
Resources = new ResourceTable();
|
||||
int counter = 0;
|
||||
Resources = new ResourceTable();
|
||||
int counter = 0;
|
||||
Resources.types = new ResourceType[os2resources.Count];
|
||||
foreach(KeyValuePair<ushort, List<Resource>> kvp in os2resources)
|
||||
{
|
||||
Resources.types[counter].count = (ushort)kvp.Value.Count;
|
||||
Resources.types[counter].id = kvp.Key;
|
||||
Resources.types[counter].name = ResourceIdToNameOs2(kvp.Key);
|
||||
Resources.types[counter].name = Os2.Resources.IdToName(kvp.Key);
|
||||
Resources.types[counter].resources = kvp.Value.OrderBy(r => r.id).ToArray();
|
||||
counter++;
|
||||
}
|
||||
@@ -319,12 +317,12 @@ namespace libexeinfo
|
||||
|
||||
resourceUpperLimit = ushort.MaxValue;
|
||||
|
||||
if(Header.entry_table_offset >= Header.module_reference_offset &&
|
||||
Header.entry_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.entry_table_offset;
|
||||
if(Header.segment_table_offset >= Header.module_reference_offset &&
|
||||
Header.segment_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.segment_table_offset;
|
||||
if(Header.resource_table_offset >= Header.module_reference_offset &&
|
||||
Header.resource_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.resource_table_offset;
|
||||
if(Header.entry_table_offset >= Header.module_reference_offset &&
|
||||
Header.entry_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.entry_table_offset;
|
||||
if(Header.segment_table_offset >= Header.module_reference_offset &&
|
||||
Header.segment_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.segment_table_offset;
|
||||
if(Header.resource_table_offset >= Header.module_reference_offset &&
|
||||
Header.resource_table_offset <= resourceUpperLimit) resourceUpperLimit = Header.resource_table_offset;
|
||||
if(Header.nonresident_names_offset >= Header.module_reference_offset &&
|
||||
Header.nonresident_names_offset <= resourceUpperLimit)
|
||||
resourceUpperLimit = (ushort)Header.nonresident_names_offset;
|
||||
@@ -335,8 +333,8 @@ namespace libexeinfo
|
||||
Header.reference_count > 0)
|
||||
{
|
||||
short[] referenceOffsets = new short[Header.reference_count];
|
||||
buffer = new byte[2];
|
||||
BaseStream.Position = Header.module_reference_offset + BaseExecutable.Header.new_offset;
|
||||
buffer = new byte[2];
|
||||
BaseStream.Position = Header.module_reference_offset + BaseExecutable.Header.new_offset;
|
||||
for(int i = 0; i < Header.reference_count; i++)
|
||||
{
|
||||
BaseStream.Read(buffer, 0, 2);
|
||||
@@ -349,7 +347,7 @@ namespace libexeinfo
|
||||
BaseStream.Position = Header.imported_names_offset + BaseExecutable.Header.new_offset +
|
||||
referenceOffsets[i];
|
||||
int len = BaseStream.ReadByte();
|
||||
buffer = new byte[len];
|
||||
buffer = new byte[len];
|
||||
BaseStream.Read(buffer, 0, len);
|
||||
ImportedNames[i] = Encoding.ASCII.GetString(buffer);
|
||||
}
|
||||
@@ -357,10 +355,10 @@ namespace libexeinfo
|
||||
|
||||
resourceUpperLimit = ushort.MaxValue;
|
||||
|
||||
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.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;
|
||||
@@ -382,7 +380,7 @@ namespace libexeinfo
|
||||
if(ResidentNames.Length > 1)
|
||||
{
|
||||
ResidentName[] newResidentNames = new ResidentName[ResidentNames.Length - 1];
|
||||
Array.Copy(ResidentNames, 1, newResidentNames, 0, ResidentNames.Length - 1);
|
||||
Array.Copy(ResidentNames, 1, newResidentNames, 0, ResidentNames.Length - 1);
|
||||
ResidentNames = newResidentNames;
|
||||
}
|
||||
else ResidentNames = null;
|
||||
@@ -401,7 +399,7 @@ namespace libexeinfo
|
||||
|
||||
if(NonResidentNames.Length > 1)
|
||||
{
|
||||
ResidentName[] newNonResidentNames = new ResidentName[NonResidentNames.Length - 1];
|
||||
ResidentName[] newNonResidentNames = new ResidentName[NonResidentNames.Length - 1];
|
||||
Array.Copy(NonResidentNames, 1, newNonResidentNames, 0, NonResidentNames.Length - 1);
|
||||
NonResidentNames = newNonResidentNames;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Text;
|
||||
using libexeinfo.Windows;
|
||||
|
||||
namespace libexeinfo
|
||||
{
|
||||
@@ -129,7 +130,7 @@ namespace libexeinfo
|
||||
|
||||
VersionNode node = new VersionNode
|
||||
{
|
||||
cbNode = BitConverter.ToUInt16(data, startPosition + nodeLength),
|
||||
cbNode = BitConverter.ToUInt16(data, startPosition + nodeLength),
|
||||
cbData = BitConverter.ToUInt16(data, startPosition + nodeLength + 2)
|
||||
};
|
||||
nodeLength += 4;
|
||||
@@ -148,7 +149,7 @@ namespace libexeinfo
|
||||
|
||||
node.rgbData = new byte[node.cbData];
|
||||
Array.Copy(data, startPosition + nodeLength, node.rgbData, 0, node.cbData);
|
||||
nodeLength += node.cbData;
|
||||
nodeLength += node.cbData;
|
||||
if(nodeLength % 4 > 0) nodeLength += 4 - nodeLength % 4;
|
||||
|
||||
List<VersionNode> children = new List<VersionNode>();
|
||||
@@ -177,8 +178,7 @@ namespace libexeinfo
|
||||
$"{(info.dwFileVersionMS & 0xFFFF0000) >> 16}.{info.dwFileVersionMS & 0xFFFF:D2}.{(info.dwFileVersionLS & 0xFFFF0000) >> 16}.{info.dwFileVersionLS & 0xFFFF}";
|
||||
ProductVersion =
|
||||
$"{(info.dwProductVersionMS & 0xFFFF0000) >> 16}.{info.dwProductVersionMS & 0xFFFF:D2}.{(info.dwProductVersionLS & 0xFFFF0000) >> 16}.{info.dwProductVersionLS & 0xFFFF}";
|
||||
FileFlags =
|
||||
(VersionFileFlags)(info.dwFileFlags & info.dwFileFlagsMask);
|
||||
FileFlags = (VersionFileFlags)(info.dwFileFlags & info.dwFileFlagsMask);
|
||||
FileOS = (VersionFileOS)info.dwFileOS;
|
||||
FileType = (VersionFileType)info.dwFileType;
|
||||
FileSubtype = (VersionFileSubtype)info.dwFileSubtype;
|
||||
@@ -196,7 +196,7 @@ namespace libexeinfo
|
||||
{
|
||||
Encoding encoding;
|
||||
|
||||
try { encoding = Encoding.GetEncoding(Convert.ToInt32(parent.Substring(4), 16)); }
|
||||
try { encoding = Encoding.GetEncoding(Convert.ToInt32(parent.Substring(4), 16)); }
|
||||
catch { encoding = Encoding.ASCII; }
|
||||
|
||||
strings.Add(node.szName, encoding.GetString(node.rgbData));
|
||||
@@ -252,8 +252,7 @@ namespace libexeinfo
|
||||
case VersionFileSubtype.VFT2_DRV_SYSTEM: return "System";
|
||||
case VersionFileSubtype.VFT2_DRV_VERSIONED_PRINTER: return "Versioned";
|
||||
case VersionFileSubtype.VFT2_UNKNOWN: return "Unknown";
|
||||
default:
|
||||
return $"Unknown type code {(uint)subtype}";
|
||||
default: return $"Unknown type code {(uint)subtype}";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -272,8 +271,7 @@ namespace libexeinfo
|
||||
case VersionFileSubtype.VFT2_FONT_TRUETYPE: return "TrueType";
|
||||
case VersionFileSubtype.VFT2_FONT_VECTOR: return "Vector";
|
||||
case VersionFileSubtype.VFT2_UNKNOWN: return "Unknown";
|
||||
default:
|
||||
return $"Unknown type code {(uint)subtype}";
|
||||
default: return $"Unknown type code {(uint)subtype}";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
65
libexeinfo/Os2/Resources.cs
Normal file
65
libexeinfo/Os2/Resources.cs
Normal file
@@ -0,0 +1,65 @@
|
||||
//
|
||||
// Resources.cs
|
||||
//
|
||||
// Author:
|
||||
// Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Copyright (c) 2017-2018 Copyright © Claunia.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITPESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONPECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
namespace libexeinfo.Os2
|
||||
{
|
||||
public static class Resources
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of a resource type according to its identifier
|
||||
/// </summary>
|
||||
/// <returns>The resource type name.</returns>
|
||||
/// <param name="id">Resource type identifier.</param>
|
||||
public static string IdToName(ushort id)
|
||||
{
|
||||
switch(id)
|
||||
{
|
||||
case (int)ResourceTypes.RT_POINTER: return "RT_POINTER";
|
||||
case (int)ResourceTypes.RT_BITMAP: return "RT_BITMAP";
|
||||
case (int)ResourceTypes.RT_MENU: return "RT_MENU";
|
||||
case (int)ResourceTypes.RT_DIALOG: return "RT_DIALOG";
|
||||
case (int)ResourceTypes.RT_STRING: return "RT_STRING";
|
||||
case (int)ResourceTypes.RT_FONTDIR: return "RT_FONTDIR";
|
||||
case (int)ResourceTypes.RT_FONT: return "RT_FONT";
|
||||
case (int)ResourceTypes.RT_ACCELTABLE: return "RT_ACCELTABLE";
|
||||
case (int)ResourceTypes.RT_RCDATA: return "RT_RCDATA";
|
||||
case (int)ResourceTypes.RT_MESSAGE: return "RT_MESSAGE";
|
||||
case (int)ResourceTypes.RT_DLGINCLUDE: return "RT_DLGINCLUDE";
|
||||
case (int)ResourceTypes.RT_VKEYTBL: return "RT_VKEYTBL";
|
||||
case (int)ResourceTypes.RT_KEYTBL: return "RT_KEYTBL";
|
||||
case (int)ResourceTypes.RT_CHARTBL: return "RT_CHARTBL";
|
||||
case (int)ResourceTypes.RT_DISPLAYINFO: return "RT_DISPLAYINFO";
|
||||
case (int)ResourceTypes.RT_FKASHORT: return "RT_FKASHORT";
|
||||
case (int)ResourceTypes.RT_FKALONG: return "RT_FKALONG";
|
||||
case (int)ResourceTypes.RT_HELPTABLE: return "RT_HELPTABLE";
|
||||
case (int)ResourceTypes.RT_HELPSUBTABLE: return "RT_HELPSUBTABLE";
|
||||
case (int)ResourceTypes.RT_FDDIR: return "RT_FDDIR";
|
||||
case (int)ResourceTypes.RT_FD: return "RT_FD";
|
||||
default: return $"{id}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -26,6 +26,40 @@
|
||||
|
||||
namespace libexeinfo.Windows
|
||||
{
|
||||
/// <summary>
|
||||
/// Resource types.
|
||||
/// </summary>
|
||||
public enum ResourceTypes : ushort
|
||||
{
|
||||
RT_ACCELERATOR = 9,
|
||||
RT_ANICURSOR = 21,
|
||||
RT_ANIICON = 22,
|
||||
RT_BITMAP = 2,
|
||||
RT_CURSOR = 1,
|
||||
RT_DIALOG = 5,
|
||||
RT_DIALOGEX = 18,
|
||||
RT_DLGINCLUDE = 17,
|
||||
RT_DLGINIT = 240,
|
||||
RT_FONT = 8,
|
||||
RT_FONTDIR = 7,
|
||||
RT_GROUP_CURSOR = 12,
|
||||
RT_GROUP_ICON = 14,
|
||||
RT_HTML = 23,
|
||||
RT_ICON = 3,
|
||||
RT_MANIFEST = 24,
|
||||
RT_MENU = 4,
|
||||
RT_MENUEX = 15,
|
||||
RT_MESSAGETABLE = 11,
|
||||
RT_NEWBITMAP = RT_NEW | RT_BITMAP,
|
||||
RT_PLUGPLAY = 19,
|
||||
RT_RCDATA = 10,
|
||||
RT_STRING = 6,
|
||||
RT_TOOLBAR = 241,
|
||||
RT_VERSION = 16,
|
||||
RT_VXD = 20,
|
||||
RT_NEW = 0x2000
|
||||
}
|
||||
|
||||
public enum BitmapCompression : uint
|
||||
{
|
||||
None = 0,
|
||||
|
||||
70
libexeinfo/Windows/Resources.cs
Normal file
70
libexeinfo/Windows/Resources.cs
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// Resources.cs
|
||||
//
|
||||
// Author:
|
||||
// Natalia Portillo <claunia@claunia.com>
|
||||
//
|
||||
// Copyright (c) 2017-2018 Copyright © Claunia.com
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITPESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONPECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
namespace libexeinfo.Windows
|
||||
{
|
||||
public static class Resources
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the name of a resource type according to its identifier
|
||||
/// </summary>
|
||||
/// <returns>The resource type name.</returns>
|
||||
/// <param name="id">Resource type identifier.</param>
|
||||
public static string IdToName(ushort id)
|
||||
{
|
||||
switch(id & 0x7FFF)
|
||||
{
|
||||
case (int)ResourceTypes.RT_ACCELERATOR: return "RT_ACCELERATOR";
|
||||
case (int)ResourceTypes.RT_ANICURSOR: return "RT_ANICURSOR";
|
||||
case (int)ResourceTypes.RT_ANIICON: return "RT_ANIICON";
|
||||
case (int)ResourceTypes.RT_BITMAP: return "RT_BITMAP";
|
||||
case (int)ResourceTypes.RT_CURSOR: return "RT_CURSOR";
|
||||
case (int)ResourceTypes.RT_DIALOG: return "RT_DIALOG";
|
||||
case (int)ResourceTypes.RT_DIALOGEX: return "RT_DIALOGEX";
|
||||
case (int)ResourceTypes.RT_DLGINCLUDE: return "RT_DLGINCLUDE";
|
||||
case (int)ResourceTypes.RT_DLGINIT: return "RT_DLGINIT";
|
||||
case (int)ResourceTypes.RT_FONT: return "RT_FONT";
|
||||
case (int)ResourceTypes.RT_FONTDIR: return "RT_FONTDIR";
|
||||
case (int)ResourceTypes.RT_GROUP_CURSOR: return "RT_GROUP_CURSOR";
|
||||
case (int)ResourceTypes.RT_GROUP_ICON: return "RT_GROUP_ICON";
|
||||
case (int)ResourceTypes.RT_HTML: return "RT_HTML";
|
||||
case (int)ResourceTypes.RT_ICON: return "RT_ICON";
|
||||
case (int)ResourceTypes.RT_MANIFEST: return "RT_MANIFEST";
|
||||
case (int)ResourceTypes.RT_MENU: return "RT_MENU";
|
||||
case (int)ResourceTypes.RT_MENUEX: return "RT_MENUEX";
|
||||
case (int)ResourceTypes.RT_MESSAGETABLE: return "RT_MESSAGETABLE";
|
||||
case (int)ResourceTypes.RT_NEWBITMAP: return "RT_NEWBITMAP";
|
||||
case (int)ResourceTypes.RT_PLUGPLAY: return "RT_PLUGPLAY";
|
||||
case (int)ResourceTypes.RT_RCDATA: return "RT_RCDATA";
|
||||
case (int)ResourceTypes.RT_STRING: return "RT_STRING";
|
||||
case (int)ResourceTypes.RT_TOOLBAR: return "RT_TOOLBAR";
|
||||
case (int)ResourceTypes.RT_VERSION: return "RT_VERSION";
|
||||
case (int)ResourceTypes.RT_VXD: return "RT_VXD";
|
||||
default: return $"{id & 0x7FFF}";
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -65,6 +65,7 @@
|
||||
<Compile Include="NE\GetStrings.cs" />
|
||||
<Compile Include="Os2\Bitmap.cs" />
|
||||
<Compile Include="Os2\Enums.cs" />
|
||||
<Compile Include="Os2\Resources.cs" />
|
||||
<Compile Include="Os2\Structs.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="MZ\Consts.cs" />
|
||||
@@ -104,6 +105,7 @@
|
||||
<Compile Include="PE\Subsystems.cs" />
|
||||
<Compile Include="Windows\Bitmap.cs" />
|
||||
<Compile Include="Windows\Enums.cs" />
|
||||
<Compile Include="Windows\Resources.cs" />
|
||||
<Compile Include="Windows\Structs.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user