Find Host_Say, UTIL_SayTextFilter and UTIL_SayTextFilter2
Locate Host_Say, UTIL_SayTextFilter and UTIL_SayTextFilter2 in CS2 server.dll or server.so using IDA Pro MCP tools.
Method
Search for the string:
mcp__ida-pro-mcp__find_regex pattern="%s %s @ %s:"
Get cross-references to the string:
mcp__ida-pro-mcp__xrefs_to addrs="<string_addr>"
Decompile and rename the referencing function:
mcp__ida-pro-mcp__decompile addr="<function_addr>"
- The decompiled function is
Host_Say, and it needs to be renamed.
mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<function_addr>", "name": "Host_Say"}]}
In the decompiled code, look for the characteristic if-else pattern:
if ( v61 )
{
v15 = 0LL;
LOBYTE(v44) = 1;
sub_XXXXXXX((unsigned int)v63, (_DWORD)a1, v44, v61, (__int64)v60, (__int64)v12, (__int64)v62, 0LL); // <-- UTIL_SayTextFilter2
}
else
{
LOBYTE(v45) = 1;
sub_XXXXXXX(v63, v69, a1, v45); // UTIL_SayTextFilter
v15 = 0LL;
}
Or on Windows:
if ( v59 )
{
sub_XXXXXXX((__int64)&v61, (__int64)v8, 1, v59, v19, v12, v60, 0i64); // <-- UTIL_SayTextFilter2
}
else
{
LOBYTE(v42) = 1;
sub_XXXXXXX(&v61, v73, v8, v42);// UTIL_SayTextFilter
}
Identify UTIL_SayTextFilter and UTIL_SayTextFilter2:
UTIL_SayTextFilter2 is called in the if branch (when v59/v61 is non-null/true)
- It takes 8 parameters: (filter, player, chat_flag, extra_param, text1, text2, text3, zero)
- the one in else branch is
UTIL_SayTextFilter
Rename them:
mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<util_saytextfilter_addr>", "name": "UTIL_SayTextFilter"}]}
mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<util_saytextfilter2_addr>", "name": "UTIL_SayTextFilter2"}]}
Generate and validate unique signature for Host_Say:
ALWAYS Use SKILL /generate-signature-for-function to generate a robust and unique signature for the function.
Write IDA analysis output for Host_Say as YAML beside the binary:
ALWAYS Use SKILL /write-func-as-yaml to write the analysis results.
Required parameters:
func_name: Host_Say
func_addr: The function address of Host_Say from step 3
func_sig: The validated signature from step 7
Note: This is NOT a virtual function, so no vtable parameters are needed.
Generate and validate unique signature for UTIL_SayTextFilter:
ALWAYS Use SKILL /generate-signature-for-function to generate a robust and unique signature for the function.
Write IDA analysis output for UTIL_SayTextFilter as YAML beside the binary:
ALWAYS Use SKILL /write-func-as-yaml to write the analysis results.
Required parameters:
func_name: UTIL_SayTextFilter
func_addr: The function address of UTIL_SayTextFilter from step 5
func_sig: The validated signature from step 9
Note: This is NOT a virtual function, so no vtable parameters are needed.
- Generate and validate unique signature for
UTIL_SayTextFilter2:
ALWAYS Use SKILL /generate-signature-for-function to generate a robust and unique signature for the function.
- Write IDA analysis output for
UTIL_SayTextFilter2 as YAML beside the binary:
ALWAYS Use SKILL /write-func-as-yaml to write the analysis results.
Required parameters:
func_name: UTIL_SayTextFilter2
func_addr: The function address of UTIL_SayTextFilter2 from step 5
func_sig: The validated signature from step 11
Note: This is NOT a virtual function, so no vtable parameters are needed.
Function Characteristics
Prototype: void Host_Say(CBasePlayerController *pController, CCommand &args, bool teamonly, int unk1, const char *unk2)
Parameters:
pController: Player controller sending the message (can be null for console)
args: Command arguments containing the message
teamonly: True for team chat, false for all chat
unk1: Unknown parameter
unk2: Unknown parameter (alternative command name)
Prototype: void UTIL_SayTextFilter(IRecipientFilter* filter, const char* pText, CBasePlayerController* pPlayer, bool chat)
Parameters:
filter: Recipient filter for message targets
pText: The text message to send
pPlayer: The player controller sending the message
chat: Boolean flag indicating if this is a chat message
Prototype: void UTIL_SayTextFilter2(IRecipientFilter* filter, CBasePlayerController* pPlayer, bool chat, const char* param, const char* text1, const char* text2, const char* text3, void* reserved)
Parameters:
filter: Recipient filter for message targets
pPlayer: The player controller sending the message
chat: Boolean flag indicating if this is a chat message
param: Additional parameter string
text1: First text parameter
text2: Second text parameter
text3: Third text parameter
reserved: Reserved parameter (usually 0/null)
DLL Information
- DLL:
server.dll (Windows) / server.so (Linux)
Notes
- Those are regular functions, NOT virtual functions
UTIL_SayTextFilter2 is the extended version of UTIL_SayTextFilter with more parameters
Output YAML Format
The output YAML filename depends on the platform:
server.dll -> UTIL_SayTextFilter.windows.yaml, UTIL_SayTextFilter2.windows.yaml
server.so -> UTIL_SayTextFilter.linux.yaml, UTIL_SayTextFilter2.linux.yaml
func_va: 0x180XXXXXX # Virtual address of the function - This can change when game updates.
func_rva: 0xXXXXXX # Relative virtual address (VA - image base) - This can change when game updates.
func_size: 0xXXX # Function size in bytes - This can change when game updates.
func_sig: XX XX XX XX XX # Unique byte signature for pattern scanning - This can change when game updates.
1---2name: find-host-say-and-util-saytextfilter-and-util-saytextfilter23description: Find and identify the Host_Say, UTIL_SayTextFilter and UTIL_SayTextFilter2 in CS2 binary using IDA Pro MCP. Use this skill when reverse engineering CS2 server.dll or server.so to locate the Host_Say, UTIL_SayTextFilter and UTIL_SayTextFilter2 function by searching for the "%s %s @ %s:" string reference and analyzing cross-references.4---5
6# Find Host_Say, UTIL_SayTextFilter and UTIL_SayTextFilter2
7
8Locate `Host_Say`, `UTIL_SayTextFilter` and `UTIL_SayTextFilter2` in CS2 `server.dll` or `server.so` using IDA Pro MCP tools.
9
10## Method
11
121. Search for the string:
13 ```
14 mcp__ida-pro-mcp__find_regex pattern="%s %s @ %s:"
15 ```
16
172. Get cross-references to the string:
18 ```
19 mcp__ida-pro-mcp__xrefs_to addrs="<string_addr>"
20 ```
21
223. Decompile and rename the referencing function:
23 ```
24 mcp__ida-pro-mcp__decompile addr="<function_addr>"
25 ```
26
27 * The decompiled function is `Host_Say`, and it needs to be renamed.
28
29 ```
30 mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<function_addr>", "name": "Host_Say"}]}
31 ```
32
33 - Key Behaviors of Host_Say:
34
35 1. Parses "say" or "say_team" commands
36 2. Validates and sanitizes chat message
37 3. Truncates message if too long (Unicode-aware)
38 4. Broadcasts message to appropriate recipients (all or team)
39 5. Logs chat to console with format `[All Chat][PlayerName (userid)]: message`
40 6. Handles console-originated messages specially
41
42
434. In the decompiled code, look for the characteristic if-else pattern:
44 ```c
45 if ( v61 )
46 {
47 v15 = 0LL;
48 LOBYTE(v44) = 1;
49 sub_XXXXXXX((unsigned int)v63, (_DWORD)a1, v44, v61, (__int64)v60, (__int64)v12, (__int64)v62, 0LL); // <-- UTIL_SayTextFilter2
50 }
51 else
52 {
53 LOBYTE(v45) = 1;
54 sub_XXXXXXX(v63, v69, a1, v45); // UTIL_SayTextFilter
55 v15 = 0LL;
56 }
57 ```
58
59 Or on Windows:
60 ```c
61 if ( v59 )
62 {
63 sub_XXXXXXX((__int64)&v61, (__int64)v8, 1, v59, v19, v12, v60, 0i64); // <-- UTIL_SayTextFilter2
64 }
65 else
66 {
67 LOBYTE(v42) = 1;
68 sub_XXXXXXX(&v61, v73, v8, v42);// UTIL_SayTextFilter
69 }
70 ```
71
725. Identify UTIL_SayTextFilter and UTIL_SayTextFilter2:
73 - `UTIL_SayTextFilter2` is called in the `if` branch (when v59/v61 is non-null/true)
74 - It takes 8 parameters: (filter, player, chat_flag, extra_param, text1, text2, text3, zero)
75 - the one in else branch is `UTIL_SayTextFilter`
76
776. Rename them:
78
79 ```
80 mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<util_saytextfilter_addr>", "name": "UTIL_SayTextFilter"}]}
81 ```
82
83 ```
84 mcp__ida-pro-mcp__rename batch={"func": [{"addr": "<util_saytextfilter2_addr>", "name": "UTIL_SayTextFilter2"}]}
85 ```
86
877. Generate and validate unique signature for `Host_Say`:
88
89 **ALWAYS** Use SKILL `/generate-signature-for-function` to generate a robust and unique signature for the function.
90
918. Write IDA analysis output for `Host_Say` as YAML beside the binary:
92
93 **ALWAYS** Use SKILL `/write-func-as-yaml` to write the analysis results.
94
95 Required parameters:
96 - `func_name`: `Host_Say`
97 - `func_addr`: The function address of `Host_Say` from step 3
98 - `func_sig`: The validated signature from step 7
99
100 Note: This is NOT a virtual function, so no vtable parameters are needed.
101
1029. Generate and validate unique signature for `UTIL_SayTextFilter`:
103
104 **ALWAYS** Use SKILL `/generate-signature-for-function` to generate a robust and unique signature for the function.
105
10610. Write IDA analysis output for `UTIL_SayTextFilter` as YAML beside the binary:
107
108 **ALWAYS** Use SKILL `/write-func-as-yaml` to write the analysis results.
109
110 Required parameters:
111 - `func_name`: `UTIL_SayTextFilter`
112 - `func_addr`: The function address of `UTIL_SayTextFilter` from step 5
113 - `func_sig`: The validated signature from step 9
114
115 Note: This is NOT a virtual function, so no vtable parameters are needed.
116
11711. Generate and validate unique signature for `UTIL_SayTextFilter2`:
118
119 **ALWAYS** Use SKILL `/generate-signature-for-function` to generate a robust and unique signature for the function.
120
12112. Write IDA analysis output for `UTIL_SayTextFilter2` as YAML beside the binary:
122
123 **ALWAYS** Use SKILL `/write-func-as-yaml` to write the analysis results.
124
125 Required parameters:
126 - `func_name`: `UTIL_SayTextFilter2`
127 - `func_addr`: The function address of `UTIL_SayTextFilter2` from step 5
128 - `func_sig`: The validated signature from step 11
129
130 Note: This is NOT a virtual function, so no vtable parameters are needed.
131
132## Function Characteristics
133
134- **Prototype**: `void Host_Say(CBasePlayerController *pController, CCommand &args, bool teamonly, int unk1, const char *unk2)`
135- **Parameters**:
136 - `pController`: Player controller sending the message (can be null for console)
137 - `args`: Command arguments containing the message
138 - `teamonly`: True for team chat, false for all chat
139 - `unk1`: Unknown parameter
140 - `unk2`: Unknown parameter (alternative command name)
141
142- **Prototype**: `void UTIL_SayTextFilter(IRecipientFilter* filter, const char* pText, CBasePlayerController* pPlayer, bool chat)`
143- **Parameters**:
144 - `filter`: Recipient filter for message targets
145 - `pText`: The text message to send
146 - `pPlayer`: The player controller sending the message
147 - `chat`: Boolean flag indicating if this is a chat message
148
149- **Prototype**: `void UTIL_SayTextFilter2(IRecipientFilter* filter, CBasePlayerController* pPlayer, bool chat, const char* param, const char* text1, const char* text2, const char* text3, void* reserved)`
150- **Parameters**:
151 - `filter`: Recipient filter for message targets
152 - `pPlayer`: The player controller sending the message
153 - `chat`: Boolean flag indicating if this is a chat message
154 - `param`: Additional parameter string
155 - `text1`: First text parameter
156 - `text2`: Second text parameter
157 - `text3`: Third text parameter
158 - `reserved`: Reserved parameter (usually 0/null)
159
160## DLL Information
161
162- **DLL**: `server.dll` (Windows) / `server.so` (Linux)
163
164## Notes
165
166- Those are regular functions, NOT virtual functions
167- `UTIL_SayTextFilter2` is the extended version of `UTIL_SayTextFilter` with more parameters
168
169## Output YAML Format
170
171The output YAML filename depends on the platform:
172- `server.dll` -> `UTIL_SayTextFilter.windows.yaml`, `UTIL_SayTextFilter2.windows.yaml`
173- `server.so` -> `UTIL_SayTextFilter.linux.yaml`, `UTIL_SayTextFilter2.linux.yaml`
174
175```yaml
176func_va: 0x180XXXXXX # Virtual address of the function - This can change when game updates.
177func_rva: 0xXXXXXX # Relative virtual address (VA - image base) - This can change when game updates.
178func_size: 0xXXX # Function size in bytes - This can change when game updates.
179func_sig: XX XX XX XX XX # Unique byte signature for pattern scanning - This can change when game updates.
180```