public IEnumerable<Address> CreatePointerScanner(ImageMap map, ImageReader rdr, IEnumerable<Address> knownAddresses, PointerScannerFlags flags) { var knownLinAddresses = knownAddresses.Select(a => a.ToUInt32()).ToHashSet(); if (flags != PointerScannerFlags.Calls) throw new NotImplementedException(string.Format("Haven't implemented support for scanning for {0} yet.", flags)); while (rdr.IsValid) { uint linAddrCall = rdr.Address.ToUInt32(); var opcode = rdr.ReadLeUInt32(); if ((opcode & 0x0F000000) == 0x0B000000) // BL { int offset = ((int)opcode << 8) >> 6; uint target = (uint)(linAddrCall + 8 + offset); if (knownLinAddresses.Contains(target)) yield return Address.Ptr32(linAddrCall); } } }
public override bool ResolveImportDescriptorEntry(string dllName, ImageReader rdrIlt, ImageReader rdrIat) { Address addrThunk = rdrIat.Address; uint iatEntry = rdrIat.ReadLeUInt32(); uint iltEntry = rdrIlt.ReadLeUInt32(); if (iltEntry == 0) return false; outer.importReferences.Add( addrThunk, ResolveImportedFunction(dllName, iltEntry, addrThunk)); return true; }
public override Address ReadPreferredImageBase(ImageReader rdr) { { uint rvaBaseOfData = rdr.ReadLeUInt32(); // Only exists in PE32, not PE32+ return Address32.Ptr32(rdr.ReadLeUInt32()); } }
public void ReadOptionalHeader(ImageReader rdr, short expectedMagic) { if (optionalHeaderSize <= 0) throw new BadImageFormatException("Optional header size should be larger than 0 in a PE executable image file."); short magic = rdr.ReadLeInt16(); if (magic != expectedMagic) throw new BadImageFormatException("Not a valid PE Header."); rdr.ReadByte(); // Linker major version rdr.ReadByte(); // Linker minor version rdr.ReadLeUInt32(); // code size (== .text section size) rdr.ReadLeUInt32(); // size of initialized data rdr.ReadLeUInt32(); // size of uninitialized data rvaStartAddress = rdr.ReadLeUInt32(); uint rvaBaseOfCode = rdr.ReadLeUInt32(); preferredBaseOfImage = innerLoader.ReadPreferredImageBase(rdr); rdr.ReadLeUInt32(); // section alignment rdr.ReadLeUInt32(); // file alignment rdr.ReadLeUInt16(); // OS major version rdr.ReadLeUInt16(); // OS minor version rdr.ReadLeUInt16(); // Image major version rdr.ReadLeUInt16(); // Image minor version rdr.ReadLeUInt16(); // Subsystem major version rdr.ReadLeUInt16(); // Subsystem minor version rdr.ReadLeUInt32(); // reserved uint sizeOfImage = rdr.ReadLeUInt32(); uint sizeOfHeaders = rdr.ReadLeUInt32(); uint checksum = rdr.ReadLeUInt32(); ushort subsystem = rdr.ReadLeUInt16(); ushort dllFlags = rdr.ReadLeUInt16(); var stackReserve = rdr.Read(arch.WordWidth); var stackCommit = rdr.Read(arch.WordWidth); var heapReserve = rdr.Read(arch.WordWidth); var heapCommit = rdr.Read(arch.WordWidth); rdr.ReadLeUInt32(); // loader flags uint dictionaryCount = rdr.ReadLeUInt32(); if (dictionaryCount == 0) return; rvaExportTable = rdr.ReadLeUInt32(); sizeExportTable = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; rvaImportTable = rdr.ReadLeUInt32(); uint importTableSize = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; rvaResources = rdr.ReadLeUInt32(); // resource address rdr.ReadLeUInt32(); // resource size if (--dictionaryCount == 0) return; rvaExceptionTable = rdr.ReadLeUInt32(); // exception address sizeExceptionTable = rdr.ReadLeUInt32(); // exception size if (--dictionaryCount == 0) return; rdr.ReadLeUInt32(); // certificate address rdr.ReadLeUInt32(); // certificate size if (--dictionaryCount == 0) return; uint rvaBaseRelocAddress = rdr.ReadLeUInt32(); uint baseRelocSize = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; uint rvaDebug = rdr.ReadLeUInt32(); uint cbDebug = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; uint rvaArchitecture = rdr.ReadLeUInt32(); uint cbArchitecture = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; uint rvaGlobalPointer = rdr.ReadLeUInt32(); uint cbGlobalPointer = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; uint rvaTls = rdr.ReadLeUInt32(); uint cbTls = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; uint rvaLoadConfig = rdr.ReadLeUInt32(); uint cbLoadConfig = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; uint rvaBoundImport = rdr.ReadLeUInt32(); uint cbBoundImport = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; uint rvaIat = rdr.ReadLeUInt32(); uint cbIat = rdr.ReadLeUInt32(); if (--dictionaryCount == 0) return; this.rvaDelayImportDescriptor = rdr.ReadLeUInt32(); uint cbDelayImportDescriptor = rdr.ReadLeUInt32(); }
public short ReadCoffHeader(ImageReader rdr) { this.machine = rdr.ReadLeUInt16(); short expectedMagic = GetExpectedMagic(machine); arch = CreateArchitecture(machine); platform = CreatePlatform(machine, Services, arch); innerLoader = CreateInnerLoader(machine); sections = rdr.ReadLeInt16(); rdr.ReadLeUInt32(); // timestamp. rdr.ReadLeUInt32(); // COFF symbol table. rdr.ReadLeUInt32(); // #of symbols. optionalHeaderSize = rdr.ReadLeInt16(); this.fileFlags = rdr.ReadLeUInt16(); rvaSectionTable = (uint) ((int)rdr.Offset + optionalHeaderSize); return expectedMagic; }
private EntryPoint LoadEntryPoint(Address addrLoad, ImageReader rdrAddrs, ImageReader rdrNames) { uint addr = rdrAddrs.ReadLeUInt32(); int iNameMin = rdrNames.ReadLeInt32(); int j; for (j = iNameMin; imgLoaded.Bytes[j] != 0; ++j) ; char[] chars = Encoding.ASCII.GetChars(imgLoaded.Bytes, iNameMin, j - iNameMin); return new EntryPoint(addrLoad + addr, new string(chars), arch.CreateProcessorState()); }
public override Address ReadCodeAddress(int byteSize, ImageReader rdr, ProcessorState state) { return Address.Ptr32(rdr.ReadLeUInt32()); }
private static Section ReadSection(ImageReader rdr) { Section sec = new Section(); sec.Name = ReadSectionName(rdr); sec.VirtualSize = rdr.ReadLeUInt32(); sec.VirtualAddress = rdr.ReadLeUInt32(); sec.SizeRawData = rdr.ReadLeUInt32(); sec.OffsetRawData = rdr.ReadLeUInt32(); rdr.ReadLeUInt32(); // pointer to relocations rdr.ReadLeUInt32(); // pointer to line numbers. rdr.ReadLeInt16(); // # of relocations rdr.ReadLeInt16(); // # of line numbers sec.Flags = rdr.ReadLeUInt32(); return sec; }
private bool ReadDeferredLoadDescriptors(ImageReader rdr, Address addrLoad) { var attributes = rdr.ReadLeUInt32(); var dllName = ReadUtf8String(rdr.ReadLeUInt32(), 0); // DLL name. if (dllName == null) return false; var rdrModule = rdr.ReadLeInt32(); var rdrThunks = imgLoaded.CreateLeReader(rdr.ReadLeUInt32()); var rdrNames = imgLoaded.CreateLeReader(rdr.ReadLeUInt32()); for (;;) { var addrThunk = imgLoaded.BaseAddress + rdrThunks.Offset; uint rvaName = rdrNames.ReadLeUInt32(); uint rvaThunk = rdrThunks.ReadLeUInt32(); if (rvaName == 0) break; importReferences.Add( addrThunk, innerLoader.ResolveImportedFunction(dllName, rvaName, addrThunk)); } rdr.ReadLeInt32(); rdr.ReadLeInt32(); rdr.ReadLeInt32(); // time stamp return true; }
/// <summary> /// Loads the import directory entry for one particular DLL. /// </summary> /// <remarks> /// The goal of this method is to discover the imported DLL's and the names /// of all imported methods. This is made difficult by the way different /// compilers and linkers build the import directory entries. Sometimes, /// the RVA to the Import lookup table (ILT) is null, so we have to use /// a last resort and walk the Import Address table (IAT).</remarks> /// <param name="rdr"></param> /// <param name="addrLoad"></param> /// <returns>True if there were entries in the import descriptor, otherwise /// false.</returns> public bool ReadImportDescriptor(ImageReader rdr, Address addrLoad) { var rvaILT = rdr.ReadLeUInt32(); // Import lookup table rdr.ReadLeUInt32(); // Ignore datestamp... rdr.ReadLeUInt32(); // ...and forwarder chain var dllName = ReadUtf8String(rdr.ReadLeUInt32(), 0); // DLL name var rvaIAT = rdr.ReadLeUInt32(); // Import address table if (rvaILT == 0 && dllName == null) return false; ImageReader rdrIlt = imgLoaded.CreateLeReader(rvaILT!=0 ? rvaILT:rvaIAT); ImageReader rdrIat = imgLoaded.CreateLeReader(rvaIAT); while (innerLoader.ResolveImportDescriptorEntry(dllName, rdrIlt, rdrIat)) ; return true; }
private ImageSymbol LoadEntryPoint(Address addrLoad, ImageReader rdrAddrs, ImageReader rdrNames) { uint rvaAddr = rdrAddrs.ReadLeUInt32(); int iNameMin = rdrNames.ReadLeInt32(); int j; for (j = iNameMin; imgLoaded.Bytes[j] != 0; ++j) ; char[] chars = Encoding.ASCII.GetChars(imgLoaded.Bytes, iNameMin, j - iNameMin); return new ImageSymbol(addrLoad + rvaAddr) { Name = new string(chars), ProcessorState = arch.CreateProcessorState(), Type = SymbolType.Procedure, }; }
public Address ReadCodeAddress(int size, ImageReader rdr, ProcessorState state) { if (size == 4) { return Address.Ptr32(rdr.ReadLeUInt32()); } throw new NotImplementedException(); }
/// <summary> /// Loads the import directory entry for one particular DLL. /// </summary> /// <remarks> /// The goal of this method is to discover the imported DLL's and the names /// of all imported methods. This is made difficult by the way different /// compilers and linkers build the import directory entries. Sometimes, /// the RVA to the Import lookup table (ILT) is null, so we have to use /// a last resort and walk the Import Address table (IAT).</remarks> /// <param name="rdr"></param> /// <param name="addrLoad"></param> /// <returns>True if there were entries in the import descriptor, otherwise /// false.</returns> public bool ReadImportDescriptor(ImageReader rdr, Address addrLoad) { var rvaILT = rdr.ReadLeUInt32(); // Import lookup table rdr.ReadLeUInt32(); // Ignore datestamp... rdr.ReadLeUInt32(); // ...and forwarder chain var dllName = ReadUtf8String(rdr.ReadLeUInt32(), 0); // DLL name var rvaIAT = rdr.ReadLeUInt32(); // Import address table if (rvaILT == 0 && dllName == null) return false; var ptrSize = platform.PointerType.Size; ImageReader rdrIlt = imgLoaded.CreateLeReader(rvaILT!=0 ? rvaILT:rvaIAT); ImageReader rdrIat = imgLoaded.CreateLeReader(rvaIAT); while (true) { var addrIat = rdrIat.Address; var addrIlt = rdrIlt.Address; if (!innerLoader.ResolveImportDescriptorEntry(dllName, rdrIlt, rdrIat)) break; ImageMap.AddItemWithSize( addrIat, new ImageMapItem { Address = addrIat, DataType = new Pointer(new CodeType(), ptrSize), Size = (uint)ptrSize, }); ImageMap.AddItemWithSize( addrIlt, new ImageMapItem { Address = addrIlt, DataType = PrimitiveType.CreateWord(ptrSize), Size = (uint)ptrSize, }); } return true; }