예제 #1
0
        /// <summary>
        /// Open the specified file.
        /// </summary>
        /// <param name="file"></param>
        /// <returns>True if the opened file was a Reko project.</returns>
        public bool OpenBinary(string file, string outputDir)
        {
            var ldr = Services.RequireService <ILoader>();

            this.Decompiler = CreateDecompiler(ldr);
            var  svc          = Services.RequireService <IWorkerDialogService>();
            bool isOldProject = false;

            svc.StartBackgroundWork("Loading program", delegate()
            {
                isOldProject = Decompiler.Load(file, outputDir);
            });
            if (Decompiler.Project == null)
            {
                return(false);
            }

            ProgramResourceGroup prg = Decompiler.Project.Programs[0].Resources;

            // Process the resources adn save as files
            ProcessResources(prg, outputDir);

            var browserSvc = Services.RequireService <IProjectBrowserService>();

            browserSvc.Load(Decompiler.Project);
            ShowLowLevelWindow();
            return(isOldProject);
        }
예제 #2
0
        public bool OpenBinaryAs(string file, string outputDir, LoadDetails details)
        {
            var ldr = Services.RequireService <ILoader>();

            this.Decompiler = CreateDecompiler(ldr);
            IWorkerDialogService svc = Services.RequireService <IWorkerDialogService>();

            svc.StartBackgroundWork("Loading program", delegate()
            {
                Program program          = Decompiler.LoadRawImage(file, outputDir, details);
                ProgramResourceGroup prg = program.Resources;

                // Process the resources adn save as files
                ProcessResources(prg, outputDir);
            });
            var browserSvc = Services.RequireService <IProjectBrowserService>();

            if (Decompiler.Project != null)
            {
                browserSvc.Load(Decompiler.Project);
                ShowLowLevelWindow();
            }
            else
            {
                browserSvc.Clear();
            }
            return(false);   // We never open projects this way.
        }
예제 #3
0
        /// <summary>
        /// Build icons out of the icon groups + icons.
        /// </summary>
        /// <param name="iconGroups"></param>
        /// <param name="icons"></param>
        private void PostProcessIcons(
            ProgramResourceGroup iconGroups, 
            ProgramResourceGroup icons, 
            Dictionary<ushort, ProgramResourceInstance> iconIds,
            List<ProgramResource> resources)
        {
            if (icons == null)
            {
                if (iconGroups != null)
                    resources.Remove(iconGroups);
                return;
            }
            if (iconGroups == null)
            {
                if (icons == null)
                    resources.Remove(icons);
                return;
            }

            foreach (ProgramResourceInstance iconGroup in iconGroups.Resources)
            {
                var r = new BinaryReader(new MemoryStream(iconGroup.Bytes));
                var stm = new MemoryStream();
                var w = new BinaryWriter(stm);

                // Copy the group header
                w.Write(r.ReadInt16());
                w.Write(r.ReadInt16());
                short dirEntries = r.ReadInt16();
                w.Write(dirEntries);

                var icIds = new List<Tuple<ushort, int>>();
                for (int i = 0; i < dirEntries; ++i)
                {
                    w.Write(r.ReadInt32());
                    w.Write(r.ReadInt32());
                    w.Write(r.ReadInt32());
                    var iconId = r.ReadUInt16();
                    w.Flush();
                    icIds.Add(Tuple.Create(iconId, (int)stm.Position));
                    w.Write(0);
                }
                foreach (var id in icIds)
                {
                    var icon = iconIds[id.Item1];
                    var icOffset = (int) w.Seek(0, SeekOrigin.Current);
                    w.Seek(id.Item2, SeekOrigin.Begin);
                    w.Write(icOffset);
                    w.Seek(icOffset, SeekOrigin.Begin);
                    w.Write(icon.Bytes);
                }
                iconGroup.Bytes = stm.ToArray();
                iconGroup.Type = "Win16_ICON";
            }
            iconGroups.Name = "ICON";
            resources.Remove(icons);
        }
예제 #4
0
        private void ProcessResources(ProgramResourceGroup prg, string outputDir)
        {
            try
            {
                if (prg.Name == "PE resources")
                {
                    // Create the dir
                    Directory.CreateDirectory(outputDir + "\\resources");
                    foreach (ProgramResourceGroup pr in prg.Resources)
                    {
                        switch (pr.Name)
                        {
                        case "CURSOR":
                        {
                            WriteResourceFile(outputDir + "\\resources", "Cursor", ".cur", pr);
                        }
                        break;

                        case "BITMAP":
                        {
                            WriteResourceFile(outputDir + "\\resources", "Bitmap", ".bmp", pr);
                        }
                        break;

                        case "ICON":
                        {
                            WriteResourceFile(outputDir + "\\resources", "Icon", ".ico", pr);
                        }
                        break;

                        case "FONT":
                        {
                            WriteResourceFile(outputDir + "\\resources", "Font", ".bin", pr);
                        }
                        break;

                        case "NEWBITMAP":
                        {
                            WriteResourceFile(outputDir + "\\resources", "NewBitmap", ".bmp", pr);
                        }
                        break;

                        default:
                            break;
                        }
                    }
                }
            }
            catch (Exception)
            {
            }
        }
예제 #5
0
        /// <summary>
        /// Reads a resource directory, starting at the position of the given image
        /// reader.
        /// </summary>
        /// <param name="rdr">A little endian <see cref="EndianImageReader"/>.</param>
        /// <returns>A list of the resources found in the directory.</returns>
        public List <ProgramResource> ReadResourceDirectory(EndianImageReader rdr)
        {
            const uint DIR_MASK     = 0x80000000;
            var        flags        = rdr.ReadUInt32();
            var        date         = rdr.ReadUInt32();
            var        version      = rdr.ReadUInt32();
            var        cNameEntries = rdr.ReadUInt16();
            var        cIdEntries   = rdr.ReadUInt16();
            var        entries      = new List <ProgramResource>();

            // Read the named entries.
            for (int i = 0; i < cNameEntries; ++i)
            {
                var rvaName  = rdr.ReadUInt32();
                var rvaEntry = rdr.ReadUInt32();
                var subRdr   = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK));
                if ((rvaEntry & DIR_MASK) == 0)
                {
                    throw new BadImageFormatException();
                }
                if ((rvaName & DIR_MASK) != 0)
                {
                    var e = new ProgramResourceGroup
                    {
                        //Name = ReadResourceString(rvaName),
                        Name = ReadResourceUtf16leString(rvaResources + (rvaName & ~DIR_MASK)),
                    };
                    e.Resources.AddRange(ReadNameDirectory(subRdr, PeResourceType.FromInt(0)));
                    entries.Add(e);
                }
            }
            // Read the entries accessed by numeric ID.
            for (int i = 0; i < cIdEntries; ++i)
            {
                var id       = rdr.ReadInt32();
                var rvaEntry = rdr.ReadUInt32();
                var subRdr   = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK));
                if ((rvaEntry & DIR_MASK) == 0)
                {
                    throw new BadImageFormatException();
                }
                var rt = PeResourceType.FromInt(id);
                var e  = new ProgramResourceGroup
                {
                    Name = rt.Name
                };
                e.Resources.AddRange(ReadNameDirectory(subRdr, rt));
                entries.Add(e);
            }
            return(entries);
        }
예제 #6
0
        public List <ProgramResource> ReadResourceDirectory(EndianImageReader rdr)
        {
            const uint DIR_MASK     = 0x80000000;
            var        flags        = rdr.ReadUInt32();
            var        date         = rdr.ReadUInt32();
            var        version      = rdr.ReadUInt32();
            var        cNameEntries = rdr.ReadUInt16();
            var        cIdEntries   = rdr.ReadUInt16();
            var        entries      = new List <ProgramResource>();

            for (int i = 0; i < cNameEntries; ++i)
            {
                var rvaName  = rdr.ReadUInt32();
                var rvaEntry = rdr.ReadUInt32();
                var subRdr   = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK));
                if ((rvaEntry & DIR_MASK) == 0)
                {
                    throw new BadImageFormatException();
                }
                if ((rvaName & DIR_MASK) != 0)
                {
                    var e = new ProgramResourceGroup
                    {
                        //Name = ReadResourceString(rvaName),
                        Name = ReadResourceUtf16leString(rvaResources + (rvaName & ~DIR_MASK)),
                    };
                    e.Resources.AddRange(ReadNameDirectory(subRdr, 0));
                    entries.Add(e);
                }
            }
            for (int i = 0; i < cIdEntries; ++i)
            {
                var id       = rdr.ReadUInt32();
                var rvaEntry = rdr.ReadUInt32();
                var subRdr   = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK));
                if ((rvaEntry & DIR_MASK) == 0)
                {
                    throw new BadImageFormatException();
                }
                var e = new ProgramResourceGroup
                {
                    Name = GenerateResourceName(id),
                };
                e.Resources.AddRange(ReadNameDirectory(subRdr, id));
                entries.Add(e);
            }
            return(entries);
        }
예제 #7
0
        public List <ProgramResource> ReadNameDirectory(ImageReader rdr, uint resourceType)
        {
            const uint DIR_MASK     = 0x80000000;
            var        flags        = rdr.ReadUInt32();
            var        date         = rdr.ReadUInt32();
            var        version      = rdr.ReadUInt32();
            var        cNameEntries = rdr.ReadUInt16();
            var        cIdEntries   = rdr.ReadUInt16();
            var        entries      = new List <ProgramResource>();

            for (int i = 0; i < cNameEntries; ++i)
            {
                var rvaName  = rdr.ReadUInt32();
                var rvaEntry = rdr.ReadUInt32();
                var subRdr   = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK));
                if ((rvaEntry & DIR_MASK) == 0)
                {
                    throw new BadImageFormatException();
                }
                var e = new ProgramResourceGroup
                {
                    Name = ReadResourceUtf16leString(rvaResources + (rvaName & ~DIR_MASK)),
                };
                e.Resources.AddRange(ReadLanguageDirectory(subRdr, resourceType, e.Name));
                entries.Add(e);
            }
            for (int i = 0; i < cIdEntries; ++i)
            {
                var id       = rdr.ReadUInt32();
                var rvaEntry = rdr.ReadUInt32();
                var subRdr   = new LeImageReader(imgLoaded, rvaResources + (rvaEntry & ~DIR_MASK));
                if ((rvaEntry & DIR_MASK) == 0)
                {
                    throw new BadImageFormatException();
                }
                var e = new ProgramResourceGroup
                {
                    Name = id.ToString(),
                };
                e.Resources.AddRange(ReadLanguageDirectory(subRdr, resourceType, e.Name));
                entries.Add(e);
            }
            return(entries);
        }
예제 #8
0
        void PostProcessBitmaps(ProgramResourceGroup bitmaps)
        {
            if (bitmaps == null)
                return;
            foreach (ProgramResourceInstance bitmap in bitmaps.Resources)
            {
                var stm = new MemoryStream();
                var bw = new BinaryWriter(stm);

                bw.Write('B');
                bw.Write('M');
                bw.Write(14 + bitmap.Bytes.Length);
                bw.Write(0);
                bw.Write(14);
                bw.Write(bitmap.Bytes, 0, bitmap.Bytes.Length);
                bw.Flush();
                bitmap.Bytes = stm.ToArray();
            }
        }
예제 #9
0
        /// <summary>
        /// Reads in the NE image resources.
        /// </summary>
        //$REFACTOR: resource loading seems to want to belong in a separate file.
        private void LoadResources(List <ProgramResource> resources)
        {
            var    rsrcTable                = new LeImageReader(RawImage, this.lfaNew + offRsrcTable);
            var    rdr                      = rsrcTable.Clone();
            ushort size_shift               = rdr.ReadLeUInt16();
            ProgramResourceGroup bitmaps    = null;
            ProgramResourceGroup iconGroups = null;
            ProgramResourceGroup icons      = null;
            var    iconIds                  = new Dictionary <ushort, ProgramResourceInstance>();
            ushort rsrcType                 = rdr.ReadLeUInt16();

            while (rsrcType != 0)
            {
                var resGrp = new ProgramResourceGroup {
                    Name = GetResourceType(rsrcType)
                };
                if (rsrcType == NE_RSCTYPE_GROUP_ICON)
                {
                    iconGroups = resGrp;
                }
                else if (rsrcType == NE_RSCTYPE_ICON)
                {
                    icons = resGrp;
                }
                else if (rsrcType == NE_RSCTYPE_BITMAP)
                {
                    bitmaps = resGrp;
                }

                ushort typeCount = rdr.ReadLeUInt16();
                uint   resLoader = rdr.ReadLeUInt32();
                for (int count = typeCount; count > 0; --count)
                {
                    ushort nameOffset = rdr.ReadLeUInt16();
                    ushort nameLength = rdr.ReadLeUInt16();
                    ushort nameFlags  = rdr.ReadLeUInt16();
                    ushort nameId     = rdr.ReadLeUInt16();
                    ushort nameHandle = rdr.ReadLeUInt16();
                    ushort nameUsage  = rdr.ReadLeUInt16();

                    string resname;
                    if ((nameId & 0x8000) != 0)
                    {
                        resname = (nameId & ~0x8000).ToString();
                    }
                    else
                    {
                        resname = ReadByteLengthString(rsrcTable, nameId);
                    }

                    var offset  = (uint)nameOffset << size_shift;
                    var rdrRsrc = new LeImageReader(base.RawImage, offset);
                    var rsrc    = rdrRsrc.ReadBytes((uint)nameLength << size_shift);

                    var rsrcInstance = new ProgramResourceInstance
                    {
                        Name  = resname,
                        Type  = "Win16_" + resGrp.Name,
                        Bytes = rsrc,
                    };
                    resGrp.Resources.Add(rsrcInstance);

                    if (rsrcType == NE_RSCTYPE_ICON)
                    {
                        iconIds[(ushort)(nameId & ~0x8000)] = rsrcInstance;
                    }
                }
                resources.Add(resGrp);

                rsrcType = rdr.ReadLeUInt16();
            }

            PostProcessIcons(iconGroups, icons, iconIds, resources);
            PostProcessBitmaps(bitmaps);
        }
예제 #10
0
        private bool WriteResourceFile(IFileSystemService fsSvc, string outputDir, string ResourceType, string ext, ProgramResourceGroup pr)
        {
            var dirPath = Path.Combine(outputDir, ResourceType);

            try
            {
                fsSvc.CreateDirectory(dirPath);
            }
            catch (Exception ex)
            {
                var diagSvc = services.RequireService <IDiagnosticsService>();
                diagSvc.Error(ex, $"Unable to create directory '{dirPath}'.");
                return(false);
            }
            string path = "";

            try
            {
                foreach (ProgramResourceGroup pr1 in pr.Resources)
                {
                    foreach (ProgramResourceInstance pr2 in pr1.Resources)
                    {
                        path = Path.Combine(dirPath, pr1.Name + ext);
                        fsSvc.WriteAllBytes(path, pr2.Bytes);
                    }
                }
            }
            catch (Exception ex)
            {
                var diagSvc = services.RequireService <IDiagnosticsService>();
                diagSvc.Error(ex, $"Unable to write file '{path}'");
                return(false);
            }
            return(true);
        }
예제 #11
0
 private void WriteResourceFile(string outputDir, string ResourceType, string ext, ProgramResourceGroup pr)
 {
     Directory.CreateDirectory(outputDir + "\\" + ResourceType);
     foreach (ProgramResourceGroup pr1 in pr.Resources)
     {
         foreach (ProgramResourceInstance pr2 in pr1.Resources)
         {
             // write the bytes to file
             try
             {
                 using (var fs = new FileStream(outputDir + "\\" + ResourceType + "\\" + pr1.Name + ext, FileMode.Create, FileAccess.Write))
                 {
                     fs.Write(pr2.Bytes, 0, pr2.Bytes.Length);
                 }
             }
             catch (Exception ex)
             {
             }
         }
     }
 }
예제 #12
0
파일: Decompiler.cs 프로젝트: nemerle/reko
 private bool WriteResource(ProgramResource?resource, IFileSystemService fsSvc, string outputDir, string ResourceType, ProgramResourceGroup pr)
 {
     if (resource is ProgramResourceGroup grp)
     {
         outputDir = Path.Combine(outputDir, grp.Name);
         try
         {
             fsSvc.CreateDirectory(outputDir);
         }
         catch (Exception ex)
         {
             eventListener.Error(ex, $"Unable to create directory '{outputDir}'.");
             return(false);
         }
         foreach (var res in grp.Resources)
         {
             if (!WriteResource(res, fsSvc, outputDir, "", null !))
             {
                 return(false);
             }
         }
         return(true);
     }
     else if (resource is ProgramResourceInstance pr2)
     {
         string path = "";
         try
         {
             if (pr2.Bytes != null)
             {
                 var filename = $"{pr2.Type}_{pr2.Name}{pr2.FileExtension}";
                 path = Path.Combine(outputDir, filename);
                 fsSvc.WriteAllBytes(path, pr2.Bytes);
             }
         }
         catch (Exception ex)
         {
             eventListener.Error(ex, $"Unable to write file '{path}'.");
             return(false);
         }
         return(true);
     }
     return(true);
 }
예제 #13
0
        /// <summary>
        /// Reads in the NE image resources.
        /// </summary>
        public List <ProgramResource> LoadResources()
        {
            List <ProgramResource> resources = new List <ProgramResource>();
            var    rsrcTable      = new LeImageReader(RawImage, OffRsrcTable);
            var    rdr            = rsrcTable.Clone();
            ushort size_shift     = rdr.ReadLeUInt16();
            var    resourceGroups = new Dictionary <ResourceType, ProgramResourceGroup>();
            var    iconIds        = new Dictionary <ushort, ProgramResourceInstance>();
            ushort rsrcType       = rdr.ReadLeUInt16();

            while (rsrcType != 0)
            {
                var rt = Win16ResourceType.FromInt(rsrcType);
                if (!resourceGroups.TryGetValue(rt, out var resGrp))
                {
                    resGrp = new ProgramResourceGroup {
                        Name = rt.Name
                    };
                    resourceGroups.Add(rt, resGrp);
                }
                ushort typeCount = rdr.ReadLeUInt16();
                uint   resLoader = rdr.ReadLeUInt32();
                for (int count = typeCount; count > 0; --count)
                {
                    ushort nameOffset = rdr.ReadLeUInt16();
                    ushort nameLength = rdr.ReadLeUInt16();
                    ushort nameFlags  = rdr.ReadLeUInt16();
                    ushort nameId     = rdr.ReadLeUInt16();
                    ushort nameHandle = rdr.ReadLeUInt16();
                    ushort nameUsage  = rdr.ReadLeUInt16();

                    string resname;
                    if ((nameId & 0x8000) != 0)
                    {
                        resname = (nameId & ~0x8000).ToString();
                    }
                    else
                    {
                        resname = ReadByteLengthString(rsrcTable, nameId);
                    }

                    var offset  = (uint)nameOffset << size_shift;
                    var rdrRsrc = new LeImageReader(RawImage, offset);
                    var rsrc    = rdrRsrc.ReadBytes((uint)nameLength << size_shift);

                    var rsrcInstance = new ProgramResourceInstance
                    {
                        Name          = resname,
                        Type          = resGrp.Name,
                        Bytes         = rsrc,
                        FileExtension = rt.FileExtension,
                    };
                    resGrp.Resources.Add(rsrcInstance);

                    if (rt == Win16ResourceType.Icon)
                    {
                        iconIds[(ushort)(nameId & ~0x8000)] = rsrcInstance;
                    }
                }
                resources.Add(resGrp);
                rsrcType = rdr.ReadLeUInt16();
            }

            PostProcessIcons(resourceGroups, iconIds, resources);
            PostProcessBitmaps(resourceGroups);

            return(resources);
        }
예제 #14
0
        /// <summary>
        /// Reads in the NE resources from OS/2.
        /// </summary>
        public List <ProgramResource> LoadOs2Resources(NeImageLoader.NeSegment[] segments, ushort segmentCount, ushort alignmentShift)
        {
            List <ProgramResource> resources = new List <ProgramResource>();
            var rsrcTable = new LeImageReader(RawImage, OffRsrcTable);
            var rdr       = rsrcTable.Clone();

            ResourceTableEntry[] entries = new ResourceTableEntry[ResourceTableEntries];
            for (int i = 0; i < entries.Length; i++)
            {
                entries[i].etype = rdr.ReadUInt16();
                entries[i].ename = rdr.ReadUInt16();
            }

            NeImageLoader.NeSegment[] resourceSegments = new NeImageLoader.NeSegment[ResourceTableEntries];
            Array.Copy(segments, segmentCount - ResourceTableEntries, resourceSegments, 0,
                       ResourceTableEntries);
            NeImageLoader.NeSegment[] realSegments = new NeImageLoader.NeSegment[segmentCount - ResourceTableEntries];
            Array.Copy(segments, 0, realSegments, 0, realSegments.Length);
            segments = realSegments;

            var os2Resources = new SortedDictionary <ushort, ProgramResourceGroup>();

            for (int i = 0; i < entries.Length; i++)
            {
                os2Resources.TryGetValue(entries[i].etype, out ProgramResourceGroup resGrp);
                var rt = Os2ResourceType.FromInt(entries[i].etype);
                if (resGrp == null)
                {
                    resGrp = new ProgramResourceGroup {
                        Name = rt.Name
                    }
                }
                ;

                uint length     = resourceSegments[i].DataLength;
                var  dataOffset = (uint)(resourceSegments[i].DataOffset << alignmentShift);

                if (length == 0)
                {
                    length = 65536;
                }
                if (dataOffset == 0)
                {
                    dataOffset = 65536;
                }

                if ((resourceSegments[i].Flags & (ushort)0x4000) != 0)
                {
                    length <<= alignmentShift;
                }

                var rdrRsrc = new LeImageReader(RawImage, dataOffset);
                var rsrc    = rdrRsrc.ReadBytes(length);

                var rsrcInstance = new ProgramResourceInstance
                {
                    Name          = $"{entries[i].ename}",
                    Type          = "Os2_" + resGrp.Name,
                    Bytes         = rsrc,
                    FileExtension = rt.FileExtension
                };
                resGrp.Resources.Add(rsrcInstance);

                os2Resources.Remove(entries[i].etype);
                os2Resources[entries[i].etype] = resGrp;
            }

            foreach (var kvp in os2Resources)
            {
                resources.Add(kvp.Value);
            }

            return(resources);
        }

        string ReadByteLengthString(EndianImageReader rdr, int offset)
        {
            var clone = rdr.Clone();

            clone.Offset = clone.Offset + offset;
            var len   = clone.ReadByte();
            var abStr = clone.ReadBytes(len);

            return(Encoding.ASCII.GetString(abStr));
        }