From 89ace222c322d773db20d36fc3418c166ccccb78 Mon Sep 17 00:00:00 2001 From: 8damon <178704185+8damon@users.noreply.github.com> Date: Fri, 21 Aug 2026 15:42:47 +0000 Subject: [PATCH] Fix cyclic x64 unwind chain parsing --- .../app/util/bin/format/pe/PEx64UnwindInfo.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PEx64UnwindInfo.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PEx64UnwindInfo.java index 91d3fe5b08..313d4d8614 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PEx64UnwindInfo.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PEx64UnwindInfo.java @@ -16,6 +16,8 @@ package ghidra.app.util.bin.format.pe; import java.io.IOException; +import java.util.HashSet; +import java.util.Set; import ghidra.app.util.bin.BinaryReader; import ghidra.app.util.bin.StructConverter; @@ -158,6 +160,15 @@ class PEx64UnwindInfo implements StructConverter { static PEx64UnwindInfo readUnwindInfo(BinaryReader reader, long offset, NTHeader ntHeader) throws IOException { + return readUnwindInfo(reader, offset, ntHeader, new HashSet<>()); + } + + private static PEx64UnwindInfo readUnwindInfo(BinaryReader reader, long offset, + NTHeader ntHeader, Set visitedOffsets) throws IOException { + if (!visitedOffsets.add(offset)) { + throw new IOException("Cyclic unwind info chain"); + } + long origIndex = reader.getPointerIndex(); long pointer = ntHeader.rvaToPointer(offset); @@ -205,7 +216,8 @@ class PEx64UnwindInfo implements StructConverter { // Follow the chain to the referenced UNWIND_INFO structure until we // get to the end - PEx64UnwindInfo info = readUnwindInfo(reader, unwindInfoAddressOrData, ntHeader); + PEx64UnwindInfo info = + readUnwindInfo(reader, unwindInfoAddressOrData, ntHeader, visitedOffsets); unwindInfo.unwindHandlerChainInfo = new ImageRuntimeFunctionEntry_X86(beginAddress, endAddress, unwindInfoAddressOrData, info); }