Skip to content
Back to skills

003 Name Skill Ab13ecd5

ASecurity

Find and identify the CBasePlayerPawn_CommitSuicide function in CS2 binary using IDA Pro MCP. Use this skill when reverse engineering CS2 server.dll or server.so to locate the CommitSuicide function by searching for the "bot_kill" command string, tracing to its handler, and identifying the CommitSuicide vfunc call in the kill loop.

  • 9 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added June 1, 2026
toolsapi

Works with

  • api
  • mcp

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned June 1, 2026

npx -y skills add tools-only/X-Skills --skill 003-name-skill_ab13ecd5 --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of 003 Name Skill Ab13ecd5?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for 003 Name Skill Ab13ecd5
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/tools-only-003-name-skill-ab13ecd5/badge)](https://www.skillsdirectory.com/skills/tools-only-003-name-skill-ab13ecd5)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: find-CBasePlayerPawn_CommitSuicide
description: Find and identify the CBasePlayerPawn_CommitSuicide function in CS2 binary using IDA Pro MCP. Use this skill when reverse engineering CS2 server.dll or server.so to locate the CommitSuicide function by searching for the "bot_kill" command string, tracing to its handler, and identifying the CommitSuicide vfunc call in the kill loop.
---

# Find CBasePlayerPawn_CommitSuicide

Locate `CBasePlayerPawn_CommitSuicide` in CS2 server.dll or server.so using IDA Pro MCP tools.

## Method

1. Search for the `bot_kill` command string:

   ```
   mcp__ida-pro-mcp__find_regex pattern="bot_kill.*all"
   ```

   This should find a string like:
   `"bot_kill <all> <t|ct> <type> <difficulty> <name> - Kills a specific bot, or all bots, matching the given criteria."`

2. Find cross-references to the string:

   ```
   mcp__ida-pro-mcp__xrefs_to addrs="<string_addr>"
   ```

   This leads to a ConCommand registration function. Decompile it to find the command handler (callback) address — the first argument stored before the description string in the registration call.

3. Decompile the `bot_kill` command handler and locate the kill loop:

   ```
   mcp__ida-pro-mcp__decompile addr="<handler_addr>"
   ```

   Look for a loop pattern like this:

   ```c
   do
   {
     v24 = *(_QWORD *)v23;
     if ( (*(unsigned __int8 (__fastcall **)(_QWORD))(**(_QWORD **)(*(_QWORD *)v23 + 24LL) + <IsAlive_offset>))(*(_QWORD *)(*(_QWORD *)v23 + 24LL)) )
     {
       (*(void (__fastcall **)(_QWORD, _QWORD, _QWORD))(**(_QWORD **)(v24 + 24) + <CommitSuicide_offset>))(
         *(_QWORD *)(v24 + 24),
         0LL,
         0LL);
       if ( !v5 )
         break;
     }
     ++v21;
     v23 += 8;
   }
   while ( v21 < v20 );
   ```

   The loop iterates over matched bots. For each bot:
   - `*(v24 + 24)` dereferences the PlayerPawn pointer
   - The first vfunc call (with `<IsAlive_offset>`) checks if the pawn is alive
   - The second vfunc call (with `<CommitSuicide_offset>`) calls `pPlayerPawn->CommitSuicide(false, false)`
   - If not in "all" mode (`!v5`), it breaks after the first kill

   Extract `<CommitSuicide_offset>` from the decompiled code (e.g., `3200LL` = `0xC80`).

4. Get CBasePlayerPawn vtable information:

   **ALWAYS** Use SKILL `/get-vtable-from-yaml` with `class_name=CBasePlayerPawn`.

   Extract `vtable_va`, `vtable_numvfunc` and `vtable_entries` from the result.

5. Map the vfunc offset to a vtable index and resolve the function address:

   ```
   vfunc_index = <CommitSuicide_offset> / 8
   ```

   Look up `vtable_entries[vfunc_index]` to get the function address.

6. Verify function characteristics to confirm `CBasePlayerPawn::CommitSuicide`:

   Decompile the resolved function address. The function should match:

   Windows:
   ```c
   char __fastcall CBasePlayerPawn_CommitSuicide(float *a1, unsigned __int8 a2, char a3)
   {
      __int64 v4; // rbp
      char result; // al
      _BYTE v7[112]; // [rsp+40h] [rbp-138h] BYREF
      __int64 v8; // [rsp+B0h] [rbp-C8h]
      int v9; // [rsp+180h] [rbp+8h] BYREF
      char v10; // [rsp+198h] [rbp+20h] BYREF

      v4 = a2;
      result = (*(__int64 (__fastcall **)(float *))(*(_QWORD *)a1 + 1336LL))(a1); // IsAlive check
      if ( result )
      {
         sub_XXX(&v9, *(_DWORD *)(*((_QWORD *)a1 + 2) + 56LL));
         result = sub_XXX(a1 + 824, (float *)&v9);
         if ( !result || a3 )
         {
            sub_XXX(&v9, *(_DWORD *)(*((_QWORD *)a1 + 2) + 56LL));
            a1[824] = *(float *)sub_XXX(&v10, &v9);
            sub_XXX((unsigned int)v7, (_DWORD)a1, (_DWORD)a1, 0, 1065353216, (_DWORD)v4 << 6, 0);
            v8 |= (32 * (v4 ^ 1) + 32) | 0x116;
            sub_XXX(a1, (__int64)v7, 0LL); // CBaseEntity::TakeDamageOld
            return sub_XXX((__int64)v7);
         }
      }
      return result;
   }
   ```

   Linux:
   ```c
   void __fastcall CBasePlayerPawn_CommitSuicide(__int64 a1, unsigned __int8 a2, char a3)
   {
      unsigned __int8 (*v4)(void); // rax
      _BYTE v5[112]; // [rsp+0h] [rbp-140h] BYREF
      __int64 v6; // [rsp+70h] [rbp-D0h]

      v4 = *(unsigned __int8 (**)(void))(*(_QWORD *)a1 + <IsAlive_offset>);
      if ( (char *)v4 == (char *)CBaseEntity_IsPlayerPawn )
      {
         if ( *(_BYTE *)(a1 + 1472) )
            return;
      }
      else if ( !v4() )
      {
         return;
      }
      if ( *(float *)(a1 + 4072) <= sub_XXX(...) || a3 )
      {
         *(float *)(a1 + 4072) = sub_XXX(...) + 5.0;
         sub_XXX(v5, a1, a1, 0LL, a2 << 6, 0LL, 1.0);
         v6 |= (a2 == 0 ? 64LL : 32LL) | 0x116;
         sub_XXX(a1, v5, 0LL); // CBaseEntity::TakeDamageOld
         sub_XXX(v5);
      }
   }
   ```

   Key verification points:
   - Calls `IsAlive` via vtable at the start
   - Constructs a `CTakeDamageInfo` on the stack (112-byte buffer)
   - Sets damage flags with `| 0x116`
   - Calls `CBaseEntity::TakeDamageOld` (verify by checking for string `"CBaseEntity::TakeDamageOld: damagetype %d with info.GetDamagePosition() == Vector::vZero\n"` in its callee)

   If the code pattern matches, proceed to rename.

7. Rename the function:

   ```
   mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<function_addr>", "name": "CBasePlayerPawn_CommitSuicide"}]}
   ```

8. Generate and validate unique signature:

   **ALWAYS** Use SKILL `/generate-signature-for-function` to generate a robust and unique signature for the function.

9. Write IDA analysis output as YAML beside the binary:

   **ALWAYS** Use SKILL `/write-vfunc-as-yaml` to write the analysis results.

   Required parameters:
   - `func_name`: `CBasePlayerPawn_CommitSuicide`
   - `func_addr`: The function address from step 5
   - `func_sig`: The validated signature from step 8

   VTable parameters:
   - `vtable_name`: `CBasePlayerPawn`
   - `vfunc_index`: The vtable index from step 5
   - `vfunc_offset`: `vfunc_offset = vfunc_index * 8`

## Function Characteristics

- **Parameters**: `(this, bool bExplodeDeath, bool bForce)` where `this` is CBasePlayerPawn pointer
- **Purpose**: Handles player suicide by constructing a CTakeDamageInfo and calling TakeDamageOld
- **Key Operations**:
  - Checks if pawn is alive via vtable call (IsAlive)
  - Checks cooldown timer to prevent rapid suicide calls
  - Constructs a 112-byte CTakeDamageInfo on the stack
  - Sets damage flags: `(32 * (bExplodeDeath ^ 1) + 32) | 0x116`
  - Calls `CBaseEntity::TakeDamageOld(this, info, 0)`
  - Destructs the CTakeDamageInfo

## VTable Information

- **VTable Name**: `CBasePlayerPawn::\`vftable'`
- **VTable Mangled Name**: `??_7CBasePlayerPawn@@6B@` (Windows) / `_ZTV16CBasePlayerPawn` (Linux)
- **VTable Index**: Changes with game updates. Resolve via `<CommitSuicide_offset> / 8`.
- **VTable Offset**: Changes with game updates. Extract from the `bot_kill` handler loop.

* Note that for `server.so`, the first 16 bytes of "vftable" are for RTTI. The real vftable = `_ZTV16CBasePlayerPawn` + `0x10`.

## String-Based Discovery

The primary discovery method uses the `bot_kill` console command:

1. **Search string**: `"bot_kill <all>"` or `"bot_kill.*all"`
2. **Xref chain**: String → ConCommand registration → command handler callback
3. **Kill loop**: The handler iterates matched bots, calling `pPlayerPawn->CommitSuicide(false, false)` via vtable

This is more robust than scanning vtable entries because:
- The `bot_kill` string is unique and stable across updates
- The kill loop structure is distinctive and unlikely to change
- The vfunc offset is extracted directly from the call site

## Output YAML Format

The output YAML filename depends on the platform:
- `server.dll` → `CBasePlayerPawn_CommitSuicide.windows.yaml`
- `server.so` → `CBasePlayerPawn_CommitSuicide.linux.yaml`

Files in this skill

  • README.md910 B
  • skill.md7.6 KB

Attribution

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

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.