Kong does not analyze functions in an arbitrary order. It builds a call graph from the binary, computes a bottom-up ordering, and processes functions from the leaves upward. This single design decision is one of the biggest factors in analysis quality.Documentation Index
Fetch the complete documentation index at: https://docs.kong.fyi/llms.txt
Use this file to discover all available pages before exploring further.
What is a Call Graph?
When Ghidra loads a binary, it identifies cross-references between functions — which function calls which. Kong queries these cross-references during the triage phase and builds caller/callee adjacency lists for every function in the binary. The call graph captures the dependency structure of the program. Higher-level functions depend on lower-level ones. An HTTP server’smain might call start_server, which calls handle_connection, which calls parse_request, which calls read_line. Understanding read_line makes parse_request clearer, which makes handle_connection clearer, and so on.
Why Bottom-Up Order Matters
The core problem: when Ghidra decompiles a stripped binary, every function has an auto-generated name likeFUN_00401a30. When the LLM analyzes a function, its decompilation includes calls to other functions — and those calls show up as FUN_ labels.
If Kong analyzed handle_request before its callees, the LLM would see something like:
FUN_00401a30 and FUN_00401c10 do based on how they are called. It can make reasonable guesses, but they are guesses.
If Kong instead analyzes the callees first and writes their names back to Ghidra immediately, the decompilation of handle_request now shows:
handle_request — a much better result than it would produce from the FUN_ version.
This is why immediate writeback matters. As soon as the LLM names a function, Kong writes that name back into Ghidra’s program database. Every subsequent decompilation benefits from all previously recovered names.
How the BFS Work Queue Works
Kong computes the bottom-up ordering using a breadth-first search (BFS) from leaf functions.Step 1: Identify leaf functions
A leaf function is one that has no callees within the set of functions being analyzed. It might call external library functions (likemalloc or printf), but those are already named — they were identified as IMPORTED during triage and excluded from analysis.
Step 2: Assign depths via BFS
Starting from the leaves (depth 0), Kong traverses the call graph upward through callers:- All leaf functions get depth 0.
- For each function at the current depth, look at its callers.
- A caller’s depth is the maximum depth of any of its callees, plus one.
- Repeat until every reachable function has a depth.
Step 3: Build the priority queue
Functions are sorted by depth (ascending), with ties broken by function size (smaller first). This produces the analysis order: leaves first, then their direct callers, then the callers of callers, up to the top-level entry points.A Concrete Example
Consider a small binary with four functions:| Function | Callees (analyzed) | Depth |
|---|---|---|
parse_request | none | 0 (leaf) |
send_response | none | 0 (leaf) |
log_startup | none | 0 (leaf) |
handle_connection | parse_request, send_response | 1 |
main | handle_connection, log_startup | 2 |
parse_request(depth 0)send_response(depth 0)log_startup(depth 0)handle_connection(depth 1) — decompilation now showsparse_requestandsend_responseby namemain(depth 2) — decompilation now showshandle_connectionandlog_startupby name
main, every function it calls has already been named. The LLM sees real names in the decompilation and produces a much better result.
Priority within the same depth
Within the same BFS depth, Kong processes smaller functions first. The priority for each function is computed as:What Gets Skipped
Not every function enters the work queue. During triage, the following classifications are excluded:IMPORTED— External library functions that are already named (e.g.,malloc,printf,send).THUNK— Thin wrappers that simply jump to another function. Ghidra already resolves these.
TRIVIAL functions (16 bytes or fewer) enter the queue but are marked as skipped during analysis — they are too small for the LLM to meaningfully analyze, and their names rarely matter to callers.
Everything else (SMALL, MEDIUM, LARGE) is analyzed in full.
Handling Cycles
Real call graphs can contain cycles (recursion, mutual recursion). Kong’s BFS handles this by tracking visited nodes. If a function has already been assigned a depth through one path, a later path can only increase its depth, never decrease it. Cyclic functions end up at the depth of their deepest non-cyclic dependency plus one. In practice, most binaries have relatively few cycles. The BFS still produces a useful ordering — the recursive functions get analyzed after their non-recursive dependencies.Next Steps
- Pipeline Overview — how call-graph analysis fits into the five-phase pipeline
- Context Windows — what information each LLM call receives
- Analyzing a Binary — end-to-end walkthrough of running an analysis

