NationalSecurityAgency/ghidra · error · ConcretionError

Cannot make Taint concrete

Error message

Cannot make Taint concrete

What it means

TaintPcodeExecutorStatePiece only tracks taint labels, not concrete bytes. getConcreteBuffer would need real bytes, so it throws ConcretionError to redirect concretization to the paired concrete state piece. As with toConcrete, taint here is auxiliary and cannot satisfy a concrete read on its own.

Source

Thrown at Ghidra/Debug/TaintAnalysis/src/main/java/ghidra/pcode/emu/taint/state/TaintPcodeExecutorStatePiece.java:81

	 * Create the taint piece
	 * 
	 * @param language the language of the emulator
	 * @param addressArithmetic the address arithmetic, likely taken from the concrete piece
	 * @param cb callbacks to receive emulation events
	 */
	public TaintPcodeExecutorStatePiece(Language language,
			PcodeArithmetic<byte[]> addressArithmetic, PcodeStateCallbacks cb) {
		super(language, addressArithmetic, TaintPcodeArithmetic.forLanguage(language), cb);
	}

	@Override
	public TaintPcodeExecutorStatePiece fork(PcodeStateCallbacks cb) {
		throw new UnsupportedOperationException();
	}

	@Override
	public MemBuffer getConcreteBuffer(Address address, Purpose purpose) {
		throw new ConcretionError("Cannot make Taint concrete", purpose);
	}

	/**
	 * {@inheritDoc}
	 * 
	 * <p>
	 * Here, we just follow the pattern: delegate to the space map.
	 */
	@Override
	protected TaintSpace getForSpace(AddressSpace space, boolean toWrite) {
		if (toWrite) {
			return spaceMap.computeIfAbsent(space, s -> new TaintSpace(space, this));
		}
		return spaceMap.get(space);
	}

	/**
	 * {@inheritDoc}

View on GitHub (pinned to d5f144c24d)

Solutions

  1. Pair the taint state piece with a concrete state piece (composite/paired state) so concrete reads route to the concrete piece.
  2. Route concrete reads explicitly through the concrete piece rather than the taint piece.
  3. Avoid forcing concrete reads in taint-only analysis.

Example fix

// before (taint-only state)
MemBuffer b = taintPiece.getConcreteBuffer(addr, Purpose.OTHER); // throws
// after (route through the paired concrete piece)
MemBuffer b = concretePiece.getConcreteBuffer(addr, Purpose.OTHER);
Defensive patterns

Strategy: fallback

Validate before calling

// Use a composite state; route concrete reads to the concrete piece.
if (statePiece instanceof TaintPcodeExecutorStatePiece) {
    return concretePiece.getConcreteBuffer(address, purpose);
}

Try / catch

try {
    return statePiece.getConcreteBuffer(address, purpose);
} catch (ConcretionError e) {
    return concretePiece.getConcreteBuffer(address, purpose);
}

Prevention

When it happens

Trigger: Requesting a concrete MemBuffer from a taint state piece - e.g. an executor path that demands a concrete buffer for an address, or user code calling getConcreteBuffer on the taint piece directly.

Common situations: Using a taint-only state without a concrete partner; an instruction/emulator path (address resolution, concrete branch) that requires a concrete buffer; user analysis calling getConcreteBuffer on taint.

Related errors


AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14). Data as JSON: /api/errors/2159049801558848. Report an issue: GitHub.