Find and identify CBaseTrigger_StartTouch and CBaseTrigger_EndTouch virtual functions in CS2 binary using IDA Pro MCP. Use this skill when reverse engineering CS2 server.dll or server.so to locate the CBaseTrigger touch handler functions by using vtable information and inherited vtable indices from CBaseEntity.
Scanned 5/31/2026
Install via CLI
openskills install tools-only/X-Skills---
name: find-CBaseTrigger_StartTouch-AND-CBaseTrigger_EndTouch
description: Find and identify CBaseTrigger_StartTouch and CBaseTrigger_EndTouch virtual functions in CS2 binary using IDA Pro MCP. Use this skill when reverse engineering CS2 server.dll or server.so to locate the CBaseTrigger touch handler functions by using vtable information and inherited vtable indices from CBaseEntity.
---
# Find CBaseTrigger_StartTouch and CBaseTrigger_EndTouch
Locate `CBaseTrigger_StartTouch` and `CBaseTrigger_EndTouch` virtual functions in CS2 `server.dll` or `server.so` using IDA Pro MCP tools.
## Prerequisites
Before using this skill, ensure the following YAML files exist beside the binary:
- `CBaseTrigger_vtable.{platform}.yaml` - Generated by `/find-CBaseTrigger_vtable` or `/write-vtable-as-yaml`
- `CBaseEntity_StartTouch.{platform}.yaml` - Contains vtable index for StartTouch
- `CBaseEntity_EndTouch.{platform}.yaml` - Contains vtable index for EndTouch
If any of these files are missing, run the corresponding skills first:
- `/find-CBaseTrigger_vtable` to generate CBaseTrigger vtable YAML
- `/find-CBaseEntity_StartTouch-AND-CBaseEntity_Touch-AND-CBaseEntity_EndTouch` to generate CBaseEntity touch function YAMLs
## Method
### 1. Load CBaseTrigger VTable Information
**ALWAYS** Use SKILL `/get-vtable-from-yaml` with `class_name=CBaseTrigger`.
If the skill returns an error, stop and report to user.
Otherwise, extract `vtable_va`, `vtable_numvfunc` and `vtable_entries` for subsequent steps.
### 2. Load CBaseEntity_StartTouch and CBaseEntity_EndTouch VTable Indices
Read the vtable indices from the existing YAML files:
```python
mcp__ida-pro-mcp__py_eval code="""
import idaapi
import os
input_file = idaapi.get_input_file_path()
dir_path = os.path.dirname(input_file)
platform = 'windows' if input_file.endswith('.dll') else 'linux'
# Read CBaseEntity_StartTouch
yaml_path1 = os.path.join(dir_path, f"CBaseEntity_StartTouch.{platform}.yaml")
print(f"=== CBaseEntity_StartTouch ===")
if os.path.exists(yaml_path1):
with open(yaml_path1, 'r', encoding='utf-8') as f:
print(f.read())
else:
print(f"ERROR: {yaml_path1} not found")
print("Please run /find-CBaseEntity_StartTouch-AND-CBaseEntity_Touch-AND-CBaseEntity_EndTouch first.")
print()
# Read CBaseEntity_EndTouch
yaml_path2 = os.path.join(dir_path, f"CBaseEntity_EndTouch.{platform}.yaml")
print(f"=== CBaseEntity_EndTouch ===")
if os.path.exists(yaml_path2):
with open(yaml_path2, 'r', encoding='utf-8') as f:
print(f.read())
else:
print(f"ERROR: {yaml_path2} not found")
print("Please run /find-CBaseEntity_StartTouch-AND-CBaseEntity_Touch-AND-CBaseEntity_EndTouch first.")
"""
```
Extract `vfunc_index` values:
- `StartTouch_index` from CBaseEntity_StartTouch YAML
- `EndTouch_index` from CBaseEntity_EndTouch YAML
### 3. Resolve CBaseTrigger Virtual Function Addresses from vtable_entries
Using the vtable entries from step 1 and indices from step 2:
- `CBaseTrigger_StartTouch` address = `vtable_entries[StartTouch_index]`
- `CBaseTrigger_EndTouch` address = `vtable_entries[EndTouch_index]`
### 4. Verify Functions (Optional)
Decompile the functions to verify they are the correct touch handlers:
```
mcp__ida-pro-mcp__decompile addr="<CBaseTrigger_StartTouch_addr>"
mcp__ida-pro-mcp__decompile addr="<CBaseTrigger_EndTouch_addr>"
```
Key characteristics:
- **CBaseTrigger_StartTouch**: Handles entity entering the trigger, adds entity to touch list, fires OnStartTouch output
- **CBaseTrigger_EndTouch**: Handles entity leaving the trigger, removes entity from touch list, fires OnEndTouch output
### 5. Rename Functions
```
mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<CBaseTrigger_StartTouch_addr>", "name": "CBaseTrigger_StartTouch"}]}
```
```
mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<CBaseTrigger_EndTouch_addr>", "name": "CBaseTrigger_EndTouch"}]}
```
### 6. Generate Signature for CBaseTrigger_StartTouch and CBaseTrigger_EndTouch
**ALWAYS** Use SKILL `/generate-signature-for-function` to generate a robust and unique signature for `CBaseTrigger_StartTouch` and `CBaseTrigger_EndTouch`.
### 7. Write CBaseTrigger_StartTouch as YAML
**ALWAYS** Use SKILL `/write-vfunc-as-yaml` to write the analysis results for `CBaseTrigger_StartTouch` and `CBaseTrigger_EndTouch`.
#### For `CBaseTrigger_StartTouch`:
Required parameters:
- `func_name`: `CBaseTrigger_StartTouch`
- `func_addr`: The function address from step 3
- `func_sig`: The validated signature from step 6
VTable parameters:
- `vtable_name`: `CBaseTrigger`
- `vfunc_offset`: `StartTouch_index * 8` (e.g., `0x498` for index 147)
- `vfunc_index`: `StartTouch_index` (e.g., `147`)
#### For `CBaseTrigger_EndTouch`:
Required parameters:
- `func_name`: `CBaseTrigger_EndTouch`
- `func_addr`: The function address from step 3
- `func_sig`: The validated signature from step 6
VTable parameters:
- `vtable_name`: `CBaseTrigger`
- `vfunc_offset`: `EndTouch_index * 8` (e.g., `0x4A8` for index 149)
- `vfunc_index`: `EndTouch_index` (e.g., `149`)
## Function Characteristics
### CBaseTrigger_StartTouch
- **Class**: `CBaseTrigger`
- **Inherited From**: `CBaseEntity::StartTouch`
- **Prototype**: `void CBaseTrigger::StartTouch(CBaseEntity* pOther)`
- **Parameters**:
- `this`: Pointer to the CBaseTrigger instance
- `pOther`: Pointer to the entity that started touching the trigger
- **Behavior**:
1. Checks if trigger is enabled (calls vtable function to verify)
2. Validates the touching entity
3. Adds entity handle to internal touch list
4. Fires OnStartTouch entity output
5. Calls PassesTriggerFilters to check if entity should activate trigger
### CBaseTrigger_EndTouch
- **Class**: `CBaseTrigger`
- **Inherited From**: `CBaseEntity::EndTouch`
- **Prototype**: `void CBaseTrigger::EndTouch(CBaseEntity* pOther)`
- **Parameters**:
- `this`: Pointer to the CBaseTrigger instance
- `pOther`: Pointer to the entity that stopped touching the trigger
- **Behavior**:
1. Validates the touching entity
2. Finds and removes entity handle from internal touch list
3. Fires OnEndTouch entity output
4. Cleans up stale entity handles from touch list
5. Fires OnEndTouchAll if no entities remain in touch list
## VTable Information
- **VTable Name**: `CBaseTrigger`
- **Parent Class**: `CBaseEntity` (touch functions are inherited virtual functions)
- **StartTouch VTable Index**: Same as `CBaseEntity::StartTouch` (typically 147, may change with updates)
- **EndTouch VTable Index**: Same as `CBaseEntity::EndTouch` (typically 149, may change with updates)
## DLL Information
- **DLL**: `server.dll` (Windows) / `server.so` (Linux)
## Output YAML Format
The output YAML filenames depend on the platform:
- `server.dll` → `CBaseTrigger_StartTouch.windows.yaml`, `CBaseTrigger_EndTouch.windows.yaml`
- `server.so` → `CBaseTrigger_StartTouch.linux.yaml`, `CBaseTrigger_EndTouch.linux.yaml`
## Notes
- These are virtual functions inherited from `CBaseEntity` and overridden in `CBaseTrigger`
- The vtable indices are the same as in `CBaseEntity` since they are inherited virtual functions
- The actual function implementations are different from `CBaseEntity` versions (trigger-specific behavior)
- Always verify the prerequisite YAML files exist before running this skill
No comments yet. Be the first to comment!