AgentStack
SKILL verified MIT Self-run

Get Vtable Address

skill-hlnd2t-cs2-vibesignatures-get-vtable-address · by HLND2T

|

No reviews yet
0 installs
6 views
0.0% view→install

Install

$ agentstack add skill-hlnd2t-cs2-vibesignatures-get-vtable-address

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

Are you the author of Get Vtable Address? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Get VTable address and size

Find a class's virtual function table by class name. Get its address and size in a single step.

Prerequisites

  • ClassName

Method

1. Get vtable address and size

Run this single Python script using mcp__ida-pro-mcp__py_eval, replacing ` with the actual class name (e.g., CGameRules, CCSPlayer_ItemServices`):

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

class_name = ""
ptr_size = 8 if idaapi.inf_is_64bit() else 4

vtable_start = None  # address of first vfunc pointer
vtable_symbol = ""
is_linux = False
method = ""

# ── Direct symbol lookup ──────────────────────────────────────────────
# Windows: ??_7ClassName@@6B@
win_name = f"??_7{class_name}@@6B@"
addr = ida_name.get_name_ea(idaapi.BADADDR, win_name)
if addr != idaapi.BADADDR:
    vtable_start = addr
    vtable_symbol = win_name
    is_linux = False
    method = "direct"

# Linux: _ZTVClassName  (e.g. _ZTV10CGameRules)
if vtable_start is None:
    linux_name = f"_ZTV{len(class_name)}{class_name}"
    addr = ida_name.get_name_ea(idaapi.BADADDR, linux_name)
    if addr != idaapi.BADADDR:
        vtable_start = addr + 0x10  # skip offset-to-top + typeinfo ptr
        vtable_symbol = f"{linux_name} + 0x10"
        is_linux = True
        method = "direct"

# ── RTTI / TypeInfo fallback ──────────────────────────────────────────
# Windows: ??_R4ClassName@@6B@ (Complete Object Locator)
if vtable_start is None:
    col_name = f"??_R4{class_name}@@6B@"
    col_addr = ida_name.get_name_ea(idaapi.BADADDR, col_name)
    if col_addr != idaapi.BADADDR:
        is_linux = False
        rdata_seg = ida_segment.get_segm_by_name(".rdata")
        for ref in idautils.DataRefsTo(col_addr):
            if rdata_seg and not (rdata_seg.start_ea ClassName (typeinfo)
if vtable_start is None:
    ti_name = f"_ZTI{len(class_name)}{class_name}"
    ti_addr = ida_name.get_name_ea(idaapi.BADADDR, ti_name)
    if ti_addr != idaapi.BADADDR:
        is_linux = True
        for ref in idautils.DataRefsTo(ti_addr):
            ott = ida_bytes.get_qword(ref - ptr_size) if ptr_size == 8 else ida_bytes.get_dword(ref - ptr_size)
            if ott == 0:
                vtable_start = ref + ptr_size
                ztv_addr = ref - ptr_size
                ztv_name = ida_name.get_name(ztv_addr) or f"_ZTV{len(class_name)}{class_name}"
                vtable_symbol = f"{ztv_name} + 0x10"
                method = "rtti_fallback"
                break

assert vtable_start is not None, f"Cannot find vtable for {class_name}"

# ── Count virtual functions ───────────────────────────────────────────
count = 0
for i in range(1000):
    ea = vtable_start + i * ptr_size

    # Linux: stop at next vtable / typeinfo symbol boundary
    if is_linux and i > 0:
        name = ida_name.get_name(ea)
        if name and (name.startswith("_ZTV") or name.startswith("_ZTI")):
            break

    ptr_value = ida_bytes.get_qword(ea) if ptr_size == 8 else ida_bytes.get_dword(ea)

    if ptr_value == 0:
        if is_linux:
            count += 1        # NULL = pure virtual placeholder
            continue
        else:
            break              # Windows: NULL = vtable end

    if ptr_value == 0xFFFFFFFFFFFFFFFF:
        break

    func = idaapi.get_func(ptr_value)
    if func is not None:
        count += 1
        continue

    flags = ida_bytes.get_full_flags(ptr_value)
    if ida_bytes.is_code(flags):
        count += 1
        continue

    break  # not a valid function pointer

size_in_bytes = count * ptr_size

print(f"vtable_class: {class_name}")
print(f"vtable_symbol: {vtable_symbol}")
print(f"vtable_va: {hex(vtable_start)}")
print(f"vtable_size: {hex(size_in_bytes)}")
print(f"vtable_numvfuncs: {count}")
print(f"method: {method}")
"""

Lookup order:

  1. Direct symbol: ??_7ClassName@@6B@ (Win) / _ZTVClassName (Linux)
  2. RTTI fallback: ??_R4ClassName@@6B@ → DataRefsTo → vtable (Win) / _ZTIClassName → DataRefsTo with offset-to-top==0 → vtable (Linux)

Platform-specific vfunc counting:

  • Linux (_ZTV prefix): NULL entries = pure virtual placeholders (keep counting); stops at next _ZTV/_ZTI symbol
  • Windows (??_7 prefix): NULL = vtable end; stops immediately

2. 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

The skill returns:

  • vtable_class: The class name
  • vtable_symbol: The IDA symbol. e.g. ??_7CGameRules@@6B@ or _ZTV10CGameRules + 0x10
  • vtable_va: The start address of the vtable (first vfunc pointer)
  • vtable_size: Total size of the vtable in bytes
  • vtable_numvfuncs: Count of virtual function entries in the vtable
  • method: How the vtable was found (direct or rtti_fallback)

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.