0%
Обязательно ознакомьтесь с правилами форума!
Safe Userinfo

CS 1.6 Amxx Safe Userinfo 1.0.4

Защита ReHLDS от уязвимостей, типа «~0WN3D~BY~X64CR3W~»
Код:
#pragma semicolon 1

#include <amxmodx>
#include <reapi>

#define PLUGIN_NAME     "Safe Userinfo"
#define PLUGIN_VERSION  "1.0.4"
#define PLUGIN_AUTHOR   "the_hunter"

public plugin_init()
{
    register_plugin(PLUGIN_NAME, PLUGIN_VERSION, PLUGIN_AUTHOR);
    RegisterHookChain(RH_SV_CheckUserInfo, "OnCheckUserInfo");
    RegisterHookChain(RG_CSGameRules_ClientUserInfoChanged, "OnClientUserInfoChanged");
}

public OnCheckUserInfo(address, buffer)
{
    if ((!IsValidUtf8InfoBuffer(buffer))) {
        SetHookChainReturn(ATYPE_INTEGER, false);
        return HC_BREAK;
    }

    return HC_CONTINUE;
}

public OnClientUserInfoChanged(player, info[])
{
    if ((!IsValidUtf8InfoString(info))) {
        KickForInvalidUserInfo(player);
        return HC_BREAK;
    }

    return HC_CONTINUE;
}

KickForInvalidUserInfo(player)
{
    new bool:isPlayerConnected = (rh_get_client_connect_time(player) != 0);

    if (isPlayerConnected) {
        rh_drop_client(player, "Invalid userinfo");
    }
}

bool:IsValidUtf8InfoBuffer(buffer)
{
    const MAX_INFO_STRING = 256;

    new info[MAX_INFO_STRING];
    get_key_value_buffer(buffer, info, charsmax(info));

    return IsValidUtf8InfoString(info);
}

bool:IsValidUtf8InfoString(const info[])
{
    new i = 0;
    new bytes, codepoint;

    while (info[i] != EOS) {
        bytes = Utf8Codepoint(info, i, codepoint);

        if (bytes < 1) {
            return false;
        }

        // Reject control characters in the ranges U+0000–U+001F and U+007F–U+009F
        if (((codepoint >= 0x0000) && (codepoint <= 0x001F)) ||
            ((codepoint >= 0x007F) && (codepoint <= 0x009F))) {
            return false;
        }

        // Reject bidirectional text control characters
        if ((codepoint >= 0x202A) && (codepoint <= 0x202E)) {
            return false;
        }

        // Reject deprecated control characters
        if ((codepoint >= 0x206A) && (codepoint <= 0x206F)) {
            return false;
        }

        // Reject Line Separator and Paragraph Separator
        if ((0x2028 == codepoint) || (0x2029 == codepoint)) {
            return false;
        }

        i += bytes;
    }

    return true;
}

stock Utf8Codepoint(const string[], index, &codepoint)
{
    new curByte = string[index];

    if (EOS == curByte) {
        return 0;
    }

    // 4-byte UTF-8 codepoint
    if (0xF0 == (0xF8 & curByte)) {
        if ((EOS == string[(index + 1)]) || (EOS == string[(index + 2)]) || (EOS == string[(index + 3)])) {
            return 0; // Incomplete sequence
        }

        if ((0x80 != (0xC0 & string[(index + 1)])) ||
            (0x80 != (0xC0 & string[(index + 2)])) ||
            (0x80 != (0xC0 & string[(index + 3)]))) {
            return 0; // Invalid continuation byte
        }

        codepoint = (((0x07 & curByte) << 18) | ((0x3F & string[(index + 1)]) << 12) |
                    ((0x3F & string[(index + 2)]) << 6) | (0x3F & string[(index + 3)]));

        if ((codepoint < 0x010000) || (codepoint > 0x10FFFF)) {
            return 0; // Out of valid Unicode range
        }

        return 4;
    }

    // 3-byte UTF-8 codepoint
    if (0xE0 == (0xF0 & curByte)) {
        if ((EOS == string[(index + 1)]) || (EOS == string[(index + 2)])) {
            return 0; // Incomplete sequence
        }

        if ((0x80 != (0xC0 & string[(index + 1)])) || (0x80 != (0xC0 & string[(index + 2)]))) {
            return 0; // Invalid continuation byte
        }

        codepoint = (((0x0F & curByte) << 12) | ((0x3F & string[(index + 1)]) << 6) | (0x3F & string[(index + 2)]));

        if ((codepoint >= 0xD800) && (codepoint <= 0xDFFF)) {
            return 0; // Surrogate pairs are not allowed
        }

        if ((codepoint < 0x0800) || (codepoint > 0xFFFF)) {
            return 0; // Out of valid Unicode range
        }

        return 3;
    }

    // 2-byte UTF-8 codepoint
    if (0xC0 == (0xE0 & curByte)) {
        if (EOS == string[(index + 1)]) {
            return 0; // Incomplete sequence
        }

        if (0x80 != (0xC0 & string[(index + 1)])) {
            return 0; // Invalid continuation byte
        }

        codepoint = (((0x1F & curByte) << 6) | (0x3F & string[(index + 1)]));

        if ((codepoint < 0x0080) || (codepoint > 0x07FF)) {
            return 0; // Out of valid Unicode range
        }

        return 2;
    }

    // 1-byte UTF-8 codepoint
    if ((curByte > 0) && (curByte <= 0x007F)) {
        codepoint = curByte;
        return 1;
    }

    return 0; // Invalid start byte
}
Верх Низ