Files
libexeinfo/exeinfo/Program.cs

191 lines
9.2 KiB
C#
Raw Normal View History

//
// Program.cs
//
// Author:
// Natalia Portillo <claunia@claunia.com>
//
// Copyright (c) 2017 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,
// FITNESS 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 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Globalization;
2018-02-25 03:08:28 +00:00
using System.IO;
using System.Text;
2017-10-16 14:58:13 +01:00
using libexeinfo;
2017-10-03 13:26:49 +01:00
namespace exeinfo
{
2018-02-25 18:42:56 +00:00
static class MainClass
2017-10-03 13:26:49 +01:00
{
public static void Main(string[] args)
{
2018-02-25 03:08:28 +00:00
if(args.Length != 1)
2017-10-03 13:26:49 +01:00
{
Console.WriteLine("exeinfo version 0.1 © 2017 Natalia Portillo");
Console.WriteLine("Usage: exeinfo file.exe");
return;
}
bool recognized = false;
2018-02-26 23:24:56 +00:00
IExecutable mzExe = new MZ(args[0]);
IExecutable neExe = new NE(args[0]);
IExecutable stExe = new AtariST(args[0]);
IExecutable lxExe = new LX(args[0]);
IExecutable coffExe = new COFF(args[0]);
IExecutable peExe = new PE(args[0]);
2017-10-03 13:26:49 +01:00
2018-02-25 18:42:56 +00:00
if(neExe.Recognized)
2017-10-16 15:28:21 +01:00
{
recognized = true;
2018-02-25 18:42:56 +00:00
Console.Write(neExe.Information);
if(((NE)neExe).Versions != null)
foreach(NE.Version vers in ((NE)neExe).Versions)
2017-10-03 17:03:21 +01:00
{
2018-02-25 03:08:28 +00:00
Console.WriteLine("\tVersion resource {0}:", vers.Name);
Console.WriteLine("\t\tFile version: {0}", vers.FileVersion);
Console.WriteLine("\t\tProduct version: {0}", vers.ProductVersion);
2018-02-25 03:08:28 +00:00
Console.WriteLine("\t\tFile type: {0}", NE.Version.TypeToString(vers.FileType));
if(vers.FileType == NE.VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} driver",
NE.Version.DriverToString(vers.FileSubtype));
else if(vers.FileType == NE.VersionFileType.VFT_DRV)
Console.WriteLine("\t\tFile subtype: {0} font", NE.Version.FontToString(vers.FileSubtype));
2018-02-25 03:08:28 +00:00
else if(vers.FileSubtype > 0)
Console.WriteLine("\t\tFile subtype: {0}", (uint)vers.FileSubtype);
2018-02-25 03:08:28 +00:00
Console.WriteLine("\t\tFile flags: {0}", vers.FileFlags);
Console.WriteLine("\t\tFile OS: {0}", NE.Version.OsToString(vers.FileOS));
2018-02-25 03:08:28 +00:00
foreach(KeyValuePair<string, Dictionary<string, string>> strByLang in vers.StringsByLanguage)
2017-10-16 15:28:21 +01:00
{
string cultureName;
string encodingName;
try
{
2018-02-25 03:08:28 +00:00
cultureName = new CultureInfo(Convert.ToInt32(strByLang.Key.Substring(0, 4), 16))
.DisplayName;
}
catch
{
2018-02-25 03:08:28 +00:00
cultureName =
$"unsupported culture 0x{Convert.ToInt32(strByLang.Key.Substring(0, 4), 16):X4}";
}
2017-10-16 15:28:21 +01:00
try
{
2018-02-25 03:08:28 +00:00
encodingName = Encoding
.GetEncoding(Convert.ToInt32(strByLang.Key.Substring(4), 16))
.EncodingName;
}
catch
{
2018-02-25 03:08:28 +00:00
encodingName =
$"unsupported encoding 0x{Convert.ToInt32(strByLang.Key.Substring(4), 16):X4}";
}
Console.WriteLine("\t\tStrings for {0} in codepage {1}:", cultureName, encodingName);
2018-02-25 03:08:28 +00:00
foreach(KeyValuePair<string, string> strings in strByLang.Value)
Console.WriteLine("\t\t\t{0}: {1}", strings.Key, strings.Value);
}
2017-10-03 17:03:21 +01:00
}
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);
}
2017-10-03 13:26:49 +01:00
}
else if(lxExe.Recognized)
2018-02-25 03:08:28 +00:00
{
recognized = true;
Console.Write(lxExe.Information);
2018-02-25 03:08:28 +00:00
}
else if(peExe.Recognized)
2018-02-25 03:08:28 +00:00
{
recognized = true;
Console.Write(peExe.Information);
}
else if(mzExe.Recognized)
{
recognized = true;
Console.Write(mzExe.Information);
2018-02-25 03:08:28 +00:00
}
if(stExe.Recognized)
2018-02-25 03:08:28 +00:00
{
recognized = true;
Console.Write(stExe.Information);
2018-02-26 23:24:56 +00:00
if(((AtariST)stExe).resourceStream != null ||
(((AtariST)stExe).ResourceHeader.rsh_vrsn != 0 && ((AtariST)stExe).ResourceHeader.rsh_vrsn != 1 &&
((AtariST)stExe).ResourceHeader.rsh_vrsn != 4 && ((AtariST)stExe).ResourceHeader.rsh_vrsn != 5))
2018-02-26 23:24:56 +00:00
{
Console.WriteLine("\tResources:");
Console.WriteLine("\t\t{0} OBJECTs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nobs, ((AtariST)stExe).ResourceHeader.rsh_object);
Console.WriteLine("\t\t{0} TEDINFOs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nted, ((AtariST)stExe).ResourceHeader.rsh_tedinfo);
Console.WriteLine("\t\t{0} ICONBLKs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nib, ((AtariST)stExe).ResourceHeader.rsh_iconblk);
Console.WriteLine("\t\t{0} BITBLKs start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nbb, ((AtariST)stExe).ResourceHeader.rsh_bitblk);
Console.WriteLine("\t\t{0} object trees start at {1}", ((AtariST)stExe).ResourceHeader.rsh_ntree, ((AtariST)stExe).ResourceHeader.rsh_trindex);
Console.WriteLine("\t\t{0} free strings start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nstring, ((AtariST)stExe).ResourceHeader.rsh_frstr);
Console.WriteLine("\t\t{0} free images start at {1}", ((AtariST)stExe).ResourceHeader.rsh_nimages, ((AtariST)stExe).ResourceHeader.rsh_frimg);
Console.WriteLine("\t\tString data starts at {0}", ((AtariST)stExe).ResourceHeader.rsh_string);
Console.WriteLine("\t\tImage data starts at {0}", ((AtariST)stExe).ResourceHeader.rsh_imdata);
Console.WriteLine("\t\tStandard resource data is {0} bytes", ((AtariST)stExe).ResourceHeader.rsh_rssize);
if(((AtariST)stExe).ResourceObjectRoot != null)
{
Console.WriteLine("\tObject tree:");
PrintAtariResourceTree(((AtariST)stExe).ResourceObjectRoot, 2);
}
2018-02-26 23:24:56 +00:00
}
2018-02-25 03:08:28 +00:00
}
if(coffExe.Recognized)
2018-02-25 03:08:28 +00:00
{
recognized = true;
Console.Write(coffExe.Information);
2018-02-25 03:08:28 +00:00
}
if(!recognized) Console.WriteLine("Executable format not recognized");
2017-10-16 15:28:21 +01:00
}
static void PrintAtariResourceTree(AtariST.TreeObjectNode node, int level)
{
for(int i = 0; i < level; i++)
Console.Write("\t");
Console.WriteLine("{0} ({1} {2}) data = {3}, coordinates ({4},{5}) size {6}x{7}", node.type, node.flags,
node.state, node.data, node.x, node.y, node.width, node.height);
if(node.child != null) PrintAtariResourceTree(node.child, level + 1);
if(node.sibling != null) PrintAtariResourceTree(node.sibling, level);
}
2017-10-03 13:26:49 +01:00
}
2018-02-25 03:08:28 +00:00
}