From arc-probe
Analyzes a single x64 function in a binary: disassembles code, identifies arguments and calling convention, finds string refs and xrefs, detects RTTI, generates signatures, labels in GUI.
npx claudepluginhub vzco/arc-probe --plugin arc-probeThis skill uses the workspace's default tool permissions.
Full analysis of a single function at a given address. Disassembles it, identifies arguments and return type, finds string references within it, maps callers and callees, checks for RTTI context, generates a signature, and labels everything in the GUI.
Detects function parameters in Windows x64 binaries by analyzing prologue, register usage, and instruction patterns to infer count, types, and calling convention.
Triages and audits IDA binaries to detect suspicious behavior, crypto/network activity, review decompiled code against source, and run multi-table queries.
Performs deep static binary analysis using radare2 and Ghidra for function enumeration, disassembly, decompilation, xrefs, and control flow graphs. Use for reverse engineering binaries without execution.
Share bugs, ideas, or general feedback.
Full analysis of a single function at a given address. Disassembles it, identifies arguments and return type, finds string references within it, maps callers and callees, checks for RTTI context, generates a signature, and labels everything in the GUI.
address (required): Address of the function (hex). Can be absolute or module+offset.module (optional): Module the function belongs to (e.g., "client.dll"). If omitted, determined automatically from address range.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. If the address is given as module+offset, resolve it to absolute.
If the address doesn't fall within any loaded module, it may be JIT-compiled or heap-allocated code. Note this and proceed with limited analysis (no xref scanning, no signature testing against a module).
First, try to land on the function start. If the given address might be mid-function, check for a prologue:
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 / push rdi / sub rsp, 0x??sub rsp, 0x?? (leaf-like)If the first instruction is NOT a prologue, the user may have given an address mid-function. Disassemble backwards to find the start:
probe.exe "disasm <address - 0x80> 40"
Scan forward through the output looking for the prologue pattern closest before the target address. The function start is typically right after a ret or int3 padding (CC CC CC).
probe.exe "disasm func <function_start>"
This disassembles until a ret instruction. Record:
ret + instruction length)If disasm func returns too many instructions (>500) or doesn't find a ret, the function may be very large or use tail calls. Fall back to disassembling a fixed count:
probe.exe "disasm <function_start> 200"
Analyze the function prologue and body for argument usage:
Register arguments (Microsoft x64 ABI):
this pointer for member functions)Look for these patterns in the disassembly:
mov [rsp+...], rcx early on — saves first arg, confirms it's usedtest rcx, rcx / cmp rcx, 0 — null check on first arg (likely a pointer)mov rax, [rcx] — loading vtable from first arg means RCX is a this pointer (member function)movss xmm0, [rcx+0x??] — reading float fields from first argReturn type clues:
xor eax, eax before ret — returns 0 (bool or int)mov eax, [rcx+0x??] then ret — getter returning int32movss xmm0, [rcx+0x??] then ret — getter returning floatlea rax, [rcx+0x??] then ret — returns pointer to sub-objectScan the disassembly output for LEA instructions with RIP-relative addressing:
lea rcx, [rip+0x????] ; loads a string address
lea rdx, [rip+0x????] ; second string argument
For each LEA with a RIP-relative operand, the target address is: LEA_address + instruction_length + displacement. Read the string at that address:
probe.exe "read_string <resolved_address>"
If the string is readable, it reveals the function's purpose. Common patterns:
"Failed to initialize %s""[%s] Player %d connected""CBaseEntity::TakeDamage"probe.exe "xref scan <function_start> <module> --type CALL --limit 20"
This scans the module for CALL instructions whose target is this function. Each result includes:
For each caller, note the enclosing function address. These are the function's callers.
If zero callers are found:
--type CALL,MOV to catch indirect references.probe.exe "xref scan <function_start> <module> --callees --limit 30"
This disassembles the function and collects all CALL/JMP targets. Each result includes:
For interesting callees, do a quick identification:
probe.exe "disasm <callee_address> 5"
Look for recognizable patterns — tiny getters, known API functions, or functions with string references.
If step 4 identified the function as a member function (uses this in RCX), check for RTTI:
probe.exe "rtti resolve <any_object_pointer_of_this_class>"
If you don't have an object pointer, check if the function appears in any vtable:
probe.exe "rtti scan <module>"
Search the results for a vtable entry matching the function address. If found, you know:
probe.exe "sig <function_start> 32 <module>"
Test the signature for uniqueness:
probe.exe "pattern <signature> <module>"
A good signature has exactly 1 match. If it has multiple matches:
probe.exe "sig <function_start> 64 <module>"
Try a longer signature. If still not unique, note that the function has duplicate prologues and requires a longer or manually-crafted signature.
If the GUI bridge is available, label the function and navigate to it:
# Set activity status
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"activity","status":"working","message":"Labeling function..."}'
# Label the function
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"batch","actions":[
{"action":"store","store":"label","method":"setLabel","args":["0x<function_start>","<function_name_or_description>"]},
{"action":"navigate","tab":"disasm","address":"0x<function_start>"},
{"action":"activity","status":"idle","message":"Done"}
]}'
Also label any identified callers/callees:
curl -s -X POST http://localhost:9996 -H "Content-Type: application/json" \
-d '{"action":"store","store":"label","method":"setLabel","args":["0x<caller_addr>","caller: <description>"]}'
Present a structured analysis:
Function Analysis: <name or description>
======================================
Address: 0x7FF612345678 (<module> + 0x5678)
Size: 0x1A0 bytes (~96 instructions)
Signature: 48 89 5C 24 08 57 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ??
Calling Convention: __fastcall (x64)
Arguments:
RCX = this pointer (C_BaseEntity*)
RDX = int32 damage amount
R8 = pointer to damage info struct
Returns: int32 (remaining health)
Strings Referenced:
+0x42: lea rcx, "CBaseEntity::TakeDamage"
+0x8A: lea rdx, "Entity %d took %d damage"
Callers (3):
0x7FF612340000 (<module> + 0x0000) — GameRules::ProcessDamage
0x7FF612341200 (<module> + 0x1200) — CombatSystem::ApplyHit
0x7FF612342800 (<module> + 0x2800) — AI_TakeDamage
Callees (5):
+0x1F: CALL 0x7FF612350000 — GetHealth (getter, returns [rcx+0x354])
+0x35: CALL 0x7FF612350100 — SetHealth (setter, writes [rcx+0x354])
+0x58: CALL 0x7FF612360000 — LogMessage (references format string)
+0x7A: CALL 0x7FF612370000 — Unknown (large function, ~0x400 bytes)
+0xA2: JMP 0x7FF612380000 — tail call to cleanup function
RTTI: CBaseEntity (vtable index 12)
Small functions are usually:
mov eax, [rcx+offset]; ret — report the field offset and typemov [rcx+offset], edx; ret — report the field offsetjmp <other_function> — follow the jump and analyze the real functionFor these, the full analysis is overkill. Just report the function type, the field offset (for getters/setters), and the target (for thunks).
CC CC CC padding (int3 alignment) before the address and try the next instruction after padding.jmp chains, unusual control flow, or encrypted instruction sequences.dump <address> 64 to see if it looks like data patterns rather than instruction bytes.