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(""); }
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(""); }
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; } }