Write Struct Offset as YAML

SkillFiles & storage

Write struct member offset analysis results as YAML file beside the binary using IDA Pro MCP. Use this skill after identifying a struct member offset and optionally generating a signature for it to persist the results in a standardized YAML format.

Available today. Use it from your connected AI after setup.

Connect ahel once, and every AI you use reads what you have installed.

Then ask your AI: use the Write Struct Offset as YAML skill

What this skill tells your AI

The instructions your AI receives, as published by hlnd2t/cs2_vibesignatures in .claude/skills/write-structoffset-as-yaml/SKILL.md and read by ahel’s review.

Persist a single struct member offset analysis result to a YAML file beside the binary using IDA Pro MCP.

Prerequisites

Before using this skill, you should have:

  1. Identified the struct name and member name
  2. Determined the member offset (and optionally size)
  3. Generated a unique signature using /generate-signature-for-structoffset

Required Parameters

ParameterDescriptionExample
struct_nameName of the struct/classCBaseEntity
member_nameName of the struct memberm_skeletonInstance
offsetHex offset of the member from struct start0x278

Optional Parameters

ParameterDescriptionExample
sizeSize of the member in bytes (use None to omit)8
offset_sigUnique byte signature locating an instruction that contains the offset (use None to omit)8B 93 E0 04 00 00
offset_sig_dispByte displacement from signature start to the target instruction. 0 or None means signature starts at the target instruction. Non-zero means backward expansion was used by /generate-signature-for-structoffset. (use None to omit)8

Method

mcp__ida-pro-mcp__py_eval code="""
import idaapi
import os
import yaml

# === REQUIRED: Replace these values ===
struct_name = "<struct_name>"           # e.g., "CBaseEntity"
member_name = "<member_name>"           # e.g., "m_skeletonInstance"
offset = <offset>                       # e.g., 0x278
# ======================================

# === OPTIONAL: Set to None to omit from output ===
size = <size>                           # e.g., 8 or None
offset_sig = <offset_sig>              # e.g., "8B 93 E0 04 00 00" or None
offset_sig_disp = <offset_sig_disp>    # e.g., 8 or None (0 also omitted)
# =================================================

# Get binary path and determine platform
input_file = idaapi.get_input_file_path()
dir_path = os.environ.get('CS2VIBE_ARTIFACT_DIR') or os.path.dirname(input_file)

if input_file.endswith('.dll'):
    platform = 'windows'
else:
    platform = 'linux'

# Build data dictionary conditionally
data = {}

data['struct_name'] = struct_name
data['member_name'] = member_name
data['offset'] = hex(offset)

if size is not None and size > 0:
    data['size'] = size

if offset_sig is not None:
    data['offset_sig'] = offset_sig

if offset_sig_disp is not None and offset_sig_disp > 0:
    data['offset_sig_disp'] = offset_sig_disp

yaml_path = os.path.join(dir_path, f"{struct_name}_{member_name}.{platform}.yaml")
with open(yaml_path, 'w', encoding='utf-8') as f:
    yaml.dump(data, f, default_flow_style=False, sort_keys=False, allow_unicode=True)
print(f"Written to: {yaml_path}")
"""

Output File Naming Convention

The output YAML filename follows this pattern:

  • <struct_name>_<member_name>.<platform>.yaml

Examples:

  • server.dllCBaseEntity_m_skeletonInstance.windows.yaml
  • libserver.so / libserver.soCBaseEntity_m_skeletonInstance.linux.yaml

Output YAML Format

Full output (with size, offset_sig, and offset_sig_disp provided):

struct_name: CBaseEntity
member_name: m_skeletonInstance
offset: 0x278
size: 8
offset_sig: FF 50 ?? 48 85 C0 74 ?? 48 8B 80 A0 03 00 00 48 83 C4 28 C3
offset_sig_disp: 8

Output without backward expansion (offset_sig_disp is 0 or omitted):

struct_name: CBaseEntity
member_name: m_skeletonInstance
offset: 0x278
size: 8
offset_sig: 8B 93 78 02 00 00

Minimal output (with size=None, offset_sig=None):

struct_name: CBaseEntity
member_name: m_skeletonInstance
offset: 0x278

Each field:

  • struct_name - Name of the struct/class
  • member_name - Name of the struct member
  • offset - Hex offset from struct start
  • size (optional) - Size in bytes
  • offset_sig (optional) - Unique byte signature of an instruction containing the offset (e.g., 8B 93 E0 04 00 00 for mov edx, [rbx+4E0h])
  • offset_sig_disp (optional) - Byte displacement from signature start to the target instruction. Only present when non-zero (backward expansion was used). Runtime: scan for offset_sig, then add offset_sig_disp to get the target instruction address.

Platform Detection

The skill automatically detects the platform based on file extension:

  • .dll → Windows
  • .so → Linux

Example Usage

With all parameters

struct_name = "CBaseEntity"
member_name = "m_skeletonInstance"
offset = 0x278
size = 8
offset_sig = "8B 93 78 02 00 00"
offset_sig_disp = None

With backward-expanded signature

struct_name = "CSkeletonInstance"
member_name = "m_animationController"
offset = 0x3A0
size = 8
offset_sig = "FF 50 40 48 85 C0 74 0C 48 8B 80 A0 03 00 00 48 83 C4 28 C3"
offset_sig_disp = 8

Without optional parameters

struct_name = "CBaseEntity"
member_name = "m_skeletonInstance"
offset = 0x278
size = None
offset_sig = None
offset_sig_disp = None

With only size

struct_name = "CBaseEntity"
member_name = "m_iHealth"
offset = 0x408
size = 4
offset_sig = None

With only signature

struct_name = "CBaseEntity"
member_name = "m_nActualMoveType"
offset = 0x4E0
size = None
offset_sig = "8B 93 E0 04 00 00"

Trusted finalization

This writer produces a semantic YAML payload at the caller-provided expected artifact path. It does not own final field ordering, scalar spelling, encoding, or line endings. After runtime validation, the trusted analyzer rewrites every successful preprocessor or Agent output through the Source2 central canonicalizer; that canonical rewrite is the only byte-level trust boundary.

Notes

  • All offsets are written in hexadecimal format with lowercase 0x prefix
  • The YAML file is written to the same directory as the input binary
  • When size is None or 0, the size field is omitted from the output entirely
  • When offset_sig is None, the offset_sig field is omitted from the output entirely
  • When offset_sig_disp is None or 0, the offset_sig_disp field is omitted from the output entirely (signature starts at the target instruction)
  • offset_sig should be a signature generated by /generate-signature-for-structoffset
  • offset_sig_disp is the byte displacement from signature start to the target instruction, only needed when backward expansion was used

Signals

GitHub stars
65
Forks
10
Last commit
Sep 2026
Advanced
Catalog kind
skill
Gateway key
write-structoffset-as-yaml
Source
github.com/hlnd2t/cs2_vibesignatures