ffi
Встроенный модуль ffi LuaJIT вызывает функции игры и работает с её памятью напрямую. Он доступен, если указан в зависимостях скрипта на сайте. Помощники vtable_bind, vtable_thunk, bind_pattern упрощают вызов функций игры.
Через FFI скрипт читает и пишет память игры и вызывает её функции без проверок. Неверный указатель, индекс или тип функции вызовет вылет игры.
-- В зависимостях скрипта на сайте указан ffi
local ffi = require("ffi")
print(type(ffi.cast)) --> function
vtable_bind(module: string, interface: string, index: number, ctype: string)#
Берёт интерфейс interface модуля module, достаёт из его таблицы виртуальных функций функцию номер index и возвращает обёртку для вызова. Указатель на интерфейс (this) подставляется сам.
| Параметр | Тип | Описание |
|---|---|---|
module |
string |
имя модуля, например "engine2.dll" |
interface |
string |
имя интерфейса с версией |
index |
number |
номер функции в таблице |
ctype |
string |
тип функции FFI, например "bool(__thiscall*)(void*)" |
Ошибки: invalid interface — интерфейс не найден; invalid C type — неверный тип.
Возвращает: function — вызов fn(...).
-- Номер функции и тип зависят от версии игры
local is_in_game = vtable_bind("engine2.dll", "Source2EngineToClient001", 39, "bool(__thiscall*)(void*)")
print(is_in_game())
vtable_thunk(index: number, ctype: string)#
Возвращает функцию, которая для любого объекта вызывает его виртуальную функцию номер index.
| Параметр | Тип | Описание |
|---|---|---|
index |
number |
номер функции в таблице |
ctype |
string |
тип функции FFI |
Возвращает: function(instance, ...) — первый аргумент — указатель на объект (cdata).
local ffi = require("ffi")
-- Номер функции условный: подставьте настоящий
local get_value = vtable_thunk(5, "int(__thiscall*)(void*)")
local obj = ffi.cast("void*", utils.interface("engine2.dll", "Source2EngineToClient001"))
-- print(get_value(obj))
bind_pattern(module: string, interface: string, signature: string, ctype: string)#
Ищет в модуле функцию по сигнатуре байтов и возвращает обёртку, которая вызывает её с интерфейсом interface в качестве this.
| Параметр | Тип | Описание |
|---|---|---|
module |
string |
имя модуля |
interface |
string |
имя интерфейса того же модуля |
signature |
string |
сигнатура байтов, как в utils.pattern |
ctype |
string |
тип функции FFI |
Ошибки: invalid interface, invalid C type, invalid signature (сигнатура не найдена).
Возвращает: function — вызов fn(...).
-- Сигнатура и тип условные: подставьте настоящие
local ok, fn = pcall(bind_pattern, "engine2.dll", "Source2EngineToClient001", "48 89 5C 24 08", "void(__thiscall*)(void*)")
print(ok and "найдено" or fn)