示例#1
0
        public static async Task <Imports> GetAsync(PortableExecutableImage image)
        {
            var directory = await ImportDirectory.GetAsync(image).ConfigureAwait(false);

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

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

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

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

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

            return(await GetAsync(image, ilt, hnt).ConfigureAwait(false));
        }
示例#2
0
        public static async Task <ImportHintNameTable> GetAsync(PortableExecutableImage image, ImportDirectory directory = null)
        {
            if (directory == null)
            {
                directory = await ImportDirectory.GetAsync(image).ConfigureAwait(false);
            }

            var entries = new Dictionary <uint, Tuple <ulong, uint, ushort, string, bool> >();
            var ilt     = await ImportAddressTables.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 ImportHintNameTable(image, directory.DataDirectory, location, entries.Values.ToArray());

            return(result);
        }
示例#3
0
        private static async Task <ImportAddressTables> GetTableAsync(PortableExecutableImage image, ImportDirectory directory, Func <ImportDirectoryEntry, uint> thunkHandler)
        {
            if (directory == null)
            {
                directory = await ImportDirectory.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 * (!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 ImportAddressTables(image, directory.DataDirectory, location, tables.ToArray());

            return(result);
        }
示例#4
0
 public static async Task <ImportAddressTables> GetAddressTableAsync(PortableExecutableImage image, ImportDirectory directory = null)
 {
     return(await GetTableAsync(image, directory, (entry) => entry.FirstThunk).ConfigureAwait(false));
 }
示例#5
0
        public static async Task <ImportDirectory> GetAsync(PortableExecutableImage image)
        {
            if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.ImportTable))
            {
                return(null);
            }

            DataDirectory dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.ImportTable];

            if (DataDirectory.IsNullOrEmpty(dataDirectory))
            {
                return(null);
            }

            var calc       = image.GetCalculator();
            var section    = calc.RVAToSection(dataDirectory.VirtualAddress);
            var fileOffset = calc.RVAToOffset(section, dataDirectory.VirtualAddress);
            var stream     = image.GetStream();

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

            var size        = Utils.SizeOf <IMAGE_IMPORT_DESCRIPTOR>();
            var descriptors = new List <Tuple <ulong, IMAGE_IMPORT_DESCRIPTOR> >();

            try
            {
                ulong offset = 0;

                while (true)
                {
                    var descriptor = await stream.ReadStructAsync <IMAGE_IMPORT_DESCRIPTOR>(size).ConfigureAwait(false);

                    if (descriptor.OriginalFirstThunk == 0 && descriptor.FirstThunk == 0)
                    {
                        break;
                    }

                    var tuple = new Tuple <ulong, IMAGE_IMPORT_DESCRIPTOR>(offset, descriptor);

                    offset += size.ToUInt32();

                    descriptors.Add(tuple);
                }
            }
            catch (Exception ex)
            {
                throw new PortableExecutableImageException(image, "Could not read import descriptor from stream.", ex);
            }

            var imageBase = image.NTHeaders.OptionalHeader.ImageBase;
            var totalSize = (descriptors.Count + 1) * size;
            var location  = new Location(image, fileOffset, dataDirectory.VirtualAddress, imageBase + dataDirectory.VirtualAddress, totalSize.ToUInt32(), totalSize.ToUInt32(), section);
            var entries   = new ImportDirectoryEntry[descriptors.Count];

            for (var i = 0; i < descriptors.Count; i++)
            {
                try
                {
                    var entryOffset   = fileOffset + descriptors[i].Item1;
                    var entryRVA      = calc.OffsetToRVA(entryOffset);
                    var entryVA       = imageBase + entryRVA;
                    var entryLocation = new Location(image, entryOffset, entryRVA, entryVA, size.ToUInt32(), size.ToUInt32());
                    var name          = await GetNameAsync(calc, stream, descriptors[i].Item2.Name).ConfigureAwait(false);

                    entries[i] = new ImportDirectoryEntry(image, entryLocation, descriptors[i].Item2, name);
                }
                catch (Exception ex)
                {
                    throw new PortableExecutableImageException(image, "Could not read import library name from stream.", ex);
                }
            }

            var result = new ImportDirectory(image, dataDirectory, location, entries);

            return(result);
        }