Example #1
0
        public static async Task <DelayedImports> GetAsync(PortableExecutableImage image)
        {
            var directory = await DelayedImportDirectory.GetAsync(image).ConfigureAwait(false);

            if (directory == null)
            {
                return(null);
            }

            var ilt = await DelayedImportAddressTables.GetLookupTableAsync(image, directory).ConfigureAwait(false);

            if (ilt == null)
            {
                return(null);
            }

            var hnt = await DelayedImportHintNameTable.GetAsync(image, directory).ConfigureAwait(false);

            if (hnt == null)
            {
                return(null);
            }

            return(await GetAsync(image, ilt, hnt).ConfigureAwait(false));
        }
Example #2
0
        public static async Task <DelayedImports> GetAsync(PortableExecutableImage image, DelayedImportAddressTables ilt, DelayedImportHintNameTable hnt)
        {
            var libraries = new List <DelayedImportLibrary>();
            var calc      = image.GetCalculator();
            var stream    = image.GetStream();

            foreach (var table in ilt)
            {
                var builder = new StringBuilder(256);
                var offset  = calc.RVAToOffset(table.DirectoryEntry.Name);

                stream.Seek(offset.ToInt64(), SeekOrigin.Begin);

                while (true)
                {
                    var b = await stream.ReadByteAsync().ConfigureAwait(false);

                    if (b <= 0)
                    {
                        break;
                    }

                    builder.Append((char)b);
                }

                var name      = builder.ToString();
                var functions = new List <ImportLibraryFunction>(table.Count);

                foreach (var entry in table)
                {
                    ImportLibraryFunction function = null;

                    if (entry.IsOrdinal)
                    {
                        function = new ImportLibraryOrdinalFunction(entry, entry.Ordinal);
                    }
                    else
                    {
                        var hintEntry = hnt.FirstOrDefault(e => e.Location.RelativeVirtualAddress == entry.Address);

                        if (hintEntry != null)
                        {
                            function = new ImportLibraryNamedFunction(entry, hintEntry);
                        }
                    }

                    if (function != null)
                    {
                        functions.Add(function);
                    }
                }

                var library = new DelayedImportLibrary(functions.ToArray(), name);

                libraries.Add(library);
            }

            var imports = new DelayedImports(libraries.ToArray());

            return(imports);
        }
Example #3
0
        public static async Task <DelayedImportHintNameTable> GetAsync(PortableExecutableImage image, DelayedImportDirectory directory = null)
        {
            if (directory == null)
            {
                directory = await DelayedImportDirectory.GetAsync(image).ConfigureAwait(false);
            }

            var entries = new Dictionary <uint, Tuple <ulong, uint, ushort, string, bool> >();
            var ilt     = await DelayedImportAddressTables.GetLookupTableAsync(image, directory).ConfigureAwait(false);

            var calc   = image.GetCalculator();
            var stream = image.GetStream();

            foreach (var table in ilt)
            {
                foreach (var entry in table)
                {
                    if (entry.Address == 0)
                    {
                        continue;
                    }

                    if (entries.ContainsKey(entry.Address))
                    {
                        continue;
                    }

                    if (!entry.IsOrdinal)
                    {
                        var    offset   = calc.RVAToOffset(entry.Address);
                        var    size     = 0u;
                        var    isPadded = false;
                        ushort hint     = 0;
                        var    name     = new StringBuilder(256);

                        stream.Seek(offset.ToInt64(), SeekOrigin.Begin);

                        hint = await stream.ReadUInt16Async().ConfigureAwait(false);

                        size += sizeof(ushort);

                        while (true)
                        {
                            var b = await stream.ReadByteAsync().ConfigureAwait(false);

                            size++;

                            if (b <= 0)
                            {
                                break;
                            }

                            name.Append((char)b);
                        }

                        if (size % 2 != 0)
                        {
                            isPadded = true;
                            size++;
                        }

                        var tuple = new Tuple <ulong, uint, ushort, string, bool>(offset, size, hint, name.ToString(), isPadded);

                        entries.Add(entry.Address, tuple);
                    }
                }
            }

            Location location;

            if (entries.Count > 0)
            {
                var firstEntry   = entries.Values.MinBy(tuple => tuple.Item1);
                var lastEntry    = entries.Values.MaxBy(tuple => tuple.Item1);
                var tableOffset  = firstEntry.Item1;
                var tableSize    = ((lastEntry.Item1 + lastEntry.Item2) - tableOffset).ToUInt32();
                var tableRVA     = calc.OffsetToRVA(tableOffset);
                var tableVA      = image.NTHeaders.OptionalHeader.ImageBase + tableRVA;
                var tableSection = calc.RVAToSection(tableRVA);

                location = new Location(image, tableOffset, tableRVA, tableVA, tableSize, tableSize, tableSection);
            }
            else
            {
                location = new Location(image, 0, 0, 0, 0, 0, null);
            }

            var result = new DelayedImportHintNameTable(image, directory.DataDirectory, location, entries.Values.ToArray());

            return(result);
        }
Example #4
0
 public static DelayedImports Get(PortableExecutableImage image, DelayedImportAddressTables ilt, DelayedImportHintNameTable hnt)
 {
     return(GetAsync(image, ilt, hnt).GetAwaiter().GetResult());
 }
Example #5
0
        private static async Task <DelayedImportAddressTables> GetTableAsync(PortableExecutableImage image, DelayedImportDirectory directory, Func <DelayedImportDirectoryEntry, uint> thunkHandler)
        {
            if (directory == null)
            {
                directory = await DelayedImportDirectory.GetAsync(image).ConfigureAwait(false);
            }

            var calc   = image.GetCalculator();
            var stream = image.GetStream();
            var tables = new List <Tuple <uint, ulong[], ImportDirectoryEntryBase> >();

            foreach (var dirEntry in directory)
            {
                var thunk = thunkHandler(dirEntry);

                if (thunk == 0)
                {
                    continue;
                }

                var entries = new List <ulong>();
                var offset  = calc.RVAToOffset(thunk);

                stream.Seek(offset.ToInt64(), SeekOrigin.Begin);

                while (true)
                {
                    var entry = (!image.Is64Bit ? await stream.ReadUInt32Async().ConfigureAwait(false) : await stream.ReadUInt64Async().ConfigureAwait(false));

                    entries.Add(entry);

                    if (entry == 0)
                    {
                        break;
                    }
                }

                var table = new Tuple <uint, ulong[], ImportDirectoryEntryBase>(thunk, entries.ToArray(), dirEntry);

                tables.Add(table);
            }

            var rva = 0u;

            if (tables.Count > 0)
            {
                rva = tables.MinBy(table => table.Item1).Item1;
            }

            var imageBase  = image.NTHeaders.OptionalHeader.ImageBase;
            var va         = imageBase + rva;
            var fileOffset = calc.RVAToOffset(rva);
            var fileSize   = 0ul;

            foreach (var table in tables)
            {
                var size = (table.Item2.Length + 1) * (!image.Is64Bit ? sizeof(uint) : sizeof(ulong));

                fileSize += size.ToUInt32();
            }

            var section  = calc.RVAToSection(rva);
            var location = new Location(image, fileOffset, rva, va, fileSize, fileSize, section);
            var result   = new DelayedImportAddressTables(image, directory.DataDirectory, location, tables.ToArray());

            return(result);
        }