From arc-probe
Generates stable byte signatures for binary functions using disassembly and wildcards to survive updates. Useful for reverse engineering and locating functions post-rebuild.
npx claudepluginhub vzco/arc-probe --plugin arc-probeThis skill uses the workspace's default tool permissions.
Generate a byte signature for a function that survives binary updates.
Compares function disassembly between binary sessions: generates byte signatures to relocate functions after updates, disassembles, and reports changes. Useful for tracking patches.
Provides disassembly patterns for x86-64 (System V/Microsoft) and ARM binaries, including function prologues/epilogues and calling conventions. Use for static analysis of executables.
Provides x86-64/ARM disassembly patterns, calling conventions, control flow recognition for static analysis of executables and compiled binaries.
Share bugs, ideas, or general feedback.
Generate a byte signature for a function that survives binary updates.
address (required): Address of the function (hex)module (optional): Module name for contextBinary updates change function addresses but rarely change the instruction sequence. A byte signature captures the function's unique bytes with wildcards for parts that change (relocations, offsets). This lets you find the function again after every update.
Disassemble the function start:
probe_disassemble address=<addr> count=15
Look at the first 15-20 instructions. The function prologue and early logic are usually the most unique.
Auto-generate a signature:
probe_generate_signature address=<addr> size=32
Returns a pattern with ?? wildcards for bytes that are likely to change between builds.
Test uniqueness:
probe_test_signature address=<addr> module=<module>
A good signature has exactly 1 match. If it has multiple matches, you need a longer or more specific signature.
If not unique, extend the signature:
probe_generate_signature address=<addr> size=64Verify the signature finds the right function:
probe_pattern_scan pattern=<signature> module=<module>
The result should be the original function address.
Always wildcard:
48 8B 05, 48 8D 0D, E8, etc.) — these change every buildNever wildcard:
48 8B, 48 89, E8, etc.) — these define the instruction typeIf auto-generation fails, read the raw bytes and apply wildcards manually:
Address Bytes Instruction
7FF6A000 48 89 5C 24 08 mov [rsp+8], rbx ; stable
7FF6A005 57 push rdi ; stable
7FF6A006 48 83 EC 20 sub rsp, 0x20 ; stack size might change
7FF6A00A 48 8B D9 mov rbx, rcx ; stable
7FF6A00D E8 XX XX XX XX call SomeFunc ; wildcard the call target
7FF6A012 48 85 C0 test rax, rax ; stable
7FF6A015 74 XX je short label ; wildcard the branch offset
Resulting signature:
48 89 5C 24 08 57 48 83 EC ?? 48 8B D9 E8 ?? ?? ?? ?? 48 85 C0 74 ??
Good:
48 89 5C 24 08 57 48 83 EC 20 48 8B D9 E8 ?? ?? ?? ?? 48 85 C0
Bad:
48 89 5C 24 ?? 48 83 EC ??
Rule of thumb: 16-32 bytes with 2-4 wildcards is usually enough. If you need more than 48 bytes, the function might not be unique enough — consider combining with a module name filter.
__fastcall (default x64) typically saves non-volatile registers and allocates stack