angr.utils.go_runtime¶
Identification of Go runtime functions that never return.
angr has no built-in knowledge of the Go runtime, so the two families of stubs that the Go compiler
emits at essentially every call site – the goroutine stack-growth stub (runtime.morestack) and
the bounds-check panic stubs – are recovered as returning functions. That attaches a large amount of
unreachable code to every Go function: a fake self-recursive tail after each morestack call site,
and one dead panic branch per bounds check.
Two identification strategies are provided, because the interesting targets are usually stripped:
by name, when symbols (or a
.gopclntab-derived symbol table) are available;by shape, which is what actually carries stripped binaries.
A false positive here silently deletes real code, so every shape-based rule below requires either overwhelming corroboration across the binary or an assembly signature that no compiler emits for ordinary code.
- angr.utils.go_runtime.GO_NORETURN_NAMES: frozenset[str] = frozenset({'os.Exit', 'runtime.Goexit', 'runtime.abort', 'runtime.badctxt', 'runtime.badmcall', 'runtime.badmcall2', 'runtime.badreflectcall', 'runtime.exit', 'runtime.exitThread', 'runtime.exitsyscall0', 'runtime.fatal', 'runtime.fatalpanic', 'runtime.fatalthrow', 'runtime.goPanicExtendIndex', 'runtime.goPanicExtendIndexU', 'runtime.goPanicExtendSlice3Acap', 'runtime.goPanicExtendSlice3AcapU', 'runtime.goPanicExtendSlice3Alen', 'runtime.goPanicExtendSlice3AlenU', 'runtime.goPanicExtendSlice3B', 'runtime.goPanicExtendSlice3BU', 'runtime.goPanicExtendSlice3C', 'runtime.goPanicExtendSlice3CU', 'runtime.goPanicExtendSliceAcap', 'runtime.goPanicExtendSliceAcapU', 'runtime.goPanicExtendSliceAlen', 'runtime.goPanicExtendSliceAlenU', 'runtime.goPanicExtendSliceB', 'runtime.goPanicExtendSliceBU', 'runtime.goPanicExtendSliceConvert', 'runtime.goPanicIndex', 'runtime.goPanicIndexU', 'runtime.goPanicSlice3Acap', 'runtime.goPanicSlice3AcapU', 'runtime.goPanicSlice3Alen', 'runtime.goPanicSlice3AlenU', 'runtime.goPanicSlice3B', 'runtime.goPanicSlice3BU', 'runtime.goPanicSlice3C', 'runtime.goPanicSlice3CU', 'runtime.goPanicSliceAcap', 'runtime.goPanicSliceAcapU', 'runtime.goPanicSliceAlen', 'runtime.goPanicSliceAlenU', 'runtime.goPanicSliceB', 'runtime.goPanicSliceBU', 'runtime.goPanicSliceConvert', 'runtime.goexit', 'runtime.goexit0', 'runtime.goexit1', 'runtime.gogo', 'runtime.gopanic', 'runtime.goschedImpl', 'runtime.main', 'runtime.mcall', 'runtime.morestack', 'runtime.morestack_noctxt', 'runtime.morestackc', 'runtime.panicBounds', 'runtime.panicBounds32', 'runtime.panicBounds64', 'runtime.panicExtendIndex', 'runtime.panicExtendIndexU', 'runtime.panicExtendSlice3Acap', 'runtime.panicExtendSlice3AcapU', 'runtime.panicExtendSlice3Alen', 'runtime.panicExtendSlice3AlenU', 'runtime.panicExtendSlice3B', 'runtime.panicExtendSlice3BU', 'runtime.panicExtendSlice3C', 'runtime.panicExtendSlice3CU', 'runtime.panicExtendSliceAcap', 'runtime.panicExtendSliceAcapU', 'runtime.panicExtendSliceAlen', 'runtime.panicExtendSliceAlenU', 'runtime.panicExtendSliceB', 'runtime.panicExtendSliceBU', 'runtime.panicExtendSliceConvert', 'runtime.panicIndex', 'runtime.panicIndexU', 'runtime.panicSlice3Acap', 'runtime.panicSlice3AcapU', 'runtime.panicSlice3Alen', 'runtime.panicSlice3AlenU', 'runtime.panicSlice3B', 'runtime.panicSlice3BU', 'runtime.panicSlice3C', 'runtime.panicSlice3CU', 'runtime.panicSliceAcap', 'runtime.panicSliceAcapU', 'runtime.panicSliceAlen', 'runtime.panicSliceAlenU', 'runtime.panicSliceB', 'runtime.panicSliceBU', 'runtime.panicSliceConvert', 'runtime.panicdivide', 'runtime.panicdottypeE', 'runtime.panicdottypeI', 'runtime.panicfloat', 'runtime.panicmakeslicecap', 'runtime.panicmakeslicelen', 'runtime.panicmem', 'runtime.panicmemAddr', 'runtime.panicnildottype', 'runtime.panicoverflow', 'runtime.panicshift', 'runtime.panicunsafeslicelen', 'runtime.panicunsafeslicelen1', 'runtime.panicunsafeslicenilptr', 'runtime.panicunsafeslicenilptr1', 'runtime.panicunsafestringlen', 'runtime.panicunsafestringlen1', 'runtime.panicunsafestringnilptr', 'runtime.panicunsafestringnilptr1', 'runtime.panicwrap', 'runtime.park_m', 'runtime.schedule', 'runtime.sigpanic', 'runtime.sigpanic0', 'runtime.throw'})¶
Go runtime (and a few closely related standard library) functions that never transfer control back to the instruction following their call site.
runtime.morestackand friends do resume the caller, but at its entry point rather than at the return address, so they do not “return” in the sense CFG recovery cares about.Deliberately excluded because they can fall through to their caller despite the suggestive names:
runtime.mexit(returns when running on an OS-provided stack, and with itruntime.mstart0andruntime.mstart),runtime.badsystemstack,runtime.badmorestackg0,runtime.badmorestackgsignal(all only print),runtime.systemstack,runtime.panicCheck1,runtime.panicCheck2,runtime.startpanic_m,runtime.dopanic_m.
- angr.utils.go_runtime.has_go_hint(project)¶
Cheap test for “this might be a Go binary”, to keep the (much more expensive) LanguageDetector off the vast majority of binaries.
- angr.utils.go_runtime.normalize_go_func_name(name)¶
Strip the ABI wrapper suffix the Go linker appends to duplicated symbols.
- angr.utils.go_runtime.find_go_noreturn_functions(project, kb=None, use_names=True)¶
Identify Go runtime functions in
projectthat never return.The caller is responsible for having established that this is a Go binary.