魔怔Bi,你来啦! HVH论坛-HVH参数-1337论坛CS2参数脚本资源配置

现在注册加入我们,获得各类教程(注入)。快将1337论坛分享给你的好朋友吧!

各种教程

注入、网络问题 - 解决办法

加入交流群 - 不禁广商

在符合法规的情况下,可以和谐交流。Q群706457565
  • Font Gradient Example
    请尝试点赞并回复后再下载附件!EXE文件发帖时附上查毒链接!
  • Font Gradient Example
    发布十份参数帖子的用户将会免费获得vip以及出参老师头衔

【教程】LUA & FFI - 实现PrintToChat

Ambr0se

1337bbs.com
管理成员
Makima小姐
知名HVH社区技术
插件开发
LV
0
 
注册
2025/01/17
消息
7
反馈评分
78
点数
13
勋章
3
CS2 - PrintToChat

我看B站FA脚本showcase 有的LUA作者用say指令打印hitlog
这个教程会讲讲怎么直接将字符串输出到Chat 而不是发送给所有人

* 阅读本文需要逆向基础 *
逆向教程: 1337bbs.com/threads/ida-cs-2-reversing-cs-2-cs-go-reversing-dll-so.186
😎 FA版本代码实现在最后(游戏更新后将失效)
📍 本文插图上传至Github 裸连可能无法加载

逆 向 教 程
我们在CS2 SDK中
进入{SDK}/game/client文件夹

63792ab4-168c-4dd9-b600-fe0c5da6c816


通过模糊搜索 找到了CBaseHudChat类中一个名为ChatPrintf的函数
dd729703-c764-4bac-bf9e-593f4fef8b92


我们现在理清思路
我们invoke这个函数的必要条件
就是需要获取到CBaseHudChat类的指针
我们注意到这个类中有个静态成员函数
static CBaseHudChat *GetHudChat( void );

但我们发现这个函数很难下手(因为他只返回了一个变量 且是静态函数 基本没有切入点)
7afb9f67-b6f7-4dcd-946b-dbaa8752e728


我们直接搜索 CBaseHudChat *
看看有没有别的办法能获取到 CBaseHudChat 类的指针
发现这里有个很有意思的东西GET_HUDELEMENT

ed768a79-f379-415d-b52c-462dfda54515


我们注意到这个宏
主要是调用了CHud::FindElement

495a2127-b851-4167-833a-de00acd552d5


我们发现这个函数有十分美妙的切入点:字符串引用
26598e38-d9e7-48d9-a99a-774a852ba701


我们进入IDA
在client.dll中搜索这个字符串
发现可以找到这个字符串

d6b587b9-8172-4ea2-b25b-bdcf99aac22e


我们定位进去 CTRL+X打开引用列表
📍你们打开列表看到的肯定不是FindElement+偏移,这个是被我改了名字所以这样
6711f3d6-07e1-4906-a4bb-42907055a831


我们定位进去发现这个函数只需要传入字符串即可
324e63e5-1bc6-42fb-b27c-cf8a1fe46767


我们为这个函数生成签名
3cf0eba6-fb5c-40a4-b875-6e968712948d


我们稍后调用这个函数 便可以获取到CBaseHudChat的指针了
📍 我们接下来需要做的是找到ChatPrintf函数


我们直接搜索ChatPrintf
发现CBaseHudChat::MsgFunc_SayText中调用了ChatPrintf函数
发现下面有字符串引用

613802e2-6e35-48ad-b2c9-6d015b88077f


我们在IDA中搜索到这个字符串后查看引用
aca71f7b-7b88-49e5-be29-0badcb99e79b


我们发现三个引用中 其中一个函数
与在SDK中看到的CBaseHudChat::MsgFunc_SayText函数结构类似
因此我们猜测箭头所指(被我命名为maybe_ChatPrintf的)的函数就是我们要找的ChatPrintf函数
📍 原因: 参数个数能对上, 两个函数的类指针相同, "%s"字符串引用
cfc3c6c3-e8ad-48b1-896c-1da1973a151e


我们定位进去 发现这个函数接受"..."类型 (代表参数个数可变)
所以我们应该是找对了

8301f592-cc5b-494a-a7a0-8f1946677266


然后我们为这个函数生成签名

LUA & FFI 教 程
我们查找CS2 FA的API 发现在utils中有个名为find_pattern的接口
我们通过调用这个API 便可以获取到函数签名的内存地址

95b40ed8-9ce1-4915-89d5-7544dbcffc9f


然后我们通过ffi.cdef 定义函数指针
449ce182-a5a8-4c93-a2ef-8b11891dc267


然后我们将获取到的内存地址转换为函数指针
00bfad45-71e4-4152-b24f-e5ddb7bf3204


然后我们便可以调用该函数
实现ChatPrintf的调用同理

代 码 实 现
代码:
local ffi = require('ffi')

ffi.cdef [[
    typedef void*(__fastcall* FindElement_t_c_r)(const char*);
]]
local sig_FindElement = '40 55 48 83 EC 20 48 83 3D EA 40 0E 01 00'
local adr_FindElement = utils.find_pattern("client.dll", sig_FindElement) -- 签名 -> FindElement内存地址
local hudElement = ffi.cast("FindElement_t_c_r", adr_FindElement) -- 地址 -> 函数指针
local CHudChatDelegate = hudElement("HudChatDelegate"); -- CHudChatDelegate

ffi.cdef [[
    typedef void*(__cdecl* ChatPrintf_t_c_r)(void*, unsigned int, const char*, ...);
]]
local sig_ChatPrintf = '4C 89 44 24 18 4C 89 4C 24 20 53 B8 40 10 00 00'
local adr_ChatPrintf = utils.find_pattern("client.dll", sig_ChatPrintf) -- 签名 -> ChatPrintf内存地址
local chatPrintf = ffi.cast("ChatPrintf_t_c_r", adr_ChatPrintf) -- 地址 -> 函数指针

local function printToChat(index, f, ...)
    chatPrintf(CHudChatDelegate, index, string.format(f, ...))
end


--[[
    --printToChat调用实例:
    printToChat(-1, "Hello, %s!", "world")
]]

🎉 测试成功 🎉
15409880-8fad-46ad-8ca2-3bc8ceb98cd4
 
后退
顶部