$npx -y skills add HLND2T/CS2_VibeSignatures --skill find-CNetworkMessages_GetIsForServerFind and identify the CNetworkMessages_GetIsForServer virtual function in CS2 binary using IDA Pro MCP. Use this skill when reverse engineering CS2 networksystem.dll or libnetworksystem.so to locate the GetIsForServer vfunc by reusing the known CNetworkMessages_SetIsForServer slo
| 1 | # Find CNetworkMessages_GetIsForServer |
| 2 | |
| 3 | Locate `CNetworkMessages_GetIsForServer` vfunc in CS2 `networksystem.dll` or `libnetworksystem.so` using IDA Pro MCP tools. |
| 4 | |
| 5 | ## Method |
| 6 | |
| 7 | ### 1. Load CNetworkMessages_SetIsForServer from YAML |
| 8 | |
| 9 | **ALWAYS** Use SKILL `/get-func-from-yaml` with `func_name=CNetworkMessages_SetIsForServer`. |
| 10 | |
| 11 | If the skill returns an error, **STOP** and report to user. |
| 12 | |
| 13 | Otherwise, extract: |
| 14 | - `func_va` of `CNetworkMessages_SetIsForServer` |
| 15 | - `vfunc_index` |
| 16 | - `vfunc_offset` |
| 17 | |
| 18 | ### 2. Load CNetworkMessages VTable from YAML |
| 19 | |
| 20 | **ALWAYS** Use SKILL `/get-vtable-from-yaml` with `class_name=CNetworkMessages`. |
| 21 | |
| 22 | If the skill returns an error, **STOP** and report to user. |
| 23 | |
| 24 | Otherwise, extract: |
| 25 | - `vtable_numvfunc` |
| 26 | - `vtable_entries` |
| 27 | |
| 28 | ### 3. Resolve the Adjacent Getter Slot |
| 29 | |
| 30 | Compute the candidate slot for `CNetworkMessages_GetIsForServer`: |
| 31 | |
| 32 | - `target_vfunc_index = CNetworkMessages_SetIsForServer.vfunc_index + 1` |
| 33 | - `target_vfunc_offset = CNetworkMessages_SetIsForServer.vfunc_offset + 8` |
| 34 | |
| 35 | Validate that `target_vfunc_index < vtable_numvfunc`, then read: |
| 36 | |
| 37 | - `candidate_func_addr = CNetworkMessages_vtable[target_vfunc_index]` |
| 38 | |
| 39 | This adjacent-slot rule is required because `GetIsForServer` immediately follows `SetIsForServer` in the `CNetworkMessages` vtable for `networksystem.dll` / `libnetworksystem.so`. |
| 40 | |
| 41 | ### 4. Decompile the Setter and Getter Candidate |
| 42 | |
| 43 | Decompile both functions: |
| 44 | |
| 45 | ```text |
| 46 | mcp__ida-pro-mcp__decompile addr="<CNetworkMessages_SetIsForServer_func_va>" |
| 47 | mcp__ida-pro-mcp__decompile addr="<candidate_func_addr>" |
| 48 | ``` |
| 49 | |
| 50 | First, confirm `CNetworkMessages_SetIsForServer` is the simple byte setter pattern: |
| 51 | |
| 52 | ```c |
| 53 | void __fastcall CNetworkMessages_SetIsForServer(__int64 a1, char a2) |
| 54 | { |
| 55 | *(_BYTE *)(a1 + 1374) = a2; |
| 56 | } |
| 57 | ``` |
| 58 | |
| 59 | Windows assembly example: |
| 60 | |
| 61 | ```asm |
| 62 | mov [rcx+55Eh], dl |
| 63 | retn |
| 64 | ``` |
| 65 | |
| 66 | Then confirm the adjacent vtable entry is the matching byte getter using the **same member offset**: |
| 67 | |
| 68 | ```c |
| 69 | __int64 __fastcall sub_1800CB790(__int64 a1) |
| 70 | { |
| 71 | return *(unsigned __int8 *)(a1 + 1374); |
| 72 | } |
| 73 | ``` |
| 74 | |
| 75 | Windows assembly example: |
| 76 | |
| 77 | ```asm |
| 78 | movzx eax, byte ptr [rcx+55Eh] |
| 79 | retn |
| 80 | ``` |
| 81 | |
| 82 | The exact member offset may change across game updates. The identification rule is: |
| 83 | |
| 84 | 1. `SetIsForServer` writes one byte to `this + <member_offset>` |
| 85 | 2. `candidate_func_addr` is the next vtable entry (`index + 1`) |
| 86 | 3. The candidate reads and returns one unsigned byte from the **same** `this + <member_offset>` |
| 87 | |
| 88 | If all three conditions hold, the candidate is `CNetworkMessages_GetIsForServer`. |
| 89 | |
| 90 | ### 5. Generate Function Signature |
| 91 | |
| 92 | **ALWAYS** Use SKILL `/generate-signature-for-function` with `addr=<candidate_func_addr>` to generate a robust and unique `func_sig` for `CNetworkMessages_GetIsForServer`. |
| 93 | |
| 94 | Use the returned validated `func_sig` in the next step. |
| 95 | |
| 96 | ### 6. Write IDA Analysis Output as YAML |
| 97 | |
| 98 | **ALWAYS** Use SKILL `/write-vfunc-as-yaml` to write the analysis results. |
| 99 | |
| 100 | Required parameters: |
| 101 | - `func_name`: `CNetworkMessages_GetIsForServer` |
| 102 | - `func_addr`: `<candidate_func_addr>` |
| 103 | - `func_sig`: The validated signature from step 5 |
| 104 | - `vfunc_sig`: `None` |
| 105 | |
| 106 | VTable parameters: |
| 107 | - `vtable_name`: `CNetworkMessages` |
| 108 | - `vfunc_offset`: `<target_vfunc_offset>` in hex |
| 109 | - `vfunc_index`: `<target_vfunc_index>` |
| 110 | |
| 111 | ## Function Characteristics |
| 112 | |
| 113 | - **Purpose**: Returns whether the `CNetworkMessages` instance is configured for server-side behavior |
| 114 | - **Binary**: `networksystem.dll` / `libnetworksystem.so` |
| 115 | - **Parameters**: `(this)` only |
| 116 | - **Return value**: An unsigned byte / boolean flag loaded from the same member written by `CNetworkMessages_SetIsForServer` |
| 117 | |
| 118 | ## Discovery Strategy |
| 119 | |
| 120 | 1. Reuse the existing `CNetworkMessages_SetIsForServer` YAML to obtain the authoritative slot index |
| 121 | 2. Reuse the existing `CNetworkMessages_vtable` YAML to resolve the adjacent vtable entry |
| 122 | 3. Confirm the semantic pair: |
| 123 | - setter writes `this + <member_offset>` |
| 124 | - adjacent getter returns `this + <member_offset>` |
| 125 | 4. Generate a stable `func_sig` from the resolved getter body |
| 126 | |
| 127 | This is robust because: |
| 128 | - The vtable adjacency (`SetIsForServer` followed by `GetIsForServer`) is stable and explicit |
| 129 | - The setter/getter pair must touch the same byte member |
| 130 | - The final YAML stores both the resolved function signature and the precise vtable metadata |
| 131 | |
| 132 | ## Output YAML Format |
| 133 | |
| 134 | The output YAML filename depends on the platform: |
| 135 | - `networksystem.dll` -> `CNetworkMessages_GetIsForServer.windows.yaml` |
| 136 | - `libnetworksystem.so` -> `CNetworkMessages_GetIsForServer.linux.yaml` |