{"record":{"id":"853ea7b4da22daff","repo":"NationalSecurityAgency/ghidra","slug":"failed-to-locate-label-symbolname","errorCode":null,"errorMessage":"Failed to locate label: {symbolName}","messagePattern":"Failed to locate label: (.+?)","errorType":"exception","errorClass":"NotFoundException","httpStatus":null,"severity":"error","filePath":"Ghidra/Features/Base/ghidra_scripts/EmuX86GccDeobfuscateHookExampleScript.java","lineNumber":199,"sourceCode":"\n\t/**\n\t * Get the thunk function corresponding to an external function. Such thunks should reside\n\t * within the EXTERNAL block. (Note: this is specific to the ELF import)\n\t * \n\t * @param symbolName external function name\n\t * @return address of thunk function which corresponds to an external function\n\t * @throws NotFoundException if thunk not found\n\t */\n\tprivate Address getExternalThunkAddress(String symbolName) throws NotFoundException {\n\t\tSymbol externalSymbol = currentProgram.getSymbolTable().getExternalSymbol(symbolName);\n\t\tif (externalSymbol != null && externalSymbol.getSymbolType() == SymbolType.FUNCTION) {\n\t\t\tFunction f = (Function) externalSymbol.getObject();\n\t\t\tAddress[] thunkAddrs = f.getFunctionThunkAddresses(false);\n\t\t\tif (thunkAddrs.length == 1) {\n\t\t\t\treturn thunkAddrs[0];\n\t\t\t}\n\t\t}\n\t\tthrow new NotFoundException(\"Failed to locate label: \" + symbolName);\n\t}\n\n\t/**\n\t * Get the global namespace symbol address which corresponds to the specified name.\n\t * \n\t * @param symbolName global symbol name\n\t * @return symbol address\n\t * @throws NotFoundException if symbol not found\n\t */\n\tprivate Address getSymbolAddress(String symbolName) throws NotFoundException {\n\t\tSymbol symbol = SymbolUtilities.getLabelOrFunctionSymbol(currentProgram, symbolName,\n\t\t\terr -> Msg.error(this, err));\n\t\tif (symbol != null) {\n\t\t\treturn symbol.getAddress();\n\t\t}\n\t\tthrow new NotFoundException(\"Failed to locate label: \" + symbolName);\n\t}\n","sourceCodeStart":181,"sourceCodeEnd":217,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/Ghidra/Features/Base/ghidra_scripts/EmuX86GccDeobfuscateHookExampleScript.java#L181-L217","documentation":"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.","triggerScenarios":"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).","commonSituations":"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.","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."],"exampleFix":"// before\nmallocEntry = getExternalThunkAddress(\"malloc\"); // throws if 0 or >1 thunks\n\n// after - fall back to the external location itself or a known address\nSymbol s = currentProgram.getSymbolTable().getExternalSymbol(\"malloc\");\nif (s != null && s.getSymbolType() == SymbolType.FUNCTION) {\n    Address[] thunks = ((Function) s.getObject()).getFunctionThunkAddresses(false);\n    mallocEntry = (thunks.length >= 1) ? thunks[0] : ((Function) s.getObject()).getEntryPoint();\n}\nif (mallocEntry == null) throw new NotFoundException(\"Failed to locate label: malloc\");","handlingStrategy":"validation","validationCode":"Symbol s = currentProgram.getSymbolTable().getExternalSymbol(name);\nif (s == null || s.getSymbolType() != SymbolType.FUNCTION) {\n    // no external function - cannot resolve thunk\n    return null;\n}\nAddress[] thunks = ((Function) s.getObject()).getFunctionThunkAddresses(false);\nboolean ok = thunks.length == 1;","typeGuard":"static boolean hasSingleExternalThunk(Program p, String name) {\n    Symbol s = p.getSymbolTable().getExternalSymbol(name);\n    if (s == null || s.getSymbolType() != SymbolType.FUNCTION) return false;\n    return ((Function) s.getObject()).getFunctionThunkAddresses(false).length == 1;\n}","tryCatchPattern":"try {\n    addr = getExternalThunkAddress(\"malloc\");\n} catch (NotFoundException e) {\n    // fall back: use the external location entry point, or skip hooking\n    printerr(e.getMessage());\n    return;\n}","preventionTips":["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."],"tags":["emulation","x86","example-script","symbol-resolution"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}