Exemple #1
0
        public PeContainer(string filename, ushort groupIconName)
        {
            ValidateFilename(filename);

            // load pe
            var datafile = PInvoke.LoadDatafile(filename);

            if (datafile == IntPtr.Zero)
            {
                throw new Win32Exception("Unable to load datafile", PInvoke.GetLastWin32Exception());
            }

            using (var disposableUpdate = new PInvoke.DisposableHandle(datafile, PInvoke.FreeLibrary))
            {
                // load group icon data
                var groupIconBytes = PInvoke.LoadResourceBytes(datafile,
                                                               (ushort)PInvoke.ResourceType.GROUP_ICON, groupIconName);

                // parse directory from data
                Directory = new PeDirectory(groupIconBytes);

                Images = new IconImage[Directory.Entries.Length];

                // parse images from data
                for (var i = 0; i < Directory.Entries.Length; i++)
                {
                    var imageBytes = PInvoke.LoadResourceBytes(datafile,
                                                               (ushort)PInvoke.ResourceType.ICON, Directory.Entries[i].Id);

                    Images[i] = new IconImage(imageBytes);
                }

                disposableUpdate.SuppressDispose();
            }
        }
Exemple #2
0
        private static void WriteDeleteOutput(DeleteArgs args)
        {
            // try copy pe
            TryCopySource(args.SourcePath, args.OutputPath);

            // update pe
            var updateHandle = BeginUpdateResource(args.OutputPath);

            using (var updateDisposable = new PInvoke.DisposableHandle(updateHandle,
                                                                       h => PInvoke.DiscardUpdateResource(updateHandle)))
            {
                DeleteResource(updateHandle, args.ResourceType,
                               args.ResourceName, args.OutputPath);

                CompleteUpdateResource(updateHandle, args.OutputPath);

                updateDisposable.SuppressDispose();
            }
        }
Exemple #3
0
        private static void WriteInjectOutput(InjectArgs args)
        {
            // load resource data
            var resourceData = ReadResource(args.ResourcePath);

            // try to copy pe
            TryCopySource(args.SourcePath, args.OutputPath);

            // update pe
            var updateHandle = BeginUpdateResource(args.OutputPath);

            using (var updateDisposable = new PInvoke.DisposableHandle(updateHandle,
                                                                       h => PInvoke.DiscardUpdateResource(updateHandle)))
            {
                UpdateResource(updateHandle, args.ResourceType,
                               args.ResourceName, resourceData, args.OutputPath);

                CompleteUpdateResource(updateHandle, args.OutputPath);

                updateDisposable.SuppressDispose();
            }
        }
Exemple #4
0
        public void ToFile(string filename, ushort groupIconName,
                           bool arrange = true, bool overwrite = false)
        {
            ValidateFilename(filename);
            Validate();

            var oldDirectory = GetOldDirectory(filename, groupIconName);

            if (overwrite && oldDirectory != null)
            {
                throw new ArgumentException("Group Icon already exists", "groupIconName");
            }

            if (arrange)
            {
                Arrange(filename, groupIconName);
            }
            else
            {
                var indexedEntries = Directory.Entries.
                                     Select((e, i) => new KeyValuePair <int, PeDirectoryEntry>(i, e)).ToArray();
                if (indexedEntries.Any(ie1 => indexedEntries.Any(ie2 =>
                                                                 ie1.Key != ie2.Key && ie1.Value.Id == ie2.Value.Id)))
                {
                    throw new InvalidOperationException("Directory Entries contain the same Id");
                }
            }

            var datafile = PInvoke.LoadDatafile(filename);

            if (datafile == IntPtr.Zero)
            {
                throw new Win32Exception("Unable to load datafile", PInvoke.GetLastWin32Exception());
            }

            var busyIconNames = GetBusyIconNames(filename, groupIconName);

            if (!arrange)
            {
                if (busyIconNames.Any(n => Directory.Entries.Any(e => e.Id == n)))
                {
                    throw new InvalidOperationException("Datafile already contains icons with Directory Entries Id");
                }
            }

            var updateHandle = PInvoke.BeginUpdateResource(filename);

            if (updateHandle == IntPtr.Zero)
            {
                throw new Win32Exception("Unable to begin update datafile", PInvoke.GetLastWin32Exception());
            }

            using (var disposableUpdate = new PInvoke.DisposableHandle(updateHandle, PInvoke.DiscardUpdateResource))
            {
                var groupIconBytes = Directory.ToBytes();

                // update group icon
                if (!PInvoke.UpdateResource(updateHandle, (ushort)PInvoke.ResourceType.GROUP_ICON,
                                            groupIconName, groupIconBytes))
                {
                    throw new Win32Exception("Unable to update group icon", PInvoke.GetLastWin32Exception());
                }

                // update icons
                for (var i = 0; i < Directory.Entries.Length; i++)
                {
                    if (!PInvoke.UpdateResource(updateHandle, (ushort)PInvoke.ResourceType.ICON,
                                                Directory.Entries[i].Id, Images[i].ToBytes()))
                    {
                        throw new Win32Exception("Unable to update icon", PInvoke.GetLastWin32Exception());
                    }
                }

                // delete icons
                if (oldDirectory != null)
                {
                    var deleteNames = oldDirectory.Entries.Select(e => e.Id).Except(Directory.Entries.Select(e => e.Id)).ToArray();
                    foreach (var deleteName in deleteNames)
                    {
                        if (!PInvoke.DeleteResource(updateHandle, (ushort)PInvoke.ResourceType.ICON, deleteName))
                        {
                            throw new Win32Exception("Unable to remove icon", PInvoke.GetLastWin32Exception());
                        }
                    }
                }

                if (!PInvoke.CompleteUpdateResource(updateHandle))
                {
                    throw new Win32Exception("Unable to complete update datafile", PInvoke.GetLastWin32Exception());
                }

                disposableUpdate.SuppressDispose();
            }
        }