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

Тема в разделе "PAWN", создана пользователем FYP, 13 янв 2016.

Статус темы:
Закрыта.
  1. FYP

    FYP админ какой-то

    Регистрация:
    09.03.13
    Сообщения:
    786
    Лайки:
    1.622
    Репутация:
    674
    До сих пор эта функция оставалась тайной для многих скриптеров сампа, нигде и никто её не документировал. Что ж, пора пролить свет на эту тёмную сторону сампа.

    SendClientCheck

    Эта функция отправляет специальный запрос на клиент, затем клиент присылает свой ответ в колбэк OnClientCheckResponse. Задержка ответа зависит в основном от пинга игрока. Функция и паблик не объявлены в стандартных инклудах, так что их придётся объявить самостоятельно в начале скрипта (например, после подключения всех инклудов):
    Код (Text):
    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
     
    #1
    Sire, hnnssy, mac и ещё 1-му нравится это.
  2. povargek

    Проверенный

    Регистрация:
    18.03.13
    Сообщения:
    51
    Лайки:
    21
    Репутация:
    25
    И вот спустя почти два года люди об этом узнали, когда тестировал это еще в мае 2014 (0.3z), у меня почему-то не вызывалась OnClientCheckResponse, пришлось делать в плагине.

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

    Проверенный

    Регистрация:
    21.12.14
    Сообщения:
    449
    Лайки:
    160
    Репутация:
    51
    Ибо способ проверки файлов в папке с игрой был слит одним из разработчиков клиента в середине 2014, до этого оно было доступно только для крупных проектов.
     
    #3
  4. povargek

    Проверенный

    Регистрация:
    18.03.13
    Сообщения:
    51
    Лайки:
    21
    Репутация:
    25
    Я про проверку на соб через 0x2 (антисоб адванса осени 2014)
     
    #4
  5. EvgeN 1137

    EvgeN 1137 Известный пользователь

    Регистрация:
    09.03.13
    Сообщения:
    137
    Лайки:
    90
    Репутация:
    82
    не было никогда способа проверки файлов, проверялась память
    для крупных проектов оно тоже не было доступно, это я тогда в декабре 2013 смастерил для адванса
    ну а в январе 2014 функцию спалили, потому что забыли выпилить из серверной сборки после очередного обновления сервера, а затем в феврале Y_Less спалил её предназначение и описал её использование
     
    #5
  6. Vovich

    Проверенный

    Регистрация:
    21.12.14
    Сообщения:
    449
    Лайки:
    160
    Репутация:
    51
    Ну вот о нем я и говорил, просто он спалил способ, ну а дальше уже чуть ли не каждый нубо рп пытался ставить эту защиту, использую один и тот-же код слизанный с паблика.
    Ну а проверять память я и не думал об этом, я чёт думал что оно чекает файлы, ибо после слива Y_Less я как-то пытался в Pawn сделать некую проверку, и там насколько я помню чекались именно файлы в папке с игрой, но я уж потом подумал что смысла 0, так как быстрее всего можно заинжектить перед запуском процесса собейт, но только из другого места, тем самым оно бы не нашло его, но я это не проверял.
    Я то думал это Рингач сделал был, а тут вон оно что, я если честно и забыл почему убрали защиту, вроде как были все же какие то недостатки, но задумка не плохая.
     
    #6
Статус темы:
Закрыта.