Эта статья подойдёт для тех, кто пытается взломать/защитить приватные работы или столкнулся с отсутствием нормального апи
Сразу скажу, что вызвать функцию которой нет в секции .publics не получится, т.к. такую функцию можно считать "истинно локальной", вызвать которую можно разве что из-под более низкоуровневого яп чем сп. Функции может не быть там по 2-м причинам:
Итак, допустим следующий код был собран на 1.10:
Запускаем и видим в консоли "test"
Теперь начинается какое-то волшебство:
Либо сделайте автоматическое получение идентификатора функции из имени через GetFunctionByName. Локальные имена придётся указывать в формате
Единственное что 100% советую делать при использовании этой плюхи - выносить идентификаторы/имена функций в геймдату (см. след. страницу), ибо пересобирать решение после каждого обновления целевого плагина, которое может всё сломать, - не комильфо
А теперь приступим к "защите". У сторонних плагинов нет доступа к .data секции, поэтому если записывать туда данные, передавать в функцию и сверять их, то это можно считать как решение нашей головной боли
Старайтесь не использовать эксплойт с не определённым размером массива, поскольку в этом случае у других плагинов будет доступ к .data секции (пример), либо соберите плагин с "истинно локальными" функциями используя компилятор по ссылке ниже
Если интересно, вот модификация последней версии из стабильной ветки (1.11-dev) с "истинно локальными" функциями: Releases · sourcepawn-publics
Сразу скажу, что вызвать функцию которой нет в секции .publics не получится, т.к. такую функцию можно считать "истинно локальной", вызвать которую можно разве что из-под более низкоуровневого яп чем сп. Функции может не быть там по 2-м причинам:
- Плагин собирался на версии компилятора ниже 1.7;
- Кто-то заморочился при сборке, поскольку компилятор явно был модифицирован.
Итак, допустим следующий код был собран на 1.10:
Код:
#include <sourcemod>
public void OnPluginStart()
{
func("test");
}
void func(const char[] text)
{
PrintToServer(text);
}
Теперь начинается какое-то волшебство:
- Открываем smxviewer (надеюсь, не надо разжёвывать как его собрать или хотя бы где взять уже собранный)
- Ищем имя функции. Если был указан модификатор
public
, то имя останется таким же, если нет, то к нему будет добавлен адрес в формате.адрес.имя
- Набрасываем следующий код, где
1
- идентификатор функции из секции .publicsКод:#include <sourcemod> public void OnPluginStart() { PrivateForward fwd = new PrivateForward(ET_Ignore, Param_String); // в 1.10 здесь будет предупреждение, которое можно проигнорировать, но в 1.11+ // приведение к типу Function вызовет ошибку и плагин не соберётся fwd.AddFunction(FindPluginByFile("test.smx"), view_as<Function>(1)); Call_StartForward(fwd); Call_PushString("test2"); Call_Finish(); }
Версия для 1.11+ (используется эксплойт с не определённым размером массива):Код:#include <sourcemod> int ptr[1]; Function func; void memset(int[] p, int off, int val) { p[off] = val; } Function getFunc(int f) { memset(ptr, 1, f); return func; } public void OnPluginStart() { PrivateForward fwd = new PrivateForward(ET_Ignore, Param_String); fwd.AddFunction(FindPluginByFile("test.smx"), getFunc(1)); Call_StartForward(fwd); Call_PushString("test2"); Call_Finish(); }
Либо сделайте автоматическое получение идентификатора функции из имени через GetFunctionByName. Локальные имена придётся указывать в формате
.адрес.имя
Единственное что 100% советую делать при использовании этой плюхи - выносить идентификаторы/имена функций в геймдату (см. след. страницу), ибо пересобирать решение после каждого обновления целевого плагина, которое может всё сломать, - не комильфо
А теперь приступим к "защите". У сторонних плагинов нет доступа к .data секции, поэтому если записывать туда данные, передавать в функцию и сверять их, то это можно считать как решение нашей головной боли
Код:
#include <sourcemod>
int protect;
public void OnPluginStart()
{
protect = GetRandomInt(1, 100500);
func(protect, "test")
}
void func(int data, const char[] text)
{
if (data != protect)
SetFailState("Гэндальф неодобрительно покачивает головой");
PrintToServer(text);
}
Если интересно, вот модификация последней версии из стабильной ветки (1.11-dev) с "истинно локальными" функциями: Releases · sourcepawn-publics