angr.utils.go_runtime¶
Identification of Go runtime functions whose control flow CFG recovery cannot infer on its own.
angr has no built-in knowledge of the Go runtime, which gets two families of functions wrong:
Functions that never return to their call site, chiefly the bounds-check panic stubs emitted at essentially every index expression. Recovered as returning, they attach one dead panic branch per bounds check to every Go function.
Functions that never execute a
retbut still resume their caller at the return address:runtime.morestack(called from the stack-check trampoline of every non-leaf function) andruntime.mcall. Both save the caller’s return address ing.schedand the scheduler later resumes it withgogo. Inferred from their bodies, they look non-returning, which cuts the argument-reload stub after everymorestackcall site off its function and stops recovery of every caller ofruntime.goparkat the park.
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_CHECK_PANIC_NAMES: frozenset[str] = frozenset({'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.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.panicoverflow', 'runtime.panicshift', 'runtime.panicunsafeslicelen', 'runtime.panicunsafeslicelen1', 'runtime.panicunsafeslicenilptr', 'runtime.panicunsafeslicenilptr1', 'runtime.panicunsafestringlen', 'runtime.panicunsafestringlen1', 'runtime.panicunsafestringnilptr', 'runtime.panicunsafestringnilptr1'})¶
bounds/slice checks (per-kind stubs before go1.25, the
panicBoundsdispatcher after), integer division/shift checks, and the unsafe.Slice/String checks.- Type:
Panic helpers that only compiler-inserted checks call
- angr.utils.go_runtime.GO_ASSERT_PANIC_NAMES: frozenset[str] = frozenset({'runtime.panicdottypeE', 'runtime.panicdottypeI', 'runtime.panicnildottype'})¶
the check that guards them is the assertion itself.
- Type:
Failure stubs of type assertions (
x.(T))
- 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.execute', '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.morestackc', 'runtime.panicBounds', 'runtime.panicBounds32', 'runtime.panicBounds32X', 'runtime.panicBounds64', 'runtime.panicExtend', '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.panicunsafestringnilptr', '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, checked against the runtime sources of go1.4 to go1.27.
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, and the functions inGO_RESUMING_NAMES.
- angr.utils.go_runtime.GO_RESUMING_NAMES: frozenset[str] = frozenset({'runtime.mcall', 'runtime.morestack', 'runtime.morestack_noctxt'})¶
Go runtime functions that never execute a
ret, but whose callers are resumed at the return address: they save it ing.schedand the scheduler later continues there throughgogo. Their bodies end in calls that do not return (abort,badmcall2), so they must be marked as returning explicitly.
- angr.utils.go_runtime.GO_STACK_GROWTH_NAMES: frozenset[str] = frozenset({'runtime.morestack', 'runtime.morestack_noctxt', 'runtime.morestackc'})¶
morestack(andmorestack_noctxt) grows the stack and resumes the caller after the call, which reloads its arguments and restarts itself;morestackcis called instead by //go:systemstack functions and throws.- Type:
The goroutine stack-growth stubs called from function preambles
- 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.
- class angr.utils.go_runtime.GoRuntimeFunctions¶
Bases:
objectGo runtime functions identified in a binary, each mapped to a short description of the evidence.
- Variables:
noreturn (
dict[int,str]) – Functions that never return to their call site.resuming (
dict[int,str]) – Functions that never execute aretbut resume their caller at the return address.stack_growth (
dict[int,str]) – The stack-growth stubs that function preambles call (morestack and morestackc). Each is innoreturnorresumingas well.
- angr.utils.go_runtime.find_go_runtime_functions(project, kb=None, use_names=True)¶
Identify the Go runtime functions in
projectwhose control flow CFG recovery must be told about.The caller is responsible for having established that this is a Go binary.
- Parameters:
- Return type:
- angr.utils.go_runtime.find_go_noreturn_functions(project, kb=None, use_names=True)¶
Identify Go runtime functions in
projectthat never return. Seefind_go_runtime_functions().