Гайд [Урок] Использование SendClientCheck

Статус
В этой теме нельзя размещать новые ответы.

FYP

Известный
Автор темы
Администратор
1,758
5,718
До сих пор эта функция оставалась тайной для многих скриптеров сампа, нигде и никто её не документировал. Что ж, пора пролить свет на эту тёмную сторону сампа.

SendClientCheck

Эта функция отправляет специальный запрос на клиент, затем клиент присылает свой ответ в колбэк OnClientCheckResponse. Задержка ответа зависит в основном от пинга игрока. Функция и паблик не объявлены в стандартных инклудах, так что их придётся объявить самостоятельно в начале скрипта (например, после подключения всех инклудов):
Код:
native SendClientCheck(playerid, type, arg, offset, size);
forward OnClientCheckResponse(playerid, type, arg, response);

Разберем аргументы SendClientCheck:
playerid - кому мы отправим запрос
type - тип запроса
arg - специальный аргумент
offset - оффсет чтения памяти
size - размер для чтения (всегда должен быть равен или больше 2)
Разберём подробнее, что всё это значит, чуть позже.

Теперь OnClientCheckResponse:
playerid - от кого пришёл ответ
type - тип ответа
arg - специальный аргумент
response - ещё один аргумент (крутое описание, да?)

Теперь разберёмся, что всё это значит. Есть только 4 типа запросов, которые клиент обрабатывает (аргумент type). Это 0x2, 0x46, 0x47, 0x48.

Тип 0x48
Начнём с простого. Данный запрос не нуждается ни в каких дополнительных аргументах (arg, offset, size). Он возвращает количество секунд с момента запуска компьютера в arg. Пример:
C++:
#include <a_samp>
native SendClientCheck(playerid, type, arg, offset, size); forward OnClientCheckResponse(playerid, type, arg, response);

public OnPlayerConnect(playerid)
{
SendClientCheck(playerid, 0x48, 0, 0, 2);
return 1;
}

public OnClientCheckResponse(playerid, type, arg, response)
{
new str[128];
switch(type)
{
  case 0x48:
  {
   format(str, sizeof(str), "Your computer has been running for %s!", Convert(arg / 1000));
   SendClientMessage(playerid, -1, str);
   }
  }
return 1;
}

Convert(number)
{
new hours = 0, mins = 0, secs = 0, string[100]; hours = floatround(number / 3600);
mins = floatround((number / 60) - (hours * 60)); secs = floatround(number - ((hours * 3600) + (mins * 60)));
if(hours > 0)
{
  format(string, 100, "%d:%02d:%02d", hours, mins, secs);
}
else
{
  format(string, 100, "%d:%02d", mins, secs);
}
return string;
}
При входе на сервер игроку напишет, сколько запущен его комп.

Тип 0x46
Этот тип читает данные структуры CBaseModelInfoSA указанной модели и возвращает однобайтовую чексумму. Можно указать, с какого оффсета начать чтение и сколько байт прочитать. Например, запрос SendClientCheck(playerid, 0x46, 1598, 0, 28) вернёт чексумму первых 28 байт структуры модели 1598. Более полный пример:
C++:
public OnPlayerConnect(playerid)
{
SendClientCheck(playerid, 0x46, 1598, 0, 28); // 1598 - beachball return 1;
}

public OnClientCheckResponse(playerid, type, arg, response)
{
new str[128];
switch(type)
{
  case 0x46:
  {
   format(str, sizeof(str), "Model %d has checksum 0x%x", arg, response);
   SendClientMessage(playerid, -1, str);
  }
}
return 1;
}

Тип 0x47
Этот тип уже читает данные структуры CColModelSA указанной модели (указатель на которую лежит по оффсету 20 в структуре CBaseModelInfoSA). Остальное всё аналогично предыдущему типу. Пример:
C++:
public OnPlayerConnect(playerid)
{
SendClientCheck(playerid, 0x47, 1598, 0, 48); // 1598 - beachball return 1;
}

public OnClientCheckResponse(playerid, type, arg, response)
{
new str[128];
switch(type)
{
  case 0x47: 
  {
   format(str, sizeof(str), "Col model %d has checksum 0x%x", arg, response);
   SendClientMessage(playerid, -1, str);
  }
}
return 1;
}

Тип 0x2
Вот мы и подобрались к самому интересному! Данный тип возвращает 32 (правда больше половины неизвестны/бесполезны) флага из структуры CPhysicalSA. Если игрок в транспорте, то возвращает информацию транспорта, а если пешком - то информацию о самом игроке. Это такие флаги как стоит ли игрок на земле, находится ли он в воде, касается ли воды, уязвим ли к различным типам урона (вот вам и античит на гм). Правда записывать данные мы не можем, только читать.
Пример использования будет ниже по ссылке.

Заключение
Вот, собственно, и всё, что из себя представляет эта секретная функция. К сожалению, сейчас она почти бесполезна. В 0.3x был ещё один тип - 0x5, он позволял читать указанный участок памяти сампа и тем самым проверять, установлены ли там патчи собейта и других читов, но его выпилили в 0.3z.
Полный скрипт-пример: http://pastebin.com/vndmMgFL
Автор урока: EvgeN 1137
Реверсинг: FYP, EvgeN 1137
Источник: http://lightcode.ru/showthread.php?t=112860
 

povargek

Известный
Друг
59
113
И вот спустя почти два года люди об этом узнали, когда тестировал это еще в мае 2014 (0.3z), у меня почему-то не вызывалась OnClientCheckResponse, пришлось делать в плагине.

UPD: Так-же можно проверять этим на собейт.
 

Vovich

HOT
Проверенный
717
197
И вот спустя почти два года люди об этом узнали, когда тестировал это еще в мае 2014 (0.3z), у меня почему-то не вызывалась OnClientCheckResponse, пришлось делать в плагине.

UPD: Так-же можно проверять этим на собейт.
Ибо способ проверки файлов в папке с игрой был слит одним из разработчиков клиента в середине 2014, до этого оно было доступно только для крупных проектов.
 

povargek

Известный
Друг
59
113
Ибо способ проверки файлов в папке с игрой был слит одним из разработчиков клиента в середине 2014, до этого оно было доступно только для крупных проектов.

Я про проверку на соб через 0x2 (антисоб адванса осени 2014)
 

EvgeN 1137

?
Проверенный
160
595
Ибо способ проверки файлов в папке с игрой был слит одним из разработчиков клиента в середине 2014, до этого оно было доступно только для крупных проектов.
не было никогда способа проверки файлов, проверялась память
для крупных проектов оно тоже не было доступно, это я тогда в декабре 2013 смастерил для адванса
ну а в январе 2014 функцию спалили, потому что забыли выпилить из серверной сборки после очередного обновления сервера, а затем в феврале Y_Less спалил её предназначение и описал её использование
 

Vovich

HOT
Проверенный
717
197
не было никогда способа проверки файлов, проверялась память
для крупных проектов оно тоже не было доступно, это я тогда в декабре 2013 смастерил для адванса
ну а в январе 2014 функцию спалили, потому что забыли выпилить из серверной сборки после очередного обновления сервера, а затем в феврале Y_Less спалил её предназначение и описал её использование
Ну вот о нем я и говорил, просто он спалил способ, ну а дальше уже чуть ли не каждый нубо рп пытался ставить эту защиту, использую один и тот-же код слизанный с паблика.
Ну а проверять память я и не думал об этом, я чёт думал что оно чекает файлы, ибо после слива Y_Less я как-то пытался в Pawn сделать некую проверку, и там насколько я помню чекались именно файлы в папке с игрой, но я уж потом подумал что смысла 0, так как быстрее всего можно заинжектить перед запуском процесса собейт, но только из другого места, тем самым оно бы не нашло его, но я это не проверял.
Я то думал это Рингач сделал был, а тут вон оно что, я если честно и забыл почему убрали защиту, вроде как были все же какие то недостатки, но задумка не плохая.
 
Статус
В этой теме нельзя размещать новые ответы.