本文へ移動
cccskills
無料GitHub で公開

find-CAttributeList_SetOrAddAttributeValueByName

Find and identify the CAttributeList_SetOrAddAttributeValueByName function in CS2 server binary using IDA Pro MCP. Use this skill when reverse engineering CS2 server.dll or libserver.so to locate the econ attribute-list workhorse that sets an existing float attribute by name or appends a new one. Resolved via a durable caller anchor: the weapon paint-kit/wear/seed/kill-eater applier function, which is itself located by the literal econ keyvalue-system strings "set item texture prefab" / "set item texture wear" / "set item texture seed". This function backs weaponpaints-style plugins that programmatically set an econ item's paint kit / wear / seed / stickers. Trigger: CAttributeList_SetOrAddAttributeValueByName, SetOrAddAttributeValueByName

インストール方法を見る

含まれるファイル(1)

  • SKILL.md8.4 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

Find CAttributeList_SetOrAddAttributeValueByName

Locate CAttributeList_SetOrAddAttributeValueByName in CS2 server.dll or libserver.so using IDA Pro MCP tools.

This is a non-virtual, direct-call member function reached through a tiny this-adjustor thunk (no vtable entry of its own — emit a byte sig, not an offset).

Do not anchor the discovery recipe on the raw byte pattern below — bytes/wildcards shift release to release. Use it only to locate/confirm the function on the currently loaded binary, then generate a fresh signature at the end.

Method

1. Locate the durable anchor strings

CAttributeList_SetOrAddAttributeValueByName has no distinctive string of its own (it's a generic hash-lookup + set/append routine), but its caller is the weapon econ-attribute applier used by CS2's own give/equip-weapon code path, and that caller references several literal econ keyvalue strings:

mcp__ida-pro-mcp__find       type="string" targets=["set item texture prefab"]
mcp__ida-pro-mcp__xrefs_to   addrs="<string_va>"

"set item texture prefab" has exactly one code referencer. That containing function (call it the paint-kit applier) also references the sibling literals "set item texture wear", "set item texture seed", "kill eater score type", and "kill eater" — this combination is a very strong, semantically durable fingerprint for "the function that programmatically stamps paint-kit/wear/seed/kill-eater attributes onto a weapon econ item", independent of its address or body shape.

Linux 14168 reference: the string "set item texture prefab" is referenced only from sub_1A9A070 (VA 0x1a9a070, size 0x394).

2. Read off the call sites inside the paint-kit applier

mcp__ida-pro-mcp__decompile addr="<paint_kit_applier_func_va>"

Inside, look for (typically) five calls of the shape helper(pAttributeListView, "<attr-name-literal>", <float-or-int-value>):

helper(v12, "set item texture prefab", (float)*(int *)(a2 + 120));
helper(v12, "set item texture wear",   *(float *)(a2 + 132));
helper(v12, "set item texture seed",   (float)*(int *)(a2 + 136));
helper(v12, "kill eater score type",   *(float *)(a2 + 140));  // only when a flag bit is set
helper(v12, "kill eater",              *(float *)(a2 + 144));  // only when a flag bit is set

helper is not the target itself — on Linux it is a tiny 2-instruction this-adjustor thunk:

add rdi, 0x70      ; adjust `this` from CEconItemView-ish base to the embedded CAttributeList member
jmp  <real_target>

Follow the jmp — its destination is CAttributeList_SetOrAddAttributeValueByName.

Linux 14168 reference: helper is sub_1B598E0 (add rdi, 70h; jmp sub_1B59720), and the real target is sub_1B59720 (VA 0x1b59720, size 0x1b5).

3. Confirm the target function's shape

Decompile the jmp target and confirm it matches:

__int64 __fastcall SetOrAddAttributeValueByName(CAttributeList *this, const char *pszAttribName, float flValue)
{
  pAttribDef = LookupAttributeDefinitionBySymbol(pszAttribName); // via a global symbol table
  if (!pAttribDef) return 0;
  for (each existing CEconItemAttribute entry in this->m_Attributes)
    if (entry's attribute-definition-index matches pAttribDef's index)
    {
      if (entry.value != flValue) { OnAttributeChanged(...); entry.value = flValue; }
      return ...;
    }
  // not found: construct a new attribute pair and append it to this->m_Attributes
  ConstructAttribute(&tmp, pAttribDef->index, flValue);
  AppendAttribute(this, &tmp);
  return ...;
}

Identification rules:

  1. Takes (this, const char *pszAttribName, float flValue) — a name string plus a float value.
  2. First does a hash/symbol lookup of pszAttribName into a global attribute-definition table.
  3. Loops over the object's existing attribute array comparing each entry's definition pointer/index; on a match, conditionally fires a change callback and overwrites the value in place.
  4. If no existing entry matches, constructs a new (index, value) pair and appends it to the list, growing/reallocating via the engine's memory allocator (g_pMemAlloc) if needed.

4. Generate function signature

ALWAYS use SKILL /generate-signature-for-function with addr=<real_target_func_addr>. Emit IDA style verbatim (space hex, ? wildcards).

Reference sig (Linux 14168 build — sanity check only, regenerate per binary): 55 48 89 E5 41 57 41 56 49 89 FE 41 55 41 54 53 48 89 F3 48 83 EC ? F3 0F 11 85

(Last-resort fallback note: if no better anchor is available on some future binary, find_bytes with this reference pattern can locate the function directly one-shot — its prologue is distinctive enough on its own — but prefer the string/caller anchor above since it survives compiler/prologue changes better.)

5. Write func YAML

ALWAYS use SKILL /write-func-as-yaml:

  • func_name: CAttributeList_SetOrAddAttributeValueByName
  • func_addr: <real_target_func_addr>
  • func_sig: validated sig from step 4

Function Characteristics

  • Purpose: Part of CS2's econ "attribute list" system (CAttributeList / CEconItemAttributeDefinition- adjacent). Sets an existing attribute's value by its string name, or appends a new attribute entry if none exists yet. This is the workhorse used by any code that programmatically sets paint-kit/wear/seed/ kill-eater/etc attributes on an econ item's attribute list — including weaponpaints-style plugins.
  • Linkage: non-virtual, direct-call (no vtable entry); reached in practice through a this-adjustor thunk from CEconItemView-shaped callers.
  • Binary: server.dll / libserver.so
  • Parameters: (this /* CAttributeList* */, const char *pszAttribName, float flValue)
  • Return value: implementation-defined status/attribute pointer (callers largely ignore it besides truthiness checks)

Discovery Strategy

  1. The target itself has no unique string, so anchor on its caller's literal econ-keyvalue strings — "set item texture prefab" has exactly one code referencer in the whole module, and that referencer is semantically stable (it is CS2's own paint-kit/wear/seed/kill-eater weapon-attribute applier, a first-party gameplay routine unlikely to disappear across updates).
  2. From that caller, every call into the attribute-setter helper passes a literal attribute-name string as its second argument — a very strong, code-shape-independent fingerprint (helper(this, "<literal>", value), repeated for each of the five known econ attribute names).
  3. On Linux the immediate call target is a two-instruction this-adjustor thunk (add rdi, N; jmp real); simply follow the unconditional jump to reach the real function.
  4. Confirm via body shape (symbol/hash lookup of the name argument, existing-attribute scan-and-update, append-if-missing fallback) — this is independent of exact byte offsets and survives reordering/inlining changes across builds.
  5. Re-generate the byte signature fresh from the resolved function each time, rather than hard-coding one.

This is robust because the anchor strings are first-party gameplay literals (not debug-only strings that could be stripped in release builds), the caller's "distinctive literal string as 2nd argument" call shape is compiler-agnostic, and the final signature is always regenerated rather than pinned.

Output YAML Format

  • server.dll -> CAttributeList_SetOrAddAttributeValueByName.windows.yaml
  • libserver.so -> CAttributeList_SetOrAddAttributeValueByName.linux.yaml

Fields: func_name, func_va, func_rva, func_size, func_sig.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

Clean up the local workspace after a dev branch has been merged into main. Verifies the current dev branch is fully merged into origin/main, then switches to main, pulls the latest, deletes the local dev branch, and deletes the remote dev branch if it still exists. STOPS and warns the user if the current branch is not yet merged. Triggers: cleanup workspace, cleanup branch, delete merged branch, finish dev branch, post-merge cleanup

日本語の概要は準備中です。原文の説明を表示しています。

mrc4tt/CS2_VibeSignatures32026年10月13日 更新

Convert an existing find-XXXX SKILL.md into a preprocessor Python script, updating configs/<GAMEVER>.yaml and removing the old SKILL.md. Covers xref-string-based and LLM_DECOMPILE-based discovery patterns.

日本語の概要は準備中です。原文の説明を表示しています。

mrc4tt/CS2_VibeSignatures32026年10月13日 更新

Create an Agent SKILL.md fallback for an existing find-XXXX finder that relies on a fragile discovery foundation — above all LLM_DECOMPILE (patterns C/D/E), which matches the decompiled shape of a predecessor function against a stored reference and breaks when a symbol is inlined or de-inlined in a way the reference does not cover. The generated fallback coexists with the preprocessor and runs only when it returns failure, recovering every target robustly by decompiling the predecessor and following the inline/de-inline boundary with semantic anchors. Use when a finder broke on a game update, or you want to durably backstop one before it does. The recipe generalizes to any finder foundation. Triggers: create agent skill fallback, add SKILL.md fallback, robust fallback for finder, backstop LLM_DECOMPILE finder, final guarantee skill

日本語の概要は準備中です。原文の説明を表示しています。

mrc4tt/CS2_VibeSignatures32026年10月13日 更新

Create a new cpp_tests entry for validating a C++ interface vtable layout against binary reference YAMLs. Creates the .cpp test file in cpp_tests/ and appends a configs/<GAMEVER>.yaml entry under cpp_tests:. Use when a user asks to add vtable layout validation for a new hl2sdk_cs2 interface class.

日本語の概要は準備中です。原文の説明を表示しています。

mrc4tt/CS2_VibeSignatures32026年10月13日 更新

create-pr

無料

Create a GitHub pull request from staged task changes or an already-committed current branch. Deliver source/config/ reference changes together with their computed source-owned `bin_artifacts` closure. PR validation routing is owned by the default-branch trusted workflow; snapshots, gamedata, and manifests are Release-derived only.

日本語の概要は準備中です。原文の説明を表示しています。

mrc4tt/CS2_VibeSignatures32026年10月13日 更新

Create a new find-XXXX preprocessor Python script from scratch (no existing SKILL.md), add configs/<GAMEVER>.yaml skill and symbol entries. Covers xref-string-based and LLM_DECOMPILE-based discovery patterns. Use when a GitHub issue or user instruction specifies a new function to find.

日本語の概要は準備中です。原文の説明を表示しています。

mrc4tt/CS2_VibeSignatures32026年10月13日 更新

mrc4tt のスキルをすべて見る

このスキルの問題を報告する