Страница 1 из 3 123 ПоследняяПоследняя
Показано с 1 по 10 из 21

Тема: Использование SendClientCheck

  1. #1
    Почетный пользователь Аватар для EvgeN 1137
    Регистрация
    10.01.2011
    Адрес
    не скажу
    Сообщений
    3,005
    Репутация: 580

    Звание: - это имя известно всем

    Использование SendClientCheck

    До сих пор эта функция оставалась тайной для многих скриптеров сампа, нигде и никто её не документировал. Что ж, пора пролить свет на эту тёмную сторону сампа.

    SendClientCheck


    Эта функция отправляет специальный запрос на клиент, затем клиент присылает свой ответ в колбэк OnClientCheckResponse. Задержка ответа зависит в основном от пинга игрока. Функция и паблик не объявлены в стандартных инклудах, так что их придётся объявить самостоятельно в начале скрипта (например, после подключения всех инклудов):

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

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

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

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

    native SendClientCheck(playeridtypeargoffsetsize);
    forward OnClientCheckResponse(playeridtypeargresponse);

    public 
    OnPlayerConnect(playerid)
    {
        
    SendClientCheck(playerid0x48002);
        return 
    1;
    }

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

    Convert(number)
    {
        new 
    hours 0mins 0secs 0string[100];
        
    hours floatround(number 3600);
        
    mins floatround((number 60) - (hours 60));
        
    secs floatround(number - ((hours 3600) + (mins 60)));
        if(
    hours 0)
        {
            
    format(string100"%d:%02d:%02d"hoursminssecs);
        }
        else
        {
            
    format(string100"%d:%02d"minssecs);
        }
        return 
    string;

    При входе на сервер игроку напишет, сколько запущен его комп.

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

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

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

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

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

    Заключение
    Вот, собственно, и всё, что из себя представляет эта секретная функция. К сожалению, сейчас она почти бесполезна. В 0.3x был ещё один тип - 0x5, он позволял читать указанный участок памяти сампа и тем самым проверять, установлены ли там патчи собейта и других читов, но его выпилили в 0.3z.

    Полный скрипт-пример: http://pastebin.com/vndmMgFL

    PHP код:
    // SendClientCheck example script by evgen1137
    // thanks to MTA devs for structs
    #include <a_samp>

    native SendClientCheck(playeridtypeargoffsetsize);
    forward OnClientCheckResponse(playeridtypeargresponse);

    #define GetBit(%0,%1) ((%0 >> %1) & 1)

    enum Flags
    {
        
    b0x01,
        
    bApplyGravity,
        
    bDisableFriction,
        
    bCollidable,
        
    b0x10,
        
    bDisableMovement,
        
    b0x40,
        
    b0x80,

        
    bSubmergedInWater,
        
    bOnSolidSurface,
        
    bBroken,
        
    b0x800,
        
    b0x1000,
        
    b0x2000,
        
    b0x4000,
        
    b0x8000,

        
    b0x10000,
        
    b0x20000,
        
    bBulletProof,
        
    bFireProof,
        
    bCollisionProof,
        
    bMeeleProof,
        
    bInvulnerable,
        
    bExplosionProof,

        
    b0x1000000,
        
    bAttachedToEntity,
        
    b0x4000000,
        
    bTouchingWater,
        
    bEnableCollision,
        
    bDestroyed,
        
    b0x40000000,
        
    b0x80000000
    };

    new 
    PhysFlags[MAX_PLAYERS][Flags];
    new 
    Timer;

    public 
    OnFilterScriptInit()
    {
        
    Timer SetTimer("TimerFunc"1000true);
    }

    public 
    OnFilterScriptExit()
    {
        
    KillTimer(Timer);
    }

    public 
    OnPlayerConnect(playerid)
    {
        for(new 
    032i++)
        {
            
    PhysFlags[playerid][Flags:i] = 0;
        }
        
    SendClientCheck(playerid0x48002);
        
    SendClientCheck(playerid0x461598028); // 1598 - beachball
        
    SendClientCheck(playerid0x471598048); // 1598 - beachball
        
    return 1;
    }

    public 
    OnClientCheckResponse(playeridtypeargresponse)
    {
        new 
    str[128];
        switch(
    type)
        {
            case 
    0x2:
            {
                
    // CPhysicalSAInterface
                // https://github.com/multitheftauto/mtasa-blue/blob/master/MTA10/game_sa/CPhysicalSA.h#L39-L73
                
    for(new 032i++)
                {
                    
    PhysFlags[playerid][Flags:i] = GetBit(argi);
                }
                
    format(strsizeof(str), "bSubmergedInWater: %d, bOnSolidSurface: %d"PhysFlags[playerid][bSubmergedInWater], PhysFlags[playerid][bOnSolidSurface]);
                
    SendClientMessage(playerid, -1str);
            }
             case 
    0x46:
            {
                
    // CBaseModelInfoSAInterface
                // https://github.com/multitheftauto/mtasa-blue/blob/master/MTA10/game_sa/CModelInfoSA.h#L138-L181
                
    format(strsizeof(str), "Model %d has checksum 0x%x"argresponse);
                
    SendClientMessage(playerid, -1str);
            }
            case 
    0x47
            {
                
    // CColModelSAInterface
                // https://github.com/multitheftauto/mtasa-blue/blob/master/MTA10/game_sa/CColModelSA.h#L87-L91
                
    format(strsizeof(str), "Col model %d has checksum 0x%x"argresponse);
                
    SendClientMessage(playerid, -1str);
            }
            case 
    0x48:
            {
                
    format(strsizeof(str), "Your computer has been running for %s!"Convert(arg 1000));
                
    SendClientMessage(playerid, -1str);
            }
        }
        return 
    1;
    }

    forward TimerFunc();
    public 
    TimerFunc()
    {
        for(new 
    0MAX_PLAYERSi++)
        {
            if(!
    IsPlayerConnected(i)) continue;
            
    SendClientCheck(i0x2002);
        }
    }

    Convert(number)
    {
        new 
    hours 0mins 0secs 0string[100];
        
    hours floatround(number 3600);
        
    mins floatround((number 60) - (hours 60));
        
    secs floatround(number - ((hours 3600) + (mins 60)));
        if(
    hours 0)
        {
            
    format(string100"%d:%02d:%02d"hoursminssecs);
        }
        else
        {
            
    format(string100"%d:%02d"minssecs);
        }
        return 
    string;


    Автор урока: EvgeN 1137
    Реверсинг: FYP, EvgeN 1137
    Эксклюзив LightCode
    При копировании указывать источник.
    :)

  2. 18 пользователей сказали cпасибо EvgeN 1137 за это полезное сообщение:

    Argument (14.01.2016), Disinterpreter (13.01.2016), e.kosovskij (14.01.2016), Fallen A. (13.01.2016), frog163 (08.02.2016), Games (14.01.2016), Mexanizm (08.03.2016), SDraw (13.01.2016), Seregamil (14.01.2016), spc. (07.02.2016), unknown2156 (14.01.2016), UnO33 (14.01.2016), Untonyst (13.01.2016), vasyok28 (14.01.2016), Джонни Ди (13.01.2016), Меша (08.03.2016), Фора (13.01.2016)

  3. #2
    Potato Аватар для SDraw
    Регистрация
    10.04.2011
    Сообщений
    1,327
    Репутация: 390

    Звание: - очень-очень хороший человек
    Хороший бэкдор, хвала проприетарщине

  4. 1 пользователь сказал cпасибо SDraw за это полезное сообщение:

    Kenny_Dalglish (11.02.2016)

  5. #3
    Почетный пользователь LC Аватар для ziggi
    Регистрация
    15.07.2010
    Адрес
    St. Petersburg
    Возраст
    30
    Сообщений
    370
    Репутация: 151

    Звание: - весьма и весьма положительная личность
    При использовании, нужно обязательно проверять на NOP.
    Блог: ziggi.org
    GitHub: github.com/ziggi
    Open-GTO Project: https://github.com/Open-GTO
    FCNPC (боты для SA-MP): https://github.com/Open-GTO/FCNPC

  6. #4
    unknown2154
    Бродяга
    Цитата Сообщение от ziggi Посмотреть сообщение
    При использовании, нужно обязательно проверять на NOP.
    Что мешает читеру перехватить RPC, составить фейковый ответ серверу и отправить его?

  7. #5
    Почетный пользователь LC Аватар для ziggi
    Регистрация
    15.07.2010
    Адрес
    St. Petersburg
    Возраст
    30
    Сообщений
    370
    Репутация: 151

    Звание: - весьма и весьма положительная личность
    Цитата Сообщение от Hidden125661 Посмотреть сообщение
    Что мешает читеру перехватить RPC, составить фейковый ответ серверу и отправить его?
    Ничего, но как дополнительный слой проверки - пойдёт.
    Блог: ziggi.org
    GitHub: github.com/ziggi
    Open-GTO Project: https://github.com/Open-GTO
    FCNPC (боты для SA-MP): https://github.com/Open-GTO/FCNPC

  8. #6
    Почетный пользователь Аватар для EvgeN 1137
    Регистрация
    10.01.2011
    Адрес
    не скажу
    Сообщений
    3,005
    Репутация: 580

    Звание: - это имя известно всем
    Сейчас любой RPC можно перехватить и составить фейковый ответ. И любой занопить. Да и вообще в произвольный момент вызвать (например, поднять пикап издалека). Так что это более глобальная проблема, чем проблема конкретно этой функции и колбэка
    :)

  9. #7
    SYSTEM Аватар для Games
    Регистрация
    28.06.2010
    Адрес
    Moscow
    Возраст
    30
    Сообщений
    1,468
    Репутация: 478

    Звание: - луч света в тёмном царстве
    Очень интересно было почитать. Молодец
    пусто

  10. #8
    Активный пользователь Аватар для vasyok28
    Регистрация
    11.01.2013
    Адрес
    Украина
    Возраст
    30
    Сообщений
    564
    Репутация: 96

    Звание: скоро придёт к известности
    А где ты про эту функцию узнал? очень интересно
    Мою подпись угнали(
    Нарушение ЕПФ: "Подпись и иже с ней" п.4 (с) TERNER

  11. #9
    Почетный пользователь Аватар для EvgeN 1137
    Регистрация
    10.01.2011
    Адрес
    не скажу
    Сообщений
    3,005
    Репутация: 580

    Звание: - это имя известно всем
    Цитата Сообщение от vasyok28 Посмотреть сообщение
    А где ты про эту функцию узнал? очень интересно
    Реверсинг: FYP, EvgeN 1137
    https://ru.wikipedia.org/wiki/Обратная_разработка
    :)

  12. #10
    Почетный пользователь LC Аватар для ziggi
    Регистрация
    15.07.2010
    Адрес
    St. Petersburg
    Возраст
    30
    Сообщений
    370
    Репутация: 151

    Звание: - весьма и весьма положительная личность
    Цитата Сообщение от vasyok28 Посмотреть сообщение
    А где ты про эту функцию узнал? очень интересно
    Сто лет назад Y_Less описал работу этой функции на каком-то читерском форуме, его ещё из-за этого из бета тестеров выгнали.
    Блог: ziggi.org
    GitHub: github.com/ziggi
    Open-GTO Project: https://github.com/Open-GTO
    FCNPC (боты для SA-MP): https://github.com/Open-GTO/FCNPC

Страница 1 из 3 123 ПоследняяПоследняя

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •