internal static async Task <ExceptionTable> GetAsync(PortableExecutableImage image, DataDirectory dataDirectory, Location location) { var calc = image.GetCalculator(); var stream = image.GetStream(); var offset = calc.RVAToOffset(dataDirectory.VirtualAddress); var rva = dataDirectory.VirtualAddress; stream.Seek(offset.ToInt64(), SeekOrigin.Begin); var entrySize = Utils.SizeOf <IMAGE_RUNTIME_FUNCTION_64>(); var entries = new List <ExceptionTableEntry>(); while (true) { var entryData = await stream.ReadStructAsync <IMAGE_RUNTIME_FUNCTION_64>(entrySize).ConfigureAwait(false); if (entryData.StartAddress == 0 && entryData.EndAddress == 0) { break; } var entryLocation = new Location(image, offset, rva, image.NTHeaders.OptionalHeader.ImageBase + rva, entrySize.ToUInt32(), entrySize.ToUInt32()); var entry = new ExceptionTableEntry64(image, entryLocation, entryData); entries.Add(entry); offset += entrySize.ToUInt32(); rva += entrySize.ToUInt32(); } var table = new ExceptionTable64(image, dataDirectory, location, entries.ToArray()); return(table); }
public static async Task <ExceptionTable> GetAsync(PortableExecutableImage image) { if (!image.NTHeaders.DataDirectories.Exists(DataDirectoryType.ExceptionTable)) { return(null); } var dataDirectory = image.NTHeaders.DataDirectories[DataDirectoryType.ExceptionTable]; if (DataDirectory.IsNullOrEmpty(dataDirectory)) { return(null); } var calc = image.GetCalculator(); var section = calc.RVAToSection(dataDirectory.VirtualAddress); var fileOffset = calc.RVAToOffset(section, dataDirectory.VirtualAddress); var imageBase = image.NTHeaders.OptionalHeader.ImageBase; var location = new Location(image, fileOffset, dataDirectory.VirtualAddress, imageBase + dataDirectory.VirtualAddress, dataDirectory.Size, dataDirectory.Size, section); ExceptionTable table; if (image.Is64Bit) { table = await ExceptionTable64.GetAsync(image, dataDirectory, location).ConfigureAwait(false); } else { table = await ExceptionTable32.GetAsync(image, dataDirectory, location).ConfigureAwait(false); } return(table); }