Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Authors
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

ProTermsPrivacyRefunds
Back to skills

Find CBaseTrigger StartTouch AND CBaseTrigger EndTouch

ASecurity

Find and identify the CBaseTrigger::StartTouch and CBaseTrigger::EndTouch overridden virtual functions in the CS2 server binary using IDA Pro MCP. Use this skill when reverse engineering server.dll or libserver.so to locate the trigger-volume touch-list add/remove handlers by RTTI-walking CBaseTrigger's and CBaseEntity's primary vtables and diffing them slot-by-slot to find CBaseTrigger's overrides, then identifying which two overridden slots implement "add pOther to the touching-entities lis...

3 stars
0 votes
0 copies
0 views
Added 9/27/2026
tools

Works with

mcp

Security Analysis

A100/100

Scanned 9/27/2026

Install to Claude Code

$npx -y skills add mrc4tt/CS2_VibeSignatures --skill find-CBaseTrigger_StartTouch-AND-CBaseTrigger_EndTouch --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Find CBaseTrigger StartTouch AND CBaseTrigger EndTouch?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Find CBaseTrigger StartTouch AND CBaseTrigger EndTouch
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mrc4tt-find-cbasetrigger-starttouch-and-cbasetrigger-endt/badge)](https://www.skillsdirectory.com/skills/mrc4tt-find-cbasetrigger-starttouch-and-cbasetrigger-endt)

More formats (shields.io, HTML) on the badges page.

Download with Pro
Files
SKILL.md
---
name: find-CBaseTrigger_StartTouch-AND-CBaseTrigger_EndTouch
description: |
  Find and identify the CBaseTrigger::StartTouch and CBaseTrigger::EndTouch overridden virtual functions in the
  CS2 server binary using IDA Pro MCP. Use this skill when reverse engineering server.dll or libserver.so to
  locate the trigger-volume touch-list add/remove handlers by RTTI-walking CBaseTrigger's and CBaseEntity's
  primary vtables and diffing them slot-by-slot to find CBaseTrigger's overrides, then identifying which two
  overridden slots implement "add pOther to the touching-entities list" (StartTouch) versus "remove pOther from
  the touching-entities list" (EndTouch).
  Trigger: CBaseTrigger_StartTouch, CBaseTrigger_EndTouch
disable-model-invocation: true
---

# Find CBaseTrigger_StartTouch and CBaseTrigger_EndTouch

Locate `CBaseTrigger::StartTouch` and `CBaseTrigger::EndTouch` in CS2 `server.dll` / `libserver.so` using IDA
Pro MCP tools.

**Note**: unlike most sibling skills, there is no known reference signature to validate against for these two
symbols — they are discovered fresh via vtable-diffing plus body-shape confirmation.

## Method

### 1. Resolve CBaseTrigger's and CBaseEntity's Primary VTables

**ALWAYS** Use SKILL `/get-vtable-address` with `class_name=CBaseTrigger` and again with `class_name=CBaseEntity`
(RTTI walk: typeinfo name string `"12CBaseTrigger"` / `"11CBaseEntity"` → typeinfo → primary vtable, the
candidate whose `offset_to_top` qword is `0` and whose first few slots point into executable memory).

> Linux 14168 reference: `CBaseTrigger` primary vtable `0x2396298`, `CBaseEntity` primary vtable `0x23cc9b8`.

### 2. Diff the Two VTables Slot-by-Slot

`CBaseTrigger` derives (indirectly) from `CBaseEntity`, so under the Itanium ABI every virtual function keeps
the **same slot index** across the inheritance chain. Read both vtables' function-pointer qwords at
`vt + 0x10 + n*8` for a generous slot range (e.g. `n` in `0..500`) and collect every `n` where the two addresses
differ — those are exactly the slots `CBaseTrigger` overrides.

```text
mcp__ida-pro-mcp__idalib py_eval code="<loop reading both vtables, diffing qwords>"
```

> Linux 14168 reference: differing slots in range 0..500 were `[125, 127, 147, 149, 150, 156, 194, 197, 198]`
> (9 overrides total — `CBaseTrigger` overrides `Spawn`/`Activate`/touch handlers/damage-related methods, etc.).

### 3. Identify StartTouch and EndTouch Among the Overridden Slots

Decompile every differing slot's `CBaseTrigger`-side function and look for the touch-list add/remove shape.
`CBaseTrigger` maintains an internal growable array of currently-touching entities (count field + pointer field,
a `CUtlVector`-shaped pair a fixed struct-offset apart, e.g. count at `this+2952`/`this+2960` in the 14168
build). The two candidates you want:

- **StartTouch**: searches the array for `pOther`'s handle; if absent, **appends** it (grows the array, bumps
  the count), and — only when the count transitions `0 → 1` — fires an additional "first toucher" callback
  (guarded by a `!= nullsub_*` check against a vtable slot, e.g. `OnStartTouchAll`). Also fires the trigger's
  `m_OnStartTouch`/output-system calls via `sub_2132220`-shaped helpers.
- **EndTouch**: searches the array for `pOther`'s handle; if found, **removes** it (shifts the tail down, shrinks
  the count), then fires the trigger's `m_OnEndTouch`/output-system calls the same way.

Both take `(CBaseTrigger *this, CBaseEntity *pOther)`. Reject any other overridden slot that doesn't touch this
array (e.g. slots that are trivial `return 0;`/`return 1;` stubs, or large functions unrelated to a touch list —
those are unrelated overrides like `ShouldCollide`/network-group helpers picked up by the same slot range scan).

**Cross-check** (do this — strong independent confirmation): decompile the **un-overridden** `CBaseEntity`-side
function at each of these two slots. Both should have the same generic shape — a short "forward the call to
some related singleton object at the *same* vtable slot" stub — which is the expected base-class placeholder
behavior for virtuals that `CBaseTrigger` (and other touch-list-owning classes) meaningfully override, while
`CBaseEntity` itself doesn't maintain a touch list.

> Linux 14168 reference: `CBaseTrigger` overrides slot **147** with `0xd54900` (StartTouch — appends to the
> touch array at `this+2952`/`this+2960`, fires `this+2168`/`this+2176`-guarded callbacks and
> `sub_2132220(this+2784/2760/2928, ...)` output calls) and slot **149** with a thin wrapper `0xd24190`
> (`if (a2) return sub_D23E70();`) that tail-calls `sub_D23E70` — which **removes** `pOther` from the same
> touch array and fires the paired `m_OnEndTouch`-style outputs at `this+2808/2928/2832` — i.e. EndTouch. Both
> un-overridden `CBaseEntity` slots (`0xd1dfa0` for 147, `0xd1e090` for 149) share the identical
> "forward to `sub_16B0920()`'s object at the same vtable offset" placeholder shape, confirming these two slots
> are the touch-list virtuals and that `CBaseTrigger` is the class that gives them real bodies.

### 4. Generate a Fresh Function Signature

Since there is no reference signature for either symbol, generate and simply record what's found:

**ALWAYS** Use SKILL `/generate-signature-for-function` with `addr=<CBaseTrigger_StartTouch_addr>`.

**ALWAYS** Use SKILL `/generate-signature-for-function` with `addr=<CBaseTrigger_EndTouch_addr>`.

> Linux 14168 reference sigs actually generated (no ground truth to compare against — reported as-is):
> - `CBaseTrigger_StartTouch` (`0xd54900`): `55 48 89 E5 41 56 41 55 49 89 F5 41 54 53 48 89 FB 48 83 EC ? 48 8B 07 FF 90 ? ? ? ? 84 C0`
> - `CBaseTrigger_EndTouch` (`0xd24190`): `48 85 F6 74 ? E9 ? ? ? ? 66 0F 1F 44 00 ? C3 CC CC CC CC CC CC CC CC CC CC CC CC CC CC CC 48 8B 07`
>   — note `EndTouch`'s real body is only 0x11 bytes (`test rsi,rsi; jz; jmp sub_D23E70`), so the signature
>   generator had to grow past the function's own `int3` padding into the *next* function's first bytes
>   (`48 8B 07`) to reach uniqueness; this is expected/benign for such a tiny thin-wrapper function and does not
>   indicate a bad signature, but it does mean the sig's tail is technically borrowed from the following symbol.

### 5. Write IDA Analysis Output as YAML

**ALWAYS** Use SKILL `/write-vfunc-as-yaml` twice, once for each symbol:

- `func_name`: `CBaseTrigger_StartTouch`, `func_addr`: `<StartTouch_addr>`, `func_sig`: from step 4,
  `vtable_name`: `CBaseTrigger`, `vfunc_offset`: `0x498` (`147*8`), `vfunc_index`: `147`.
- `func_name`: `CBaseTrigger_EndTouch`, `func_addr`: `<EndTouch_addr>`, `func_sig`: from step 4,
  `vtable_name`: `CBaseTrigger`, `vfunc_offset`: `0x4A8` (`149*8`), `vfunc_index`: `149`.

## Function Characteristics

- **Purpose**: `StartTouch`/`EndTouch` maintain `CBaseTrigger`'s per-instance list of entities currently
  overlapping the trigger volume, and fire the corresponding `m_OnStartTouch`/`m_OnEndTouch` (and
  `...All` variants on first/last toucher) I/O outputs.
- **Binary**: `server.dll` / `libserver.so`
- **Parameters**: `(CBaseTrigger *this, CBaseEntity *pOther)`
- **Return value**: `void`
- **VTable**: `CBaseTrigger`, slots 147 (`StartTouch`) and 149 (`EndTouch`) on the Linux 14168 reference build —
  these slot indices are inherited unchanged from `CBaseEntity::StartTouch`/`EndTouch` (Itanium ABI keeps virtual
  slot indices stable across the inheritance chain), so re-deriving them via `/get-vtable-index` against
  whichever build you're on is safer than hardcoding `147`/`149`.

## Discovery Strategy

1. RTTI-walk both `CBaseTrigger`'s and `CBaseEntity`'s primary vtables — no string/xref anchor is needed for
   either class since Itanium typeinfo name strings (`"12CBaseTrigger"`, `"11CBaseEntity"`) are always present
   even in a stripped binary.
2. Diff the two vtables slot-by-slot; every differing slot is a genuine `CBaseTrigger` override, independent of
   any single function's absolute address.
3. Among the overrides, identify the touch-list add/remove pair by body shape (grows vs. shrinks the same
   internal array, fires the paired Start/End output-event helpers) rather than by hardcoding a slot number —
   this survives the touch-list's own internal struct-offset layout changing across builds, as long as the
   *shape* of "search array, mutate count, conditionally fire paired outputs" stays recognizable.
4. Cross-checking against `CBaseEntity`'s own (un-overridden) placeholder bodies at the same two slots is a
   free, independent sanity check that costs nothing extra since both vtables were already resolved in step 1.

## Output YAML Format

The output YAML filenames depend on the platform:
- `server.dll` -> `CBaseTrigger_StartTouch.windows.yaml`, `CBaseTrigger_EndTouch.windows.yaml`
- `libserver.so` -> `CBaseTrigger_StartTouch.linux.yaml`, `CBaseTrigger_EndTouch.linux.yaml`

Fields (both files): `func_name`, `func_va`, `func_rva`, `func_size`, `func_sig`, `vtable_name`, `vfunc_offset`,
`vfunc_index`.

Attribution

mrc4ttmrc4tt
View sourceMore from mrc4tt →
SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Know which skills are safe — weekly.

Best new skills + every skill we flagged as malicious. From the team that scanned 103,619.

Join free

Related Skills

ucoz-landing-skill

Playbook for creating and editing uCoz landing pages via MCP tools (`templates_tool`, `ftp_tool`, `modules_tool`). Use for tasks such as: "build a landing page", "update the homepage as a landing page", "create a promo page on the homepage", "add a lead form / menu / SEO to the homepage". Homepage: `page_list`, `page_get`; first publish — `page_update` with full `page_tmpl`; HTML edits after generation — `patch_template` (module_id=2, template_id=1), not `update_template`. Activate the mail f...

107 votes

Paperclip

Interact with the Paperclip control plane API for task coordination and governance. Use when checking assignments, updating issue status, posting comments, delegating work, managing routines, or calling Paperclip API endpoints.

813271 votes

Instantly Rdsthomas Mission Control

Instantly.ai cold email outreach API - manage campaigns, leads, accounts, and analytics. Use for cold email automation, lead management, campaign creation/monitoring, and email account warmup.

761 votes

Daw Music

Digital Audio Workstation usage, music composition, interactive music systems, and game audio implementation for immersive soundscapes.

761 votes

Caveman Compress

Compress natural language memory files (CLAUDE.md, todos, preferences) into caveman format to save input tokens. Preserves all technical substance, code, URLs, and structure. Compressed version overwrites the original file. Human-readable backup saved as FILE.original.md. Trigger: /caveman-compress FILEPATH or "compress memory file"

1074700 votes
View all in tools →