Example #1
0
        public void ResolveImports(ExportTable exports)
        {
            if (entry.size == 0)
            {
                Tracing.Log(Tracing.Debug, "// No imports to resolve.");
                return;
            }

            int importOffset = (int)entry.virtualAddress;

            //Tracing.Log(Tracing.Debug, "  import offset={0:x8}", importOffset);
            //
            // start at the importOffset specified above creating and filling out ImportDescriptors
            // There is no indication in the header as to how many descriptors are present.
            // In the last descriptor all fields will be 0; this code checks just the firstChunk field.
            //
            for (;;)
            {
                ImportDescriptor importDescriptor =
                    new ImportDescriptor(mem, ref importOffset);
                if (importDescriptor.firstChunk == 0)
                {
                    return;
                }
                ushort hint = 0;
                String name = null;
                if (importDescriptor.name != 0)
                {
                    name = mem.ReadAsciiZeroString((int)importDescriptor.name);
                }

#if verbose
                Tracing.Log(Tracing.Debug, "//     {0}", name);
                importDescriptor.DumpToStream("//              ");
                Tracing.Log(Tracing.Debug, "//");
#endif
                UIntPtr offsetHintTable = UIntPtr.Zero;

                if (0 == importDescriptor.characteristics)
                {
                    offsetHintTable = (UIntPtr)importDescriptor.characteristics;
                }
                else
                {
                    offsetHintTable = (UIntPtr)importDescriptor.firstChunk;
                }
                UIntPtr offsetIAT = (UIntPtr)importDescriptor.firstChunk;

#if PTR_SIZE_64
                //
                // AIFIX: Add hint logic.
                //

                for (;;)
                {
                    ulong ImportEntry = (ulong)mem.Read64((int)offsetIAT);

                    if (ImportEntry == 0)
                    {
                        break;
                    }

                    if ((ImportEntry >> 63) != 0)
                    {
                        throw new BadImageFormatException("Import Ordinal encountered");
                    }

                    name = mem.ReadAsciiZeroString(((int)(ImportEntry & 0x7FFFFFFF)) + 2);

                    UIntPtr Address;

                    Address = exports.Resolve(hint, name);

                    if (Address == 0)
                    {
                        throw new BadImageFormatException("Import not found");
                    }

                    mem.Write64((int)offsetIAT, (ulong)Address);

                    offsetIAT += 8;
                }
#else
                for (;;)
                {
                    // read elements in the hint array for processing
                    // the hint array terminates when the its content is 0
                    int importByNameEntry = (int)mem.Read32((int)offsetHintTable);
                    if (importByNameEntry == 0)
                    {
                        break;
                    }
#if verbose
                    Tracing.Log(Tracing.Debug, "importByName entry is {0:x8}",
                                importByNameEntry);
#endif
                    int nameStringOffset = importByNameEntry & 0x7fffffff;
                    if ((importByNameEntry & 0x8000000) != 0)
                    {
                        // should never happen in Singularity (no Ordinals)
                        throw new BadImageFormatException("Import Ordinal encountered");
                    }
                    else
                    {
                        name = mem.ReadAsciiZeroString((int)nameStringOffset + 2);
                        hint = mem.Read16Unchecked(nameStringOffset);
                        //Tracing.Log(Tracing.Debug, " function to lookup is {0}", name);

                        UIntPtr addr = exports.Resolve(hint, name);
                        if (0 != addr)
                        {
                            //Overwrite ptr in IAT with address of function in the
                            // IAT thunk table
#if verbose
                            int meth = name.IndexOf('@');
                            int rest = name.IndexOf('@', meth + 1) + 1;
                            int clas = name.LastIndexOf('_', rest, rest - meth) + 1;
                            Tracing.Log(Tracing.Debug, "    import: {1:x8} is {2:x8} {0}",
                                        name.Substring(0, meth) + "@" + name.Substring(clas, rest - clas) + "@" name.Substring(rest)
                                            (uint) offsetIAT, (uint)addr);
#endif
                            mem.Write32((int)offsetIAT, (uint)addr);
                        }
                        else
                        {
                            Tracing.Log(Tracing.Debug, " Import not found: {0}", name);
                            throw new BadImageFormatException("Import not found");
                        }
                    }
                    // increment "array indices"
                    offsetIAT       += 4;
                    offsetHintTable += 4;
                }
                //Tracing.Log(Tracing.Debug, "");
#endif
            }
            //throw new BadImageFormatException("");
        }
Example #2
0
        public void DumpIAT(String title)
        {
            Tracing.Log(Tracing.Debug, "// {0}", title);
            if (entry.size == 0)
            {
                Tracing.Log(Tracing.Debug, "// No data.");
                return;
            }
            int importOffset = (int)entry.virtualAddress;

            Tracing.Log(Tracing.Debug, "  import offset={0:x8}", importOffset);
            //
            // start at the importOffset specified above creating and filling out ImportDescriptors
            // There is no indication in the header as to how many descriptors are present.
            // In the last descriptor all fields will be 0; this code checks just the firstChunk field.
            //
            for (;;)
            {
                ImportDescriptor importDescriptor =
                    new ImportDescriptor(mem, ref importOffset);

                //Use hit/Name array pointed to by "characteristics"
                // FirstChunk points to the IAT table which is modified at load time to
                //  to reflect the fixed-up thunk to access the function
                if (importDescriptor.characteristics == 0)
                {
                    return;
                }
                String name = null;
                if (importDescriptor.name != 0)
                {
                    name = mem.ReadAsciiZeroString((int)importDescriptor.name);
                }
                Tracing.Log(Tracing.Debug, "// {0}", name);
                importDescriptor.DumpToStream();
                Tracing.Log(Tracing.Debug, "//");

                int importTableOffset = (int)importDescriptor.characteristics;
                for (;;)
                {
                    int importTableID = (int)mem.Read32(importTableOffset);
                    if (importTableID == 0)
                    {
                        break;
                    }
                    Tracing.Log(Tracing.Debug, "importTableID is {0:x8}", importTableID);
                    int nameStringOffset =
                        importTableID & 0x7fffffff;
                    importTableOffset += 4;
                    if ((importTableID & 0x8000000) != 0)
                    {
                        Tracing.Log(Tracing.Debug, "//              {0:x8} by ordinal {1:x8}",
                                    mem.Read16(importTableOffset),
                                    (importTableID & 0x7ffffff));
                    }
                    else
                    {
                        Tracing.Log(Tracing.Debug, "//              {1:x8} {0:x8}",
                                    mem.ReadAsciiZeroString(nameStringOffset + 2),
                                    mem.Read16(importTableOffset));
                    }
                }
                Tracing.Log(Tracing.Debug, "");
            }
            //throw new BadImageFormatException("");
        }
Example #3
0
        private void DumpIAT(StreamWriter outputStream,
                             String title,
                             ref DirectoryEntry entry)
        {
            outputStream.WriteLine("// " + title);
            if (entry.size == 0)
            {
                outputStream.WriteLine("// No data.");
                outputStream.WriteLine();
                return;
            }
            if (entry.size < ImportDescriptor.SIZE)
            {
                outputStream.WriteLine("Not enough data for IMAGE_IMPORT_DESCRIPTOR");
                return;
            }
            int importOffset = this.VaToOffset(entry.virtualAddress);

            while (true)
            {
                this.stream.Seek(importOffset, SeekOrigin.Begin);
                ImportDescriptor importDescriptor =
                    new ImportDescriptor(this.stream);
                if (importDescriptor.firstChunk == 0)
                {
                    return;
                }
                String name = null;
                if (importDescriptor.name != 0)
                {
                    int nameOffset = this.VaToOffset(importDescriptor.name);
                    name = this.readString(nameOffset);
                }
                outputStream.WriteLine("//     " + name);
                importDescriptor.DumpToStream(outputStream, "//              ");
                outputStream.WriteLine("//");

                int importTableOffset =
                    this.VaToOffset(importDescriptor.firstChunk);
                while (true)
                {
                    this.stream.Seek(importTableOffset, SeekOrigin.Begin);
                    BinaryReader intReader     = new BinaryReader(this.stream);
                    int          importTableID = intReader.ReadInt32();
                    if (importTableID == 0)
                    {
                        break;
                    }
                    outputStream.WriteLine("importTableID is " + importTableID.ToString("x"));
                    outputStream.Flush();
                    int nameStringOffset =
                        this.VaToOffset(importTableID & 0x7fffffff);
                    this.stream.Seek(nameStringOffset, SeekOrigin.Begin);
                    intReader = new BinaryReader(this.stream);
                    if ((importTableID & 0x8000000) != 0)
                    {
                        outputStream.WriteLine("//              " + intReader.ReadInt16().ToString("x8") + " by ordinal " + (importTableID & 0x7ffffff));
                    }
                    else
                    {
                        outputStream.WriteLine("//              " + intReader.ReadInt16().ToString("x8") + " " + this.readString(nameStringOffset + 2));
                    }
                    importTableOffset += 4;
                }
                outputStream.WriteLine();
                importOffset += ImportDescriptor.SIZE;
            }
        }