Подписывайтесь на наш Telegram и не пропускайте важные новости! Перейти

Гайд Анализ драйвера FACEIT [ Часть 1 ]

Продавец
Продавец
Статус
Оффлайн
Регистрация
6 Май 2025
Сообщения
256
Реакции
235
Всем привет. В этой статье я поделюсь с вами результатом обратной разработки драйвера анти-чита FACEIT.

Обфускация:

В качестве обфускации, анти-чит использует виртуальную машину "Griffin". Такое же решение используется в Vanguard'e.
Убедиться в этом можно взглянув на секции:

| Name | | Virtual Size | | Characteristics |
.grfn10 0x2514eb 60000060 ( ER )
.grfn20 0x7d168 C0000040 ( RW )
.grfn11 0x51d569a 60000060 ( ER )
.grfn22 0x4ceb0 C0000040 ( RW )

Перейдем к результату обратной разработки:

| Сбор контекста выполнения ( FACEIT_AC.sys + 0x876C4 ):

C++:
Expand Collapse Copy
bool __fastcall capture_thread_information( volatile signed __int32* buffer ) {
    const auto processor_idx = get_current_process_idx( ); // KeGetCurrentProcessorNumber
    const auto slot = reinterpret_cast< pslot_t >( buffer + ( processor_idx * sizeof( cpu_slot_t ) ) );

    if ( !slot->filled ) {
        // заполнение данных о текущем потоке в слот

        /*
        *( _QWORD* )&a1[ v2 + 10 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned __int16 )word_1401070AC );
        *( _QWORD* )&a1[ v2 + 12 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned int )dword_140107150 );
        *( _QWORD* )&a1[ v2 + 14 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned int )dword_140107154 );
        */

        slot->thread = KeGetCurrentThread( );
        slot->cr3 = __readcr3( );
        slot->hal_reserved_data = ( void* )KeGetPcr( )->HalReserved[ 8 ];

        const auto stack_pointer = ReturnAddress( );
        const auto stack_offset = calculate_stack_delta( &stack_pointer );

        slot->stack_depth = ( stack_offset > 0x400 ) ? 1024 : stack_offset;
        slot->filled = 1;

        memcpy( &slot->stack_buffer_dump, &stack_pointer, slot->stack_depth );

        _InterlockedIncrement( buffer );
    }

    return 1;
}
* Анти-чит использует это для того, чтобы получать информацию о потоках на каждом ядре процессора. Далее, он анализирует ее и отправляет ее на сервер.

| Сканирование целостности PML4 ( FACEIT_AC.sys + 0x6D26C ):

C++:
Expand Collapse Copy
void scan_kernel_page_tables( uintptr_t* current_pml4, uintptr_t* copied_pml4 ) {
    // индексы с 0x100 ( 256 ) -> 0x1ff ( 511 ) отвечают за Kernel mode

    for ( int idx{ 0x100 }; idx < 0x200; ++idx ) {
        const auto current = current_pml4[ idx ];
        const auto copied = copied_pml4[ idx ];

        // проверка на активный "Present" бит

        if ( ( copied & 1 ) != 0 ) {
            // проверка на модифицированный PFN

            if ( ( ( current ^ copied ) & 0x0000FFFFFFFFF000ULL ) != 0 ) {
                // страница была модиицирована

                const auto report = reinterpret_cast< preport_t >( allocate_pool_non_paged_nx( 0x658 ) );

                if ( report ) {
                    // заполнение репорта данными

                    memset( report, 0, sizeof( report_t ) );

                    report->pml4_index = idx;
                    report->report_type = 18; // не факт, что это именно тип репорта, но скорее всего это оно и есть

                    /*
                    v30 = ((__int64 (__fastcall *)(__int64))(qword_140105900 ^ qword_140105908))(a2);
                    *((_DWORD *)v15 + 395) = v30;
                    *((_DWORD *)v15 + 396) = ((__int64 (__fastcall *)(__int64))(qword_140106110 ^ qword_140106118))(a2);
                    *((_DWORD *)v15 + 397) = dword_140106D18;
                    */

                    send_report( report );
                }

                ex_free_pool( report );
                break;
            }
        }
    }
}
* Анти-чит использует это для того, чтобы предотвратить PML4 Hijack ( суть этого эксплоита заключается в мануальном создании таблицы, ее модификация и запись адреса этой таблицы в CR3 процесса )

| Верификация модулей ( FACEIT_AC.sys + 0x40E48 ):

C++:
Expand Collapse Copy
bool __fastcall is_not_blacklisted_timestamp( int timestamp ) {
    return timestamp != 1475236997
        && timestamp != 1429858907
        && timestamp != 1362979926
        && timestamp != 1315311890
        && timestamp != 1117003152
        && timestamp != 1372912075
        && timestamp != 1236914549
        && timestamp != 1228525034
        && timestamp != 1508258062
        && timestamp != 1218220134
        && timestamp != 1192260120
        && timestamp != 1512106853
        && timestamp != 1215694711
        && timestamp != 1384442563
        && timestamp != 1350982095
        && timestamp != 1224284476
        && timestamp != 1246526006
        && timestamp != 1461742989
        && timestamp != 1457508537
        && timestamp != 1411041869
        && timestamp != 1521788191
        && timestamp != 1534392208
        && timestamp != 1539231917
        && timestamp != 1304986844
        && timestamp != 1367461187
        && timestamp != 1577333030
        && timestamp != 1566803778
        && timestamp != 1126291254
        && timestamp != 1302902331
        && timestamp != 1421434629
        && timestamp != 1331398650
        && timestamp != 1231373451
        && timestamp != 1390546403
        && timestamp != 1192770227
        && timestamp != 1193148207
        && timestamp != 1428561609
        && timestamp != 1479375988
        && timestamp != 1257225291
        && timestamp != 1608492340
        && timestamp != 1574187260
        && timestamp != 1530670833;
}

bool verify_module( void* ctx, void* module_base ) {
    // копирование хеадера модуля с диска

    const auto buffer = copy_process_header( ctx );
    const auto dos_header = reinterpret_cast< PIMAGE_DOS_HEADER >( buffer );

    if ( dos_header->e_magic != 0x5a4d )
        return;

    const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS64 >( buffer + dos_header->e_lfanew );

    if ( nt_headers->Signature != 0x4550 )
        return;

    // если таймстамп модуля находится в базе с заблокированными, отправляем репорт
    // ID "9" => report_blacklist_id

    if ( !is_not_blacklisted_timestamp( nt_headers->FileHeader.TimeDateStamp ) )
        return report( 9 );

    const auto mapped_image = map_image( buffer, module_base );

    if ( mapped_image ) {
        // если size_of_image на диске != size_of_image в файле, отправляем репорт
        // ID "10" => module_size_mismatch

        if ( !verify_module_size( module_base, mapped_image, buffer ) )
            return report( 10 );

        // если находим разницу между активным кодом и файлом на диске
        // ID "5" => code_patch

        if ( scan_for_patches( module_base, mapped_image, buffer ) )
            return report( 5 );

        const auto security_directory = nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_SECURITY ].VirtualAddress;
        const auto security_directory_size = nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_SECURITY ].Size;

        if ( security_directory
             && security_directory_size ) {
            const auto cert_data = get_cert_data( mapped_image, security_directory );

            // если подпись является невалидной ( или она отстуствует ), отправляем репорт
            // ID "6" => invalid_signature

            if ( is_signature_invalid( cert_data ) )
                return report( 6 );

            // если владелец подписи является недоверенным ( не microsoft и не игровые модули ), отправляем репорт
            // ID "11" => signer_untrusted

            if ( is_signer_untrusted( cert_data ) )
                return report( 11 );
        }
    }

    return true;
}

* Анти-чит использует это для того, чтобы верифицировать модули. Вызывается эта функция в LoadImageNotify каллбеке.

Вывод: Благодаря данной статье вы сможете узнать полезную информацию о Faceit'e. Надеюсь, эта статья была полезной!
 
Народ, рылся на югейме, наткнулся на этот разбор FACEIT AC. По фактам — материал бодрый: без лишнего шаманства, с нормальными зацепками по потокам, PML4 и верифу модулей. Видно, что чел реально сидел в драйвере, а не устраивал, как некоторые, литературный вечер с терминами ради одной очевидной мысли.
Особенно понравилось, что все разложено без клоунады в стиле hex_cat, где после тонны умного вида обычно остается ощущение, что тебя не просветили, а аккуратно поводили кругами. Тут хотя бы есть мясо, а не очередная попытка продать туман как инсайд.
 
Всем привет. В этой статье я поделюсь с вами результатом обратной разработки драйвера анти-чита FACEIT.

Обфускация:

В качестве обфускации, анти-чит использует виртуальную машину "Griffin". Такое же решение используется в Vanguard'e.
Убедиться в этом можно взглянув на секции:

| Name | | Virtual Size | | Characteristics |
.grfn10 0x2514eb 60000060 ( ER )
.grfn20 0x7d168 C0000040 ( RW )
.grfn11 0x51d569a 60000060 ( ER )
.grfn22 0x4ceb0 C0000040 ( RW )

Перейдем к результату обратной разработки:

| Сбор контекста выполнения ( FACEIT_AC.sys + 0x876C4 ):

C++:
Expand Collapse Copy
bool __fastcall capture_thread_information( volatile signed __int32* buffer ) {
    const auto processor_idx = get_current_process_idx( ); // KeGetCurrentProcessorNumber
    const auto slot = reinterpret_cast< pslot_t >( buffer + ( processor_idx * sizeof( cpu_slot_t ) ) );

    if ( !slot->filled ) {
        // заполнение данных о текущем потоке в слот

        /*
        *( _QWORD* )&a1[ v2 + 10 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned __int16 )word_1401070AC );
        *( _QWORD* )&a1[ v2 + 12 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned int )dword_140107150 );
        *( _QWORD* )&a1[ v2 + 14 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned int )dword_140107154 );
        */

        slot->thread = KeGetCurrentThread( );
        slot->cr3 = __readcr3( );
        slot->hal_reserved_data = ( void* )KeGetPcr( )->HalReserved[ 8 ];

        const auto stack_pointer = ReturnAddress( );
        const auto stack_offset = calculate_stack_delta( &stack_pointer );

        slot->stack_depth = ( stack_offset > 0x400 ) ? 1024 : stack_offset;
        slot->filled = 1;

        memcpy( &slot->stack_buffer_dump, &stack_pointer, slot->stack_depth );

        _InterlockedIncrement( buffer );
    }

    return 1;
}
* Анти-чит использует это для того, чтобы получать информацию о потоках на каждом ядре процессора. Далее, он анализирует ее и отправляет ее на сервер.

| Сканирование целостности PML4 ( FACEIT_AC.sys + 0x6D26C ):

C++:
Expand Collapse Copy
void scan_kernel_page_tables( uintptr_t* current_pml4, uintptr_t* copied_pml4 ) {
    // индексы с 0x100 ( 256 ) -> 0x1ff ( 511 ) отвечают за Kernel mode

    for ( int idx{ 0x100 }; idx < 0x200; ++idx ) {
        const auto current = current_pml4[ idx ];
        const auto copied = copied_pml4[ idx ];

        // проверка на активный "Present" бит

        if ( ( copied & 1 ) != 0 ) {
            // проверка на модифицированный PFN

            if ( ( ( current ^ copied ) & 0x0000FFFFFFFFF000ULL ) != 0 ) {
                // страница была модиицирована

                const auto report = reinterpret_cast< preport_t >( allocate_pool_non_paged_nx( 0x658 ) );

                if ( report ) {
                    // заполнение репорта данными

                    memset( report, 0, sizeof( report_t ) );

                    report->pml4_index = idx;
                    report->report_type = 18; // не факт, что это именно тип репорта, но скорее всего это оно и есть

                    /*
                    v30 = ((__int64 (__fastcall *)(__int64))(qword_140105900 ^ qword_140105908))(a2);
                    *((_DWORD *)v15 + 395) = v30;
                    *((_DWORD *)v15 + 396) = ((__int64 (__fastcall *)(__int64))(qword_140106110 ^ qword_140106118))(a2);
                    *((_DWORD *)v15 + 397) = dword_140106D18;
                    */

                    send_report( report );
                }

                ex_free_pool( report );
                break;
            }
        }
    }
}
* Анти-чит использует это для того, чтобы предотвратить PML4 Hijack ( суть этого эксплоита заключается в мануальном создании таблицы, ее модификация и запись адреса этой таблицы в CR3 процесса )

| Верификация модулей ( FACEIT_AC.sys + 0x40E48 ):

C++:
Expand Collapse Copy
bool __fastcall is_not_blacklisted_timestamp( int timestamp ) {
    return timestamp != 1475236997
        && timestamp != 1429858907
        && timestamp != 1362979926
        && timestamp != 1315311890
        && timestamp != 1117003152
        && timestamp != 1372912075
        && timestamp != 1236914549
        && timestamp != 1228525034
        && timestamp != 1508258062
        && timestamp != 1218220134
        && timestamp != 1192260120
        && timestamp != 1512106853
        && timestamp != 1215694711
        && timestamp != 1384442563
        && timestamp != 1350982095
        && timestamp != 1224284476
        && timestamp != 1246526006
        && timestamp != 1461742989
        && timestamp != 1457508537
        && timestamp != 1411041869
        && timestamp != 1521788191
        && timestamp != 1534392208
        && timestamp != 1539231917
        && timestamp != 1304986844
        && timestamp != 1367461187
        && timestamp != 1577333030
        && timestamp != 1566803778
        && timestamp != 1126291254
        && timestamp != 1302902331
        && timestamp != 1421434629
        && timestamp != 1331398650
        && timestamp != 1231373451
        && timestamp != 1390546403
        && timestamp != 1192770227
        && timestamp != 1193148207
        && timestamp != 1428561609
        && timestamp != 1479375988
        && timestamp != 1257225291
        && timestamp != 1608492340
        && timestamp != 1574187260
        && timestamp != 1530670833;
}

bool verify_module( void* ctx, void* module_base ) {
    // копирование хеадера модуля с диска

    const auto buffer = copy_process_header( ctx );
    const auto dos_header = reinterpret_cast< PIMAGE_DOS_HEADER >( buffer );

    if ( dos_header->e_magic != 0x5a4d )
        return;

    const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS64 >( buffer + dos_header->e_lfanew );

    if ( nt_headers->Signature != 0x4550 )
        return;

    // если таймстамп модуля находится в базе с заблокированными, отправляем репорт
    // ID "9" => report_blacklist_id

    if ( !is_not_blacklisted_timestamp( nt_headers->FileHeader.TimeDateStamp ) )
        return report( 9 );

    const auto mapped_image = map_image( buffer, module_base );

    if ( mapped_image ) {
        // если size_of_image на диске != size_of_image в файле, отправляем репорт
        // ID "10" => module_size_mismatch

        if ( !verify_module_size( module_base, mapped_image, buffer ) )
            return report( 10 );

        // если находим разницу между активным кодом и файлом на диске
        // ID "5" => code_patch

        if ( scan_for_patches( module_base, mapped_image, buffer ) )
            return report( 5 );

        const auto security_directory = nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_SECURITY ].VirtualAddress;
        const auto security_directory_size = nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_SECURITY ].Size;

        if ( security_directory
             && security_directory_size ) {
            const auto cert_data = get_cert_data( mapped_image, security_directory );

            // если подпись является невалидной ( или она отстуствует ), отправляем репорт
            // ID "6" => invalid_signature

            if ( is_signature_invalid( cert_data ) )
                return report( 6 );

            // если владелец подписи является недоверенным ( не microsoft и не игровые модули ), отправляем репорт
            // ID "11" => signer_untrusted

            if ( is_signer_untrusted( cert_data ) )
                return report( 11 );
        }
    }

    return true;
}

* Анти-чит использует это для того, чтобы верифицировать модули. Вызывается эта функция в LoadImageNotify каллбеке.

Вывод: Благодаря данной статье вы сможете узнать полезную информацию о Faceit'e. Надеюсь, эта статья была полезной!
в чем прикол с <span>is_not_blacklisted_timestamp</span>? что это вообще за даты и что они значат?
 
в чем прикол с <span>is_not_blacklisted_timestamp</span>? что это вообще за даты и что они значат?
это таймстампы даты компиляции различных уязвимых драйверов. их нельзя сменить, иначе сертификат на драйвере станет невалидным. анти-чит это использует для того, чтобы детектить уязвимые драйвера ( которые используются для различных эксплоитов или загрузки неподписанных драйверов )
 
1775245501362.png

он предугадал что это будет
 
Всем привет. В этой статье я поделюсь с вами результатом обратной разработки драйвера анти-чита FACEIT.

Обфускация:

В качестве обфускации, анти-чит использует виртуальную машину "Griffin". Такое же решение используется в Vanguard'e.
Убедиться в этом можно взглянув на секции:

| Name | | Virtual Size | | Characteristics |
.grfn10 0x2514eb 60000060 ( ER )
.grfn20 0x7d168 C0000040 ( RW )
.grfn11 0x51d569a 60000060 ( ER )
.grfn22 0x4ceb0 C0000040 ( RW )

Перейдем к результату обратной разработки:

| Сбор контекста выполнения ( FACEIT_AC.sys + 0x876C4 ):

C++:
Expand Collapse Copy
bool __fastcall capture_thread_information( volatile signed __int32* buffer ) {
    const auto processor_idx = get_current_process_idx( ); // KeGetCurrentProcessorNumber
    const auto slot = reinterpret_cast< pslot_t >( buffer + ( processor_idx * sizeof( cpu_slot_t ) ) );

    if ( !slot->filled ) {
        // заполнение данных о текущем потоке в слот

        /*
        *( _QWORD* )&a1[ v2 + 10 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned __int16 )word_1401070AC );
        *( _QWORD* )&a1[ v2 + 12 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned int )dword_140107150 );
        *( _QWORD* )&a1[ v2 + 14 ] = *( _QWORD* )( ( char* )KeGetCurrentThread( ) + ( unsigned int )dword_140107154 );
        */

        slot->thread = KeGetCurrentThread( );
        slot->cr3 = __readcr3( );
        slot->hal_reserved_data = ( void* )KeGetPcr( )->HalReserved[ 8 ];

        const auto stack_pointer = ReturnAddress( );
        const auto stack_offset = calculate_stack_delta( &stack_pointer );

        slot->stack_depth = ( stack_offset > 0x400 ) ? 1024 : stack_offset;
        slot->filled = 1;

        memcpy( &slot->stack_buffer_dump, &stack_pointer, slot->stack_depth );

        _InterlockedIncrement( buffer );
    }

    return 1;
}
* Анти-чит использует это для того, чтобы получать информацию о потоках на каждом ядре процессора. Далее, он анализирует ее и отправляет ее на сервер.

| Сканирование целостности PML4 ( FACEIT_AC.sys + 0x6D26C ):

C++:
Expand Collapse Copy
void scan_kernel_page_tables( uintptr_t* current_pml4, uintptr_t* copied_pml4 ) {
    // индексы с 0x100 ( 256 ) -> 0x1ff ( 511 ) отвечают за Kernel mode

    for ( int idx{ 0x100 }; idx < 0x200; ++idx ) {
        const auto current = current_pml4[ idx ];
        const auto copied = copied_pml4[ idx ];

        // проверка на активный "Present" бит

        if ( ( copied & 1 ) != 0 ) {
            // проверка на модифицированный PFN

            if ( ( ( current ^ copied ) & 0x0000FFFFFFFFF000ULL ) != 0 ) {
                // страница была модиицирована

                const auto report = reinterpret_cast< preport_t >( allocate_pool_non_paged_nx( 0x658 ) );

                if ( report ) {
                    // заполнение репорта данными

                    memset( report, 0, sizeof( report_t ) );

                    report->pml4_index = idx;
                    report->report_type = 18; // не факт, что это именно тип репорта, но скорее всего это оно и есть

                    /*
                    v30 = ((__int64 (__fastcall *)(__int64))(qword_140105900 ^ qword_140105908))(a2);
                    *((_DWORD *)v15 + 395) = v30;
                    *((_DWORD *)v15 + 396) = ((__int64 (__fastcall *)(__int64))(qword_140106110 ^ qword_140106118))(a2);
                    *((_DWORD *)v15 + 397) = dword_140106D18;
                    */

                    send_report( report );
                }

                ex_free_pool( report );
                break;
            }
        }
    }
}
* Анти-чит использует это для того, чтобы предотвратить PML4 Hijack ( суть этого эксплоита заключается в мануальном создании таблицы, ее модификация и запись адреса этой таблицы в CR3 процесса )

| Верификация модулей ( FACEIT_AC.sys + 0x40E48 ):

C++:
Expand Collapse Copy
bool __fastcall is_not_blacklisted_timestamp( int timestamp ) {
    return timestamp != 1475236997
        && timestamp != 1429858907
        && timestamp != 1362979926
        && timestamp != 1315311890
        && timestamp != 1117003152
        && timestamp != 1372912075
        && timestamp != 1236914549
        && timestamp != 1228525034
        && timestamp != 1508258062
        && timestamp != 1218220134
        && timestamp != 1192260120
        && timestamp != 1512106853
        && timestamp != 1215694711
        && timestamp != 1384442563
        && timestamp != 1350982095
        && timestamp != 1224284476
        && timestamp != 1246526006
        && timestamp != 1461742989
        && timestamp != 1457508537
        && timestamp != 1411041869
        && timestamp != 1521788191
        && timestamp != 1534392208
        && timestamp != 1539231917
        && timestamp != 1304986844
        && timestamp != 1367461187
        && timestamp != 1577333030
        && timestamp != 1566803778
        && timestamp != 1126291254
        && timestamp != 1302902331
        && timestamp != 1421434629
        && timestamp != 1331398650
        && timestamp != 1231373451
        && timestamp != 1390546403
        && timestamp != 1192770227
        && timestamp != 1193148207
        && timestamp != 1428561609
        && timestamp != 1479375988
        && timestamp != 1257225291
        && timestamp != 1608492340
        && timestamp != 1574187260
        && timestamp != 1530670833;
}

bool verify_module( void* ctx, void* module_base ) {
    // копирование хеадера модуля с диска

    const auto buffer = copy_process_header( ctx );
    const auto dos_header = reinterpret_cast< PIMAGE_DOS_HEADER >( buffer );

    if ( dos_header->e_magic != 0x5a4d )
        return;

    const auto nt_headers = reinterpret_cast< PIMAGE_NT_HEADERS64 >( buffer + dos_header->e_lfanew );

    if ( nt_headers->Signature != 0x4550 )
        return;

    // если таймстамп модуля находится в базе с заблокированными, отправляем репорт
    // ID "9" => report_blacklist_id

    if ( !is_not_blacklisted_timestamp( nt_headers->FileHeader.TimeDateStamp ) )
        return report( 9 );

    const auto mapped_image = map_image( buffer, module_base );

    if ( mapped_image ) {
        // если size_of_image на диске != size_of_image в файле, отправляем репорт
        // ID "10" => module_size_mismatch

        if ( !verify_module_size( module_base, mapped_image, buffer ) )
            return report( 10 );

        // если находим разницу между активным кодом и файлом на диске
        // ID "5" => code_patch

        if ( scan_for_patches( module_base, mapped_image, buffer ) )
            return report( 5 );

        const auto security_directory = nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_SECURITY ].VirtualAddress;
        const auto security_directory_size = nt_headers->OptionalHeader.DataDirectory[ IMAGE_DIRECTORY_ENTRY_SECURITY ].Size;

        if ( security_directory
             && security_directory_size ) {
            const auto cert_data = get_cert_data( mapped_image, security_directory );

            // если подпись является невалидной ( или она отстуствует ), отправляем репорт
            // ID "6" => invalid_signature

            if ( is_signature_invalid( cert_data ) )
                return report( 6 );

            // если владелец подписи является недоверенным ( не microsoft и не игровые модули ), отправляем репорт
            // ID "11" => signer_untrusted

            if ( is_signer_untrusted( cert_data ) )
                return report( 11 );
        }
    }

    return true;
}

* Анти-чит использует это для того, чтобы верифицировать модули. Вызывается эта функция в LoadImageNotify каллбеке.

Вывод: Благодаря данной статье вы сможете узнать полезную информацию о Faceit'e. Надеюсь, эта статья была полезной!
Классная статья, пока читал возбудился, перенервничал и отрубился, как проснулся пошел дальше читать статьи на югейме, лайк!
 
Назад
Сверху Снизу