Générer signature de fonction

VérifiéSûr

Générer et valider des signatures d'octets uniques pour les fonctions avec IDA Pro MCP. Localiser les fonctions de manière fiable à travers les mises à jour binaires.

Spar Skills Guide Bot
SecuriteAvancé
25/07/2026
Claude CodeCursor
#reverse-engineering#ida-pro#binary-analysis#signatures#mcp

Recommandé pour

Synthèse automatique

Génère et valide automatiquement une signature d'octets unique pour une fonction analysée dans IDA Pro via le serveur MCP, en détectant les opérandes volatils à remplacer par des jokers.

Points forts

  • Automatise entièrement la détection des jokers en analysant les types d'opérandes (imm, near, far, mem, displ) et les instructions call/jump.
  • Résout l'adresse fournie vers le véritable début de fonction, même si l'utilisateur pointe au milieu du corps.
  • Recherche par dichotomie la signature la plus courte restant unique dans le binaire, en s'arrêtant toujours sur des frontières d'instructions complètes.
  • Gère la compatibilité entre les versions d'IDA en basculant de find_bytes vers bin_search.

Limites

  • Nécessite une instance IDA Pro avec le serveur MCP ida-pro-mcp connecté et une fonction déjà identifiée par l'analyse.
  • La validité de la signature reste liée au binaire courant : elle peut ne plus être unique après une mise à jour importante du programme.
  • Le script fourni est un extrait et suppose une exécution via py_eval, ce qui demande une certaine familiarité avec l'API IDAPython.
Quand l'utiliser

Utilisez cette compétence lorsque vous devez créer une signature de pattern stable pour retrouver une fonction dans des versions successives d'un binaire.

Quand l'éviter

Évitez-la si vous n'avez pas d'environnement IDA Pro avec MCP actif ou si vous cherchez simplement à renommer ou décompiler une fonction.

Analyse de sécurité

Sûr
Score qualité88/100

The skill instructs the AI to run a Python script via IDA Pro MCP's py_eval to analyze binary functions and generate byte signatures. The script only reads binary bytes, resolves function boundaries, and performs pattern searches within the loaded IDA database. It does not execute destructive commands, access the network, exfiltrate data, or modify files. The use of py_eval is scoped to a specific, read-only analysis task.

Aucun point d'attention détecté

Comment cette analyse est faite

Exemples

Signature for a known function
Generate a unique byte signature for the function at 0x00401A30 so I can find it again in the next build of this DLL.
Signature from a mid-function address
I'm sitting at 0x14000F2C inside a function — produce the shortest unique pattern signature for the whole function and show me the wildcarded bytes.
Validate signature uniqueness
Create a pattern-scanning signature for this function and confirm it matches exactly one location in the binary.

name: generate-signature-for-function description: | 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

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 ?? ?? ?? ??

Du fichier au premier essai

Le téléchargement contient exactement le contenu affiché sur cette fiche. Cette copie peut différer de la dernière version du dépôt source.

Consulter la source et ses fichiers annexes

Ce téléchargement contient uniquement SKILL.md. Les scripts, références, modèles et dépendances éventuels ne sont pas inclus. Récupérez les fichiers nécessaires depuis la source en conservant leur arborescence avant de poursuivre.

1. Télécharger le fichier

Télécharger SKILL.md

Depuis la racine d’un projet de test, enregistrez le fichier sous .skill-downloads/generate-function-signature-mrzxurg0/SKILL.md, ou utilisez la commande suivante. Ce dossier sert à examiner la skill avant son installation.

Commande pour macOS/Linux ou WSL : un shell POSIX et curl sont nécessaires. Sous Windows sans WSL, utilisez le bouton de téléchargement et créez le dossier manuellement.

mkdir -p '.skill-downloads/generate-function-signature-mrzxurg0' && curl --fail --show-error --location 'https://skills-guides.com/api/skills/generate-function-signature-mrzxurg0/download' --output '.skill-downloads/generate-function-signature-mrzxurg0/SKILL.md.part' && mv '.skill-downloads/generate-function-signature-mrzxurg0/SKILL.md.part' '.skill-downloads/generate-function-signature-mrzxurg0/SKILL.md'

2. Vérifier les prérequis

Lisez SKILL.md avant de l’utiliser. Si le fichier cite des scripts ou services externes, examinez-les et préparez les accès nécessaires dans votre environnement de test.

Extrait original : Prerequisites
  • Function address (from decompilation, xrefs, or rename)
  • IDA Pro MCP connection

Les plateformes de la fiche sont des indications du catalogue. Les chemins ci-dessous suivent la documentation des outils ; ils ne prouvent pas que cette skill y a été exécutée. Aucune version minimale de ces outils n’est attestée pour cette fiche.

3. Charger la skill

Après vérification, copiez le dossier complet dans le projet avec l’une des commandes ci-dessous, puis ouvrez une nouvelle session de l’outil. La commande s’arrête si un dossier du même nom existe déjà : comparez les fichiers avant de le remplacer.

Claude Code
test -f '.skill-downloads/generate-function-signature-mrzxurg0/SKILL.md' && test -s '.skill-downloads/generate-function-signature-mrzxurg0/SKILL.md' && mkdir -p '.claude/skills' && test ! -e '.claude/skills/generate-signature-for-function' && cp -R '.skill-downloads/generate-function-signature-mrzxurg0' '.claude/skills/generate-signature-for-function'

Cursor
test -f '.skill-downloads/generate-function-signature-mrzxurg0/SKILL.md' && test -s '.skill-downloads/generate-function-signature-mrzxurg0/SKILL.md' && mkdir -p '.cursor/skills' && test ! -e '.cursor/skills/generate-signature-for-function' && cp -R '.skill-downloads/generate-function-signature-mrzxurg0' '.cursor/skills/generate-signature-for-function'

OpenSkills

OpenSkills doit déjà être installé. La procédure locale install/read est contrôlée avec OpenSkills 1.5.0, qui exige Node.js ≥ 20.6.0. Aucun slug du catalogue n’est résolu automatiquement.

Installation officielle d’OpenSkills
openskills install './.skill-downloads/generate-function-signature-mrzxurg0'

openskills read 'generate-function-signature-mrzxurg0'

La lecture doit afficher le contenu du fichier installé et son dossier de base. Elle ne lance ni la skill ni ses dépendances.

Pour un agent qui lit AGENTS.md, synchronisez ensuite l’index. Cette commande modifie AGENTS.md : relisez le diff avant de l’utiliser.

openskills sync

Mode manuel ou autre outil : joignez SKILL.md à une conversation, ou ouvrez-le dans un agent capable de lire les fichiers. Ajoutez les ressources annexes nécessaires. Il n’existe pas de dossier universel reconnu par tous les outils.

4. Faire un premier essai

Utilisez une entrée courte et fictive : un endpoint d’API, un petit document ou un brief d’interface. Dans une nouvelle conversation, joignez le fichier ou donnez son chemin à l’agent, puis adaptez cette demande :

Lis .skill-downloads/generate-function-signature-mrzxurg0/SKILL.md et applique ses instructions à cet exemple : [décrire une entrée de test]. Indique les fichiers, dépendances ou accès qui manquent. Produis le résultat demandé par la skill sans inventer de données ni exécuter de script non examiné.

Résultat attendu : une sortie correspondant aux instructions de la skill, ou une liste précise des prérequis manquants. Une simple confirmation de lecture ne valide pas le premier usage. Si une ressource externe est indisponible, ce parcours reste à tester.

Skills similaires