internal ExceptionTableEntry64(PortableExecutableImage image, Location location, IMAGE_RUNTIME_FUNCTION_64 function) : base(image, location) { _unwindInfo = null; StartAddress = function.StartAddress; EndAddress = function.EndAddress; UnwindInfoAddress = function.UnwindInfoAddress; }
public async Task <ExceptionUnwindInfo> GetUnwindInfoAsync() { if (_unwindInfo == null && UnwindInfoAddress > 0) { var calc = Image.GetCalculator(); var stream = Image.GetStream(); try { var offset = calc.RVAToOffset(UnwindInfoAddress); stream.Seek(offset.ToInt64(), SeekOrigin.Begin); var versionFlags = await stream.ReadByteAsync().ConfigureAwait(false); var sizeOfProlog = await stream.ReadByteAsync().ConfigureAwait(false); var countOfCodes = await stream.ReadByteAsync().ConfigureAwait(false); var frameRegisterOffset = await stream.ReadByteAsync().ConfigureAwait(false); var codes = new List <ushort>(); for (var i = 0; i < countOfCodes; i++) { var code = await stream.ReadUInt16Async().ConfigureAwait(false); codes.Add(code); } if (countOfCodes % 2 != 0) { await stream.SkipBytesAsync(sizeof(ushort)).ConfigureAwait(false); } var flags = GetFlags(versionFlags); uint handlerAddress = 0; ExceptionChainedUnwindInfo chainedInfo = null; if ((flags & ExceptionUnwindInfoFlags.ExceptionHandler) == ExceptionUnwindInfoFlags.ExceptionHandler || (flags & ExceptionUnwindInfoFlags.UnwindHandler) == ExceptionUnwindInfoFlags.UnwindHandler) { handlerAddress = await stream.ReadUInt32Async().ConfigureAwait(false); } if ((flags & ExceptionUnwindInfoFlags.ChainHandler) == ExceptionUnwindInfoFlags.ChainHandler) { var chainedFunction = await stream.ReadStructAsync <IMAGE_RUNTIME_FUNCTION_64>(); if (chainedFunction.StartAddress != 0) { chainedInfo = new ExceptionChainedUnwindInfo(chainedFunction.StartAddress, chainedFunction.EndAddress, chainedFunction.UnwindInfoAddress); } } _unwindInfo = new ExceptionUnwindInfo(Image, UnwindInfoAddress, versionFlags, sizeOfProlog, countOfCodes, frameRegisterOffset, codes.ToArray(), handlerAddress, chainedInfo); } catch (Exception ex) { throw new PortableExecutableImageException(Image, "Could not read exception unwind information from stream.", ex); } } return(_unwindInfo); }