NationalSecurityAgency/ghidra · error · NotFoundException
Failed to locate label: {symbolName}
Error message
Failed to locate label: {symbolName} What it means
Thrown by EmuX86GccDeobfuscateHookExampleScript.getExternalThunkAddress when it cannot resolve a single thunk for an external function symbol. The method looks up an external symbol by name, requires it to be a FUNCTION, and requires exactly one thunk address; otherwise NotFoundException is thrown. It is an example-script helper used to find hook points for malloc/free/strlen.
Source
Thrown at Ghidra/Features/Base/ghidra_scripts/EmuX86GccDeobfuscateHookExampleScript.java:199
/**
* Get the thunk function corresponding to an external function. Such thunks should reside
* within the EXTERNAL block. (Note: this is specific to the ELF import)
*
* @param symbolName external function name
* @return address of thunk function which corresponds to an external function
* @throws NotFoundException if thunk not found
*/
private Address getExternalThunkAddress(String symbolName) throws NotFoundException {
Symbol externalSymbol = currentProgram.getSymbolTable().getExternalSymbol(symbolName);
if (externalSymbol != null && externalSymbol.getSymbolType() == SymbolType.FUNCTION) {
Function f = (Function) externalSymbol.getObject();
Address[] thunkAddrs = f.getFunctionThunkAddresses(false);
if (thunkAddrs.length == 1) {
return thunkAddrs[0];
}
}
throw new NotFoundException("Failed to locate label: " + symbolName);
}
/**
* Get the global namespace symbol address which corresponds to the specified name.
*
* @param symbolName global symbol name
* @return symbol address
* @throws NotFoundException if symbol not found
*/
private Address getSymbolAddress(String symbolName) throws NotFoundException {
Symbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(currentProgram, symbolName,
err -> Msg.error(this, err));
if (symbol != null) {
return symbol.getAddress();
}
throw new NotFoundException("Failed to locate label: " + symbolName);
}
View on GitHub (pinned to d5f144c24d)
Solutions
- Run the script only against the deobHookExample ELF compiled with gcc for x86-64 (see script header).
- Confirm the external functions malloc/free/strlen are imported as thunks; if not, retarget mallocEntry/freeEntry/strlenEntry to the actual implementation addresses.
- If multiple thunks exist, extend the helper to pick one deterministically instead of requiring exactly one.
- Check the program's external symbol table for the expected names before running.
Example fix
// before
mallocEntry = getExternalThunkAddress("malloc"); // throws if 0 or >1 thunks
// after - fall back to the external location itself or a known address
Symbol s = currentProgram.getSymbolTable().getExternalSymbol("malloc");
if (s != null && s.getSymbolType() == SymbolType.FUNCTION) {
Address[] thunks = ((Function) s.getObject()).getFunctionThunkAddresses(false);
mallocEntry = (thunks.length >= 1) ? thunks[0] : ((Function) s.getObject()).getEntryPoint();
}
if (mallocEntry == null) throw new NotFoundException("Failed to locate label: malloc"); Defensive patterns
Strategy: validation
Validate before calling
Symbol s = currentProgram.getSymbolTable().getExternalSymbol(name);
if (s == null || s.getSymbolType() != SymbolType.FUNCTION) {
// no external function - cannot resolve thunk
return null;
}
Address[] thunks = ((Function) s.getObject()).getFunctionThunkAddresses(false);
boolean ok = thunks.length == 1; Type guard
static boolean hasSingleExternalThunk(Program p, String name) {
Symbol s = p.getSymbolTable().getExternalSymbol(name);
if (s == null || s.getSymbolType() != SymbolType.FUNCTION) return false;
return ((Function) s.getObject()).getFunctionThunkAddresses(false).length == 1;
} Try / catch
try {
addr = getExternalThunkAddress("malloc");
} catch (NotFoundException e) {
// fall back: use the external location entry point, or skip hooking
printerr(e.getMessage());
return;
} Prevention
- Run the example script only against deobHookExample (x86:LE:64 ELF).
- Confirm libc symbols are imported as thunks before relying on getExternalThunkAddress.
- Extend the helper to handle zero/multiple thunks gracefully.
When it happens
Trigger: Running EmuX86GccDeobfuscateHookExampleScript against a program where the external symbol (e.g. 'malloc') is missing, is not a function, has zero thunks (library not imported via thunks), or has multiple thunks. Also triggered if the wrong program is loaded (the script is hard-coded for deobHookExample on x86:LE:64).
Common situations: Loading a program other than deobHookExample. The binary imports the libc functions directly without thunks. The external symbol was renamed or stripped. The program is statically linked so there are no external locations.
Related errors
- Sleigh language required
- DataType %s has dynamic length
- Input %s conflicts: 0x%s != 0x%s
- Emulation requires a Sleigh language
- Timed out reading or writing target
AI-assisted analysis of NationalSecurityAgency/ghidra@d5f144c24d (2026-08-14).
Data as JSON: /api/errors/853ea7b4da22daff.
Report an issue: GitHub.