예제 #1
0
        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;
        }
예제 #2
0
        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);
        }