GE

generate-signature-for-function

Creates persistent, pattern-scannable byte signatures for functions using IDA Pro to ensure stability across binary updates.

Install

mkdir -p .claude/skills/generate-signature-for-function && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/13409" && unzip -o skill.zip -d .claude/skills/generate-signature-for-function && rm skill.zip

Installs to .claude/skills/generate-signature-for-function

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Generate and validate unique byte signatures for functions using IDA Pro MCP. Use this skill when you need to create a pattern-scanning signature for a function that can reliably locate it across binary updates. Triggers: generate signature, byte signature, pattern signature, function signature, unique signature, sig for function
331 chars✓ has a “when” triggerlonger than Claude Code's old 250-char listing cap (fine on current versions)
Intermediate

Key capabilities

  • Generate unique hex byte signatures for functions
  • Programmatically detect wildcards in signatures
  • Validate signature uniqueness through progressive testing
  • Resolve input addresses to actual function starts
  • Output the shortest unique signature directly

How it works

The skill resolves the input address to the function start, decodes instructions, programmatically determines wildcard positions, and progressively tests at each instruction boundary via binary search to output the shortest unique signature.

Inputs & outputs

You give it
Function address (input_addr)
You get back
JSON object with func_sig (space-separated hex bytes with ?? for wildcards) or error message

When to use generate-signature-for-function

  • Create function signature
  • Verify signature uniqueness
  • Prepare pattern scan for binary update

About this skill

Generate Signature for Function

Generate a unique hex byte signature for a function using fully programmatic wildcard detection and validation — no manual byte analysis required.

Prerequisites

  • Function address (from decompilation, xrefs, or rename)
  • IDA Pro MCP connection

Method

1. Generate and Validate Signature (Single Step)

Use a single py_eval call that:

  • Resolves the input address to the actual function start
  • Decodes instructions and programmatically determines wildcard positions
  • Tracks instruction boundaries so prefixes always cover complete instructions
  • Progressively tests at each instruction boundary via binary search
  • Outputs the shortest unique signature directly

Note: The input address may be in the middle of a function. The script automatically resolves it to the actual function start.

mcp__ida-pro-mcp__py_eval code="""
import idaapi, ida_bytes, idautils, ida_ua, ida_segment, json

input_addr = <func_addr>
min_sig_bytes = 6
max_sig_bytes = 96
max_instructions = 64

# --- Binary search wrapper (IDA 9.0+ find_bytes -> older bin_search fallback) ---
def raw_bin_search(ea, max_ea, data, mask, flags=0):
    if hasattr(ida_bytes, 'find_bytes'):
        return ida_bytes.find_bytes(data, ea, range_end=max_ea, mask=mask, flags=flags)
    return ida_bytes.bin_search(ea, max_ea, data, mask, len(data), flags)

# --- Resolve to actual function start ---
func = idaapi.get_func(input_addr)
if not func:
    print(json.dumps({"error": f"{hex(input_addr)} is not inside a known function", "status": "failed"}))
    raise SystemExit

func_addr = func.start_ea
if func_addr != input_addr:
    print(f"NOTE: Resolved {hex(input_addr)} -> function start at {hex(func_addr)}")

# --- Collect instruction bytes with auto-wildcarding ---
limit_end = min(func.end_ea, func_addr + max_sig_bytes)
sig_tokens = []
inst_boundaries = []  # cumulative byte count at end of each instruction
cursor = func_addr

while cursor < func.end_ea and cursor < limit_end and len(sig_tokens) < max_sig_bytes:
    insn = idautils.DecodeInstruction(cursor)
    if not insn or insn.size <= 0:
        break
    raw = ida_bytes.get_bytes(cursor, insn.size)
    if not raw:
        break

    wild = set()

    # Auto-wildcard volatile operand bytes (imm/near/far/mem/displ)
    for op in insn.ops:
        op_type = int(op.type)
        if op_type == int(idaapi.o_void):
            continue
        if op_type in (int(idaapi.o_imm), int(idaapi.o_near), int(idaapi.o_far), int(idaapi.o_mem), int(idaapi.o_displ)):
            offb = int(op.offb)
            if offb > 0 and offb < insn.size:
                dsz = ida_ua.get_dtype_size(getattr(op, 'dtype', getattr(op, 'dtyp', 0)))
                if dsz <= 0:
                    dsz = insn.size - offb
                end = min(insn.size, offb + dsz)
                for i in range(offb, end):
                    wild.add(i)
            offo = int(op.offo)
            if offo > 0 and offo < insn.size:
                dsz2 = ida_ua.get_dtype_size(getattr(op, 'dtype', getattr(op, 'dtyp', 0)))
                if dsz2 <= 0:
                    dsz2 = insn.size - offo
                end2 = min(insn.size, offo + dsz2)
                for i in range(offo, end2):
                    wild.add(i)

    # Special handling for call/jump instructions
    b0 = raw[0]
    if b0 in (0xE8, 0xE9, 0xEB):
        for i in range(1, insn.size):
            wild.add(i)
    elif b0 == 0x0F and insn.size >= 2 and (raw[1] & 0xF0) == 0x80:
        for i in range(2, insn.size):
            wild.add(i)
    elif 0x70 <= b0 <= 0x7F:
        for i in range(1, insn.size):
            wild.add(i)

    for idx in range(insn.size):
        sig_tokens.append("??" if idx in wild else f"{raw[idx]:02X}")

    inst_boundaries.append(len(sig_tokens))
    cursor += insn.size

if not sig_tokens:
    print(json.dumps({"error": f"no instruction bytes at {hex(func_addr)}", "status": "failed"}))
    raise SystemExit

# --- Search bounds ---
seg = ida_segment.get_segm_by_name(".text")
if seg:
    search_start, search_end = seg.start_ea, seg.end_ea
else:
    search_start, search_end = idaapi.cvar.inf.min_ea, idaapi.cvar.inf.max_ea

# --- Progressive search at instruction boundaries only ---
best_sig = None

for boundary in inst_boundaries:
    if boundary < min_sig_bytes:
        continue

    prefix_tokens = sig_tokens[:boundary]
    if all(t == "??" for t in prefix_tokens):
        continue

    data = bytes(0 if t == "??" else int(t, 16) for t in prefix_tokens)
    mask = bytes(0x00 if t == "??" else 0xFF for t in prefix_tokens)
    flags = ida_bytes.BIN_SEARCH_FORWARD | ida_bytes.BIN_SEARCH_NOBREAK

    matches = []
    ea = raw_bin_search(search_start, search_end, data, mask, flags)
    while ea != idaapi.BADADDR and len(matches) < 2:
        matches.append(ea)
        ea = raw_bin_search(ea + 1, search_end, data, mask, flags)

    if len(matches) == 1 and matches[0] == func_addr:
        best_sig = " ".join(prefix_tokens)
        break

if best_sig:
    print(json.dumps({
        "func_va": hex(func_addr),
        "func_rva": hex(func_addr - idaapi.get_imagebase()),
        "func_size": hex(func.end_ea - func_addr),
        "func_sig": best_sig,
        "sig_bytes": len(best_sig.split()),
        "status": "success"
    }))
else:
    print(json.dumps({
        "func_va": hex(func_addr),
        "func_size": hex(func.end_ea - func_addr),
        "total_tokens": len(sig_tokens),
        "sig_full": " ".join(sig_tokens),
        "error": "no unique prefix found within collected bytes",
        "status": "failed"
    }))
"""

Result handling:

  • status == "success" → Use func_sig directly as the final signature
  • status == "failed" → See Step 2

2. Iterate if Needed

If Step 1 returns status: "failed":

  1. Increase max_sig_bytes (e.g., to 192) and re-run Step 1
  2. Consider including bytes beyond the function boundary
  3. Re-run until unique

3. Continue with Unfinished Tasks

If we are called by a task from a task list / parent SKILL, restore and continue with the unfinished tasks.

Output Format

Signature format: space-separated hex bytes with ?? for wildcards.

Example: 48 89 5C 24 ?? 48 89 74 24 ?? 57 48 83 EC ?? 48 8B F9 E8 ?? ?? ?? ??

When not to use it

  • When manual byte analysis is preferred over programmatic wildcard detection
  • When IDA Pro MCP connection is not available
  • When the function address is unknown

Prerequisites

Function address (from decompilation, xrefs, or rename)IDA Pro MCP connection

Limitations

  • Requires an IDA Pro MCP connection.
  • Requires a known function address.
  • If no unique prefix is found within collected bytes, it reports an error.

How it compares

This skill automates wildcard detection and validation, eliminating manual byte analysis and progressively testing for uniqueness, unlike manual signature creation.

Compared to similar skills

generate-signature-for-function side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
generate-signature-for-function (this skill)04moNo flagsIntermediate
game-engine-resources144moNo flagsAdvanced
graphics-api-hooking72moNo flagsAdvanced
idapython47moNo flagsAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

You might also like

game-engine-resources

gmh5225

Guide for game engine development resources including engine source code, plugins, and development guides. Use this skill when researching game engines (Unreal, Unity, Godot, custom engines), engine architecture, or game development frameworks.

1485

graphics-api-hooking

gmh5225

Guide for graphics API hooking and rendering techniques for DirectX, OpenGL, and Vulkan. Use this skill when working with graphics hooks, overlay rendering, shader manipulation, or game rendering pipeline analysis.

725

idapython

mrexodia

IDA Pro Python scripting for reverse engineering. Use when writing IDAPython scripts, analyzing binaries, working with IDA's API for disassembly, decompilation (Hex-Rays), type systems, cross-references, functions, segments, or any IDA database manipulation. Covers ida_* modules (50+), idautils iterators, and common patterns.

422

static-analysis

gmh5225

Expertise in LLVM-based static analysis including dataflow analysis, pointer analysis, taint tracking, and program verification. Use this skill when implementing security scanners, bug finders, code quality tools, or performing program analysis research.

518

memory-safety-patterns

sickn33

Implement memory-safe programming with RAII, ownership, smart pointers, and resource management across Rust, C++, and C. Use when writing safe systems code, managing resources, or preventing memory bugs.

415

libfuzzer

trailofbits

Coverage-guided fuzzer built into LLVM for C/C++ projects. Use for fuzzing C/C++ code that can be compiled with Clang.

14

Search skills

Search the agent skills registry