Ejemplo n.º 1
0
        protected void OnBtnLoadClick(object sender, EventArgs e)
        {
            txtFile.Text        = "";
            txtType.Text        = "";
            txtInformation.Text = "";
            cmbArch.Items.Clear();
            lblSubsystem.Visible    = false;
            txtSubsystem.Visible    = false;
            tabStrings.Visible      = false;
            tabGemResources.Visible = false;
            tabSegments.Visible     = false;
            tabNeResources.Visible  = false;
            tabLeVxdVersion.Visible = false;
            tabLxResources.Visible  = false;
            tabPeResources.Visible  = false;
            tabBeResources.Visible  = false;

            OpenFileDialog dlgOpen = new OpenFileDialog {
                Title = "Choose executable file", MultiSelect = false
            };

            if (dlgOpen.ShowDialog(this) != DialogResult.Ok)
            {
                return;
            }

            txtFile.Text        = dlgOpen.FileName;
            txtInformation.Text = "";
            txtOs.Text          = "";
            txtSubsystem.Text   = "";
            txtType.Text        = "";

            IExecutable mzExe         = new MZ(dlgOpen.FileName);
            IExecutable neExe         = new libexeinfo.NE(dlgOpen.FileName);
            IExecutable stExe         = new AtariST(dlgOpen.FileName);
            IExecutable lxExe         = new libexeinfo.LX(dlgOpen.FileName);
            IExecutable coffExe       = new COFF(dlgOpen.FileName);
            IExecutable peExe         = new libexeinfo.PE(dlgOpen.FileName);
            IExecutable geosExe       = new Geos(dlgOpen.FileName);
            IExecutable elfExe        = new ELF(dlgOpen.FileName);
            IExecutable recognizedExe = null;

            if (mzExe.Recognized)
            {
                recognizedExe = mzExe;
                if (((MZ)mzExe).ResourceObjectRoots != null && ((MZ)mzExe).ResourceObjectRoots.Any())
                {
                    tabGemResources.Update(((MZ)mzExe).ResourceObjectRoots, ((MZ)mzExe).GemColorIcons);
                    tabGemResources.Visible = true;
                }
            }

            if (neExe.Recognized)
            {
                recognizedExe = neExe;
                if (((libexeinfo.NE)neExe).Resources.types != null && ((libexeinfo.NE)neExe).Resources.types.Any())
                {
                    tabNeResources.Update(((libexeinfo.NE)neExe).Resources.types,
                                          ((libexeinfo.NE)neExe).Header.target_os);
                    tabNeResources.Visible = true;
                }
            }
            else if (lxExe.Recognized)
            {
                recognizedExe = lxExe;
                if (((libexeinfo.LX)lxExe).WinVersion != null)
                {
                    tabLeVxdVersion.Visible = true;
                    tabLeVxdVersion.Update(((libexeinfo.LX)lxExe).WinVersion);
                }

                if (((libexeinfo.LX)lxExe).neFormatResourceTable.types != null &&
                    ((libexeinfo.LX)lxExe).neFormatResourceTable.types.Any())
                {
                    tabLxResources.Update(((libexeinfo.LX)lxExe).neFormatResourceTable.types);
                    tabLxResources.Visible = true;
                }
            }
            else if (peExe.Recognized)
            {
                recognizedExe = peExe;
                if (((libexeinfo.PE)peExe).WindowsResourcesRoot?.children != null)
                {
                    tabPeResources.Update(((libexeinfo.PE)peExe).WindowsResourcesRoot);
                    tabPeResources.Visible = true;
                }

                if (((libexeinfo.PE)peExe).BeosResources != null)
                {
                    tabBeResources.Update(((libexeinfo.PE)peExe).BeosResources, peExe.IsBigEndian);
                    tabBeResources.Visible = true;
                }
            }
            else if (stExe.Recognized)
            {
                recognizedExe = stExe;
                if (((AtariST)stExe).ResourceObjectRoots != null && ((AtariST)stExe).ResourceObjectRoots.Any())
                {
                    tabGemResources.Update(((AtariST)stExe).ResourceObjectRoots, ((AtariST)stExe).GemColorIcons);
                    tabGemResources.Visible = true;
                }
            }
            else if (coffExe.Recognized)
            {
                recognizedExe = coffExe;
            }
            else if (elfExe.Recognized)
            {
                recognizedExe = elfExe;
            }
            else if (geosExe.Recognized)
            {
                recognizedExe = geosExe;
            }
            else
            {
                txtType.Text = "Format not recognized";
            }

            if (recognizedExe == null)
            {
                return;
            }

            txtType.Text        = recognizedExe.Type;
            txtInformation.Text = recognizedExe.Information;
            foreach (Architecture arch in recognizedExe.Architectures)
            {
                cmbArch.Items.Add(Enums.ArchitectureName.FirstOrDefault(ar => ar.arch == arch).longName);
            }
            cmbArch.SelectedIndex = 0;

            if (recognizedExe.RequiredOperatingSystem.MajorVersion > 0)
            {
                txtOs.Text = $"{recognizedExe.RequiredOperatingSystem.Name}" +
                             $" {recognizedExe.RequiredOperatingSystem.MajorVersion}" +
                             $".{recognizedExe.RequiredOperatingSystem.MinorVersion}";
            }
            else
            {
                txtOs.Text = recognizedExe.RequiredOperatingSystem.Name;
            }

            if (!string.IsNullOrEmpty(recognizedExe.RequiredOperatingSystem.Subsystem))
            {
                lblSubsystem.Visible = true;
                txtSubsystem.Visible = true;
                txtSubsystem.Text    = recognizedExe.RequiredOperatingSystem.Subsystem;
            }

            if (recognizedExe.Strings != null && recognizedExe.Strings.Any())
            {
                tabStrings.Update(recognizedExe.Strings);
                tabStrings.Visible = true;
            }

            if (recognizedExe.Segments != null && recognizedExe.Segments.Any())
            {
                tabSegments.Update(recognizedExe.Segments);
                tabSegments.Visible = true;
            }
        }
Ejemplo n.º 2
0
        // TODO: How to know VxD structure offset
        void Initialize()
        {
            Recognized = false;
            if (BaseStream == null)
            {
                return;
            }

            BaseExecutable = new MZ(BaseStream);
            if (!BaseExecutable.Recognized)
            {
                return;
            }

            if (BaseExecutable.Header.new_offset >= BaseStream.Length)
            {
                return;
            }

            BaseStream.Seek(BaseExecutable.Header.new_offset, SeekOrigin.Begin);
            byte[] buffer = new byte[Marshal.SizeOf(typeof(LXHeader))];
            BaseStream.Read(buffer, 0, buffer.Length);
            IntPtr hdrPtr = Marshal.AllocHGlobal(buffer.Length);

            Marshal.Copy(buffer, 0, hdrPtr, buffer.Length);
            Header = (LXHeader)Marshal.PtrToStructure(hdrPtr, typeof(LXHeader));
            Marshal.FreeHGlobal(hdrPtr);
            Recognized = Header.signature == SIGNATURE || Header.signature == SIGNATURE16;

            if (!Recognized)
            {
                return;
            }

            Type        = Header.signature == SIGNATURE16 ? "Linear Executable (LE)" : "Linear eXecutable (LX)";
            IsBigEndian = Header.byte_order == 1 || Header.word_order == 1;
            List <string> strings = new List <string>();

            OperatingSystem reqOs = new OperatingSystem();

            switch (Header.os_type)
            {
            case TargetOS.OS2:
                reqOs.Name = "OS/2";
                if (Header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
                    !Header.module_flags.HasFlag(ModuleFlags.PMCompatible) ||
                    !Header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
                    Header.module_flags.HasFlag(ModuleFlags.PMCompatible))
                {
                    reqOs.Subsystem = "Console";
                }
                else if (Header.module_flags.HasFlag(ModuleFlags.PMIncompatible) &&
                         Header.module_flags.HasFlag(ModuleFlags.PMCompatible))
                {
                    reqOs.Subsystem = "Presentation Manager";
                }
                break;

            case TargetOS.Windows:
            case TargetOS.Win32:
            case TargetOS.Unknown:
                reqOs.Name = "Windows";
                break;

            case TargetOS.DOS:
                reqOs.Name = "Windows";
                break;

            default:
                reqOs.Name = $"Unknown code {(ushort)Header.os_type}";
                break;
            }

            RequiredOperatingSystem = reqOs;

            if (Header.resident_names_off != 0)
            {
                ResidentNames =
                    GetResidentStrings(BaseStream, BaseExecutable.Header.new_offset, Header.resident_names_off);

                if (ResidentNames.Length >= 1)
                {
                    ModuleName = ResidentNames[0].name;

                    if (ResidentNames.Length > 1)
                    {
                        NE.ResidentName[] newResidentNames = new NE.ResidentName[ResidentNames.Length - 1];
                        Array.Copy(ResidentNames, 1, newResidentNames, 0, ResidentNames.Length - 1);
                        ResidentNames = newResidentNames;
                    }
                    else
                    {
                        ResidentNames = null;
                    }
                }
            }

            if (Header.nonresident_name_table_len > 0)
            {
                NonResidentNames = GetResidentStrings(BaseStream, 0, Header.nonresident_name_table_off);

                if (NonResidentNames.Length >= 1)
                {
                    ModuleDescription = NonResidentNames[0].name;

                    if (NonResidentNames.Length > 1)
                    {
                        NE.ResidentName[] newNonResidentNames = new NE.ResidentName[NonResidentNames.Length - 1];
                        Array.Copy(NonResidentNames, 1, newNonResidentNames, 0, NonResidentNames.Length - 1);
                        NonResidentNames = newNonResidentNames;
                    }
                    else
                    {
                        NonResidentNames = null;
                    }
                }
            }

            if (Header.import_module_table_off != 0 && Header.import_module_entries > 0)
            {
                BaseStream.Position = Header.import_module_table_off + BaseExecutable.Header.new_offset;
                ImportedNames       = new string[Header.import_module_entries];
                for (int i = 0; i < Header.import_module_entries; i++)
                {
                    int len = BaseStream.ReadByte();
                    buffer = new byte[len];
                    BaseStream.Read(buffer, 0, len);
                    ImportedNames[i] = Encoding.ASCII.GetString(buffer);
                }
            }

            if (!string.IsNullOrEmpty(ModuleName))
            {
                strings.Add(ModuleName);
            }
            if (!string.IsNullOrEmpty(ModuleDescription))
            {
                strings.Add(ModuleDescription);
            }

            objectTableEntries     = new ObjectTableEntry[Header.obj_no];
            objectPageTableEntries = new ObjectPageTableEntry[Header.module_pages_no];

            BaseStream.Position = Header.obj_table_off + BaseExecutable.Header.new_offset;
            buffer = new byte[Marshal.SizeOf(typeof(ObjectTableEntry))];
            for (int i = 0; i < Header.obj_no; i++)
            {
                BaseStream.Read(buffer, 0, buffer.Length);
                objectTableEntries[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <ObjectTableEntry>(buffer);
            }

            BaseStream.Position = Header.obj_page_table_off + BaseExecutable.Header.new_offset;

            if (Header.signature == SIGNATURE16)
            {
                buffer = new byte[Marshal.SizeOf(typeof(ObjectPageTableEntry16))];
                for (int i = 0; i < Header.module_pages_no; i++)
                {
                    BaseStream.Read(buffer, 0, buffer.Length);
                    ObjectPageTableEntry16 page16 =
                        BigEndianMarshal.ByteArrayToStructureLittleEndian <ObjectPageTableEntry16>(buffer);

                    int pageNo = (page16.High << 8) + page16.Low;

                    objectPageTableEntries[i] = new ObjectPageTableEntry
                    {
                        DataSize       = (ushort)Header.page_size,
                        Flags          = (PageTableAttributes)page16.Flags,
                        PageDataOffset = (uint)((pageNo - 1) * Header.page_size)
                    };
                }
            }
            else
            {
                buffer = new byte[Marshal.SizeOf(typeof(ObjectPageTableEntry))];
                for (int i = 0; i < Header.module_pages_no; i++)
                {
                    BaseStream.Read(buffer, 0, buffer.Length);
                    objectPageTableEntries[i] =
                        BigEndianMarshal.ByteArrayToStructureLittleEndian <ObjectPageTableEntry>(buffer);
                }
            }

            int debugSections   = 0;
            int winrsrcSections = 0;

            if (Header.debug_info_len > 0)
            {
                debugSections = 1;
            }
            if (Header.win_res_len > 0)
            {
                winrsrcSections = 1;
            }

            Segment[] sections = new Segment[objectTableEntries.Length + debugSections + winrsrcSections];
            for (int i = 0; i < objectTableEntries.Length; i++)
            {
                sections[i] = new Segment {
                    Flags = $"{objectTableEntries[i].ObjectFlags}"
                };
                if (objectTableEntries[i].ObjectFlags.HasFlag(ObjectFlags.Resource))
                {
                    sections[i].Name = ".rsrc";
                }
                else if (objectTableEntries[i].ObjectFlags.HasFlag(ObjectFlags.Executable))
                {
                    sections[i].Name = ".text";
                }
                else if (!objectTableEntries[i].ObjectFlags.HasFlag(ObjectFlags.Writable))
                {
                    sections[i].Name = ".rodata";
                }
                else if (StringHandlers.CToString(objectTableEntries[i].Name).ToLower() == "bss")
                {
                    sections[i].Name = ".bss";
                }
                else if (!string.IsNullOrWhiteSpace(StringHandlers.CToString(objectTableEntries[i].Name).Trim()))
                {
                    sections[i].Name = StringHandlers.CToString(objectTableEntries[i].Name).Trim();
                }
                else
                {
                    sections[i].Name = ".data";
                }

                if (objectTableEntries[i].PageTableEntries == 0 ||
                    objectTableEntries[i].PageTableIndex > objectPageTableEntries.Length)
                {
                    sections[i].Size = objectTableEntries[i].VirtualSize;
                    continue;
                }

                int shift = (int)(Header.signature == SIGNATURE16 ? 0 : Header.page_off_shift);

                if (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1]
                    .Flags.HasFlag(PageTableAttributes.IteratedDataPage))
                {
                    sections[i].Offset =
                        (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1].PageDataOffset << shift) +
                        Header.obj_iter_pages_off;
                }
                else if (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1]
                         .Flags.HasFlag(PageTableAttributes.LegalPhysicalPage))
                {
                    sections[i].Offset =
                        (objectPageTableEntries[objectTableEntries[i].PageTableIndex - 1].PageDataOffset << shift) +
                        Header.data_pages_off;
                }
                else
                {
                    sections[i].Offset = 0;
                }

                sections[i].Size = 0;
                for (int j = 0; j < objectTableEntries[i].PageTableEntries; j++)
                {
                    sections[i].Size += objectPageTableEntries[j + objectTableEntries[i].PageTableIndex - 1].DataSize;
                }

                if (sections[i].Offset + sections[i].Size > BaseStream.Length)
                {
                    sections[i].Size = BaseStream.Length - sections[i].Offset;
                }
            }

            if (winrsrcSections > 0)
            {
                sections[sections.Length - debugSections - winrsrcSections] = new Segment
                {
                    Name   = ".rsrc",
                    Size   = Header.win_res_len,
                    Offset = Header.win_res_off
                }
            }
            ;

            if (debugSections > 0)
            {
                sections[sections.Length - debugSections] = new Segment
                {
                    Name   = ".debug",
                    Size   = Header.debug_info_len,
                    Offset = Header.debug_info_off
                }
            }
            ;

            // It only contains a RT_VERSION resource prefixed by some 12-byte header I can't find information about, so let's just skip it.
            if (winrsrcSections > 0)
            {
                buffer = new byte[Header.win_res_len];
                BaseStream.Position = Header.win_res_off + 12;
                BaseStream.Read(buffer, 0, buffer.Length);
                WinVersion = new NE.Version(buffer);
                strings.AddRange(from s in WinVersion.StringsByLanguage from k in s.Value select k.Value);
            }

            resources           = new ResourceTableEntry[Header.resource_entries];
            BaseStream.Position = Header.resource_table_off + BaseExecutable.Header.new_offset;
            buffer = new byte[Marshal.SizeOf(typeof(ResourceTableEntry))];
            for (int i = 0; i < resources.Length; i++)
            {
                BaseStream.Read(buffer, 0, buffer.Length);
                resources[i] = BigEndianMarshal.ByteArrayToStructureLittleEndian <ResourceTableEntry>(buffer);
            }

            SortedDictionary <ResourceTypes, List <NE.Resource> > os2Resources =
                new SortedDictionary <ResourceTypes, List <NE.Resource> >();

            for (int i = 0; i < resources.Length; i++)
            {
                os2Resources.TryGetValue(resources[i].type, out List <NE.Resource> thisResourceType);

                if (thisResourceType == null)
                {
                    thisResourceType = new List <NE.Resource>();
                }

                NE.Resource thisResource = new NE.Resource
                {
                    id         = resources[i].id,
                    name       = $"{resources[i].id}",
                    flags      = 0,
                    dataOffset = (uint)(sections[resources[i].obj_no - 1].Offset + resources[i].offset),
                    length     = resources[i].size
                };

                thisResource.data   = new byte[thisResource.length];
                BaseStream.Position = thisResource.dataOffset;
                BaseStream.Read(thisResource.data, 0, thisResource.data.Length);

                thisResourceType.Add(thisResource);
                os2Resources.Remove(resources[i].type);
                os2Resources.Add(resources[i].type, thisResourceType);
            }

            if (os2Resources.Count > 0)
            {
                neFormatResourceTable = new NE.ResourceTable();
                int counter = 0;
                neFormatResourceTable.types = new NE.ResourceType[os2Resources.Count];
                foreach (KeyValuePair <ResourceTypes, List <NE.Resource> > kvp in os2Resources)
                {
                    neFormatResourceTable.types[counter].count     = (ushort)kvp.Value.Count;
                    neFormatResourceTable.types[counter].id        = (ushort)kvp.Key;
                    neFormatResourceTable.types[counter].name      = Resources.IdToName((ushort)kvp.Key);
                    neFormatResourceTable.types[counter].resources = kvp.Value.OrderBy(r => r.id).ToArray();
                    counter++;
                }

                foreach (NE.ResourceType rtype in neFormatResourceTable.types)
                {
                    if (rtype.name != "RT_STRING")
                    {
                        continue;
                    }

                    strings.AddRange(NE.GetOs2Strings(rtype));
                }
            }

            Segments = sections;
            Strings  = strings;
        }