From arc-probe
Finds all callers of a function address in binaries via xref scans, disassembles argument setup before call sites, and shows containing functions and string refs. Useful for reverse engineering native x64 code.
npx claudepluginhub vzco/arc-probe --plugin arc-probeThis skill uses the workspace's default tool permissions.
Find all functions that call a given function address. For each caller, disassemble the argument setup instructions before the call site to understand what parameters are being passed.
Builds reverse call tree from target function address by tracing callers upward multiple levels using xref scans and disassembly. Shows argument setup and call hierarchy.
Finds function call sites in binaries using VulHunt Lua queries. Useful for analyzing callers of functions, checking call relationships, or identifying API invocations.
Analyzes IDA cross-references to find callers, callees, imports, data references, call graphs, and dependency chains using SQL queries on xrefs and imports tables.
Share bugs, ideas, or general feedback.
Find all functions that call a given function address. For each caller, disassemble the argument setup instructions before the call site to understand what parameters are being passed.
address (required): Address of the target function (hex). Can be absolute or module+offset.module (optional): Module to search for callers in. If omitted, determined automatically from the address range.probe.exe "ping"
If using the bridge:
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"probe","command":"ping"}'
If the address is module+offset, resolve it to absolute:
probe.exe "modules list"
Compare the target address against each module's base + size range to identify which module it belongs to. Record the module name and base address.
probe.exe "disasm <address> 5"
Look for a function prologue at the address:
push rbp / sub rsp, 0x??push rbx / sub rsp, 0x??mov [rsp+8], rbx / sub rsp, 0x??sub rsp, 0x?? (leaf-like)If the first instruction is NOT a prologue, the user may have given a mid-function address. Search backwards for the start:
probe.exe "disasm <address - 0x80> 40"
Look for the prologue closest before the target address. Use the corrected function start for the xref scan.
probe.exe "xref scan <address> <module> --type CALL --limit 20"
This scans the module for CALL and JMP instructions whose target resolves to the function address. Each result includes:
source -- address of the calling instructionfunction -- enclosing function address (from .pdata)instruction -- the disassembled call/jmp instructionIf zero callers are found:
--type CALL,MOV to catch indirect references like mov rax, <addr>.probe.exe "modules list"
Then scan each relevant module.probe.exe "rtti scan <module>"
For each caller found, disassemble the 8 instructions leading up to the call to see the argument setup:
probe.exe "disasm <call_site_address - 0x20> 12"
Look for these argument-passing patterns (Windows x64 ABI):
mov rcx, ... or lea rcx, ... -- first argument (or this pointer)mov rdx, ... or lea rdx, ... -- second argumentmov r8, ... or lea r8, ... -- third argumentmov r9, ... or lea r9, ... -- fourth argumentmov [rsp+0x20], ... -- fifth argument (stack)Pay special attention to:
lea rcx, [rip+0x????] -- loading a string address as an argument. Resolve it:
probe.exe "read_string <resolved_rip_target>"
mov rcx, <register> where the register was loaded from a struct field -- reveals context about the caller.mov edx, 1, xor r8d, r8d) -- reveals parameter semantics.For each caller, check if the enclosing function has any identifying information:
a. Check for labels (if GUI bridge is running):
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"store","store":"label","method":"getLabel","args":["0x<enclosing_function>"]}'
b. Check for string references inside the caller function:
probe.exe "disasm func <enclosing_function>"
Scan the output for lea instructions with RIP-relative addressing and resolve them to strings.
c. Check function store (functions previously discovered):
probe.exe "functions at <enclosing_function>"
Format the output as a table:
Callers of sub_7FF612345678 (client.dll + 0x5678)
===================================================
# Caller Function Call Site Args Before Call
-- ---------------------- -------------------- ----------------------------------------
1 sub_7FF612340000 client.dll + 0x0042 lea rcx, [rip+0x1234] -> "player_name"
(client.dll + 0x0000) mov edx, [rbx+0x354] (health field)
xor r8d, r8d (arg3 = 0)
2 ProcessDamage client.dll + 0x1234 mov rcx, rsi (this pointer)
(client.dll + 0x1200) mov edx, edi (damage amount)
mov r8, [rsp+0x40] (stack local)
3 sub_7FF612342800 client.dll + 0x2842 lea rcx, [rbp+0x30] (local struct)
(client.dll + 0x2800) lea rdx, [rip+0x5678] -> "entity"
refs: "AI_TakeDamage" mov r8d, 1 (arg3 = 1)
Total: 3 direct callers found in client.dll
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" -d '{
"action":"batch","actions":[
{"action":"activity","status":"working","message":"Navigating to first caller..."},
{"action":"navigate","tab":"disasm","address":"0x<first_call_site>"},
{"action":"store","store":"label","method":"setLabel","args":["0x<target_function>","<function_name_or_addr>"]},
{"action":"activity","status":"idle","message":"Done — found N callers"}
]
}'
Also label each caller if a name was identified:
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"store","store":"label","method":"setLabel","args":["0x<caller_addr>","caller_name"]}'
this (RCX from a struct access pattern), trace it to understand the calling object's typejmp instead of call) are also callers -- xref scan catches these with --type CALLcall [rax+offset] (indirect) and won't appear in a direct xref scan