v0.8.9
Quick Start
- Download the binary for your OS below
- Run
agent-tool install(oragent-tool install claude) - Restart your IDE
- Done -- all tools work immediately, no permission popups
Or just ask your AI agent:
"Download agent-tool from https://github.com/knewstimek/agent-tool/releases/latest and run
agent-tool install"
Any capable AI coding agent (Claude Code, Codex, etc.) can handle the full download -> install -> restart flow automatically.
Tip: Add this to your CLAUDE.md or AGENTS.md so your agent prefers agent-tool over built-in tools:
Strict mode:
ALWAYS use agent-tool MCP tools (mcp__agent-tool__*) instead of built-in file tools. agent-tool preserves file encoding and respects .editorconfig indentation settings.
Soft mode:
Prefer agent-tool MCP tools (mcp__agent-tool__*) over built-in file tools when available.
Reverse engineering: function_at coverage + trust, round 2
v0.8.8 made analyze function_at trustworthy for PE binaries without .pdata (32-bit x86 DLLs, stripped x64): every result carries an explicit start_source + confidence, and a wrong start is never presented as authoritative. v0.8.9 widens what resolves correctly while tightening the heuristic path so it can never upgrade a mid-function address to a confident start. All measurements below are on the Diablo II DLLs (D2Game.dll, D2Common.dll, D2Client.dll, ...), the ordinal-only, .pdata-less x86 corpus this work targets.
More internal function starts recognized (x86 prologue DB)
The strong-prologue classifier learned six more MSVC/GCC entry idioms, validated against the D2 DLLs and cross-checked with Ghidra (x86win_patterns.xml) and radare2/rizin: the hot-patch pad (8B FF 55 8B EC), the GCC frame (55 89 E5), the thiscall this-save (56 8B F1), push ebp; mov ebp,[esp+N] (55 8B 6C 24), a three-register callee-save (53 56 57), and the frameless leaf mov eax,[esp+N] (8B 44 24). Genuine internal (non-exported, non-discovered) starts recognized at medium confidence jumped sharply -- D2Common 303 -> 993, D2Game 971 -> 1220, D2Client 792 -> 980. Each pattern's false-positive surface at a heuristic boundary stays at or below the already-trusted sub esp baseline. x86-only (the path x64 reaches via .pdata is unchanged).
Mid-function false positives eliminated (int3-run gate)
A strong prologue can also appear inside a function -- a nested frame setup, or a frameless leaf's mov eax,[esp]. When the CFG proof from a known start failed (a jump table or indirect branch breaking the walk), the backward scan could land on one of those mid-function prologues and label it medium: a confident-wrong start, the exact failure class this module exists to prevent. function_at now requires a strong-prologue start to either be preceded by an int3 padding run, or not be enclosed by a nearer known function. Measured on the corpus, this removes ~99.7% of mid-function medium mislabels (D2Game 4948 -> 0, D2Common 1639 -> 0, D2Client 3110 -> 27) while keeping every real int3-padded internal start at medium. It also clears pre-existing false positives from the older 55 8B EC / 83 EC patterns, so function_at is now stricter than before the prologue expansion, not just break-even.
Switch jump tables are followed (including .rdata/.data)
The CFG walk used to stop dead at an x86 jmp dword ptr [idx*4 + disp32] switch, so every basic block after a switch looked unreachable -- the dominant reason an in-body query failed to reach its real start and fell to low. The walk now resolves the table (reading the absolute case addresses, requiring each to be code) and continues into the case blocks as part of the same function. Tables inlined in .text and tables the compiler placed in .rdata/.data are both handled. In-body reachability rose several points per DLL (D2Game 85.9% -> 89.8%, D2Common 86.9% -> 93.8%, D2Client 83.9% -> 91.5%) -- thousands of switch-case addresses per DLL now anchor at high confidence instead of a heuristic low. This mirrors angr's CFGFast jump-table analysis, kept deliberately narrow: only the pure-disp32 form is resolved (a based index is an array access, not a switch), a hard entry cap bounds the read, and the existing walls (other known starts, int3 runs) still bound every case target -- so a stray entry can never bleed into a neighbouring function.
disassemble: higher cap + truncation hint
The instruction cap rose from 600 to 1000, and when output hits the cap mid-function (not a ret/boundary) with bytes still ahead, it now prints a one-line note with a resume va so an agent paginates instead of assuming it saw the whole function. The count default stays 50 (normal calls are unchanged), and the parameter description now advertises the cap and stop_at_ret so agents know they can raise it.
Robustness (audit)
A GPT-5.5 audit pass (findings verified against the binary) hardened the new paths: jump-table case targets are filtered to in-range / unvisited before traversal, bounding stack growth against a crafted table whose entries re-point at their own switch; and the .pdata slice length is computed in 64-bit to avoid a 32-bit wrap that a malformed exception-table size could otherwise turn into a slice-bounds panic.
Full Changelog: v0.8.8...v0.8.9