QUALITY MADE IN GERMANY
. BattlEye состоит из множества элементов, совместно работающих над поиском читеров в играх, оплативших использование продукта. Четырьмя основными элементами являются:\.namedpipeBattleye
и до 2018 года был незашифрованным. Теперь все передаваемые данные шифруются xor-шифровальщиком с очень маленькими ключами, из-за чего чрезвычайно просто выполнять известные атаки на основе открытых текстов (plaintext attacks). Когда шелл-код передаётся клиенту, он располагается и выполняется за пределами всех известных модулей, из-за чего его легко определить. Для создания дампа шелл-кода можно или обрабатывать стандартные функции Windows API типа CreateFile, ReadFile и т.п., и выполнять дамп соответствующей области памяти всех вызывающих модулей (запрашивая информацию о памяти по возвращаемому адресу), находящихся за пределами всех известных модулей, или периодически сканировать пространство виртуальной памяти игры в поисках исполняемой памяти за пределами всех известных модулей, и дампить её на диск. При этом нужно отслеживать, дамп каких областей уже был выполнен, чтобы в результате не получилось множество одинаковых дампов.// MEMORY ENUMERATION
for (current_address = 0
// QUERY MEMORY_BASIC_INFORMATION
NtQueryVirtualMemory(GetCurrentProcess(), current_address, 0, &memory_information, 0x30, &return_length) >= 0
current_address = memory_information.base_address + memory_information.region_size)
{
const auto outside_of_shellcode =
memory_information.base_address > shellcode_entry ||
memory_information.base_address + memory_information.region_size <= shellcode_entry
const auto executable_memory =
memory_information.state == MEM_COMMIT &&
(memory_information.protect == PAGE_EXECUTE ||
memory_information.protect == PAGE_EXECUTE_READ ||
memory_information.protect == PAGE_EXECUTE_READWRITE
const auto unknown_whitelist =
memory_information.protect != PAGE_EXECUTE_READWRITE ||
memory_information.region_size != 100000000
if (!executable_memory || !outside_of_shellcode || !unknown_whitelist)
continue
// RUN CHECKS
memory::anomaly_check(memory_information
memory::pattern_check(current_address, memory_information
memory::module_specific_check_microsoft(memory_information
memory::guard_check(current_address, memory_information
memory::module_specific_check_unknown(memory_information
}
void memory::anomaly_check(MEMORY_BASIC_INFORMATION memory_information)
{
// REPORT ANY EXECUTABLE PAGE OUTSIDE OF KNOWN MODULES
if (memory_information.type == MEM_PRIVATE || memory_information.type == MEM_MAPPED)
{
if ((memory_information.base_address & 0xFF0000000000) != 0x7F0000000000 && // UPPER EQUALS 0x7F
(memory_information.base_address & 0xFFF000000000) != 0x7F000000000 && // UPPER EQUALS 0x7F0
(memory_information.base_address & 0xFFFFF0000000) != 0x70000000 && // UPPER EQUALS 0x70000
memory_information.base_address != 0x3E0000))
{
memory_report.unknown = 0
memory_report.report_id = 0x2F
memory_report.base_address = memory_information.base_address
memory_report.region_size = memory_information.region_size
memory_report.memory_info =
memory_information.type |
memory_information.protect |
memory_information.state
battleye::report(&memory_report, sizeof(memory_report), 0
}
}
}
[05 18] ojectsPUBGChinese
[05 17] BattleGroundsPrivate_CheatESP
[05 17] [%.0fm] %s
[05 3E] 0000Neck0000Chest0000000Mouse 10
[05 3F] PlayerESPColor
[05 40] Aimbot: %d02D3E2041
[05 36] HackMachine
[05 4A] VisualHacks.net
[05 50] 3E232F653E31314E4E563D4276282A3A2E463F757523286752552E6F30584748
[05 4F] DLLInjection-master\x64\Release[05 52] NameESP
[05 48] Skullhack
[05 55] .rdata$zzzdbg
[05 39] AimBot
[05 39] EB4941803C123F755C623FEB388D41D0FBEC93C977583E930EB683E1DF
[05 5F] 55E9
[05 5F] 57E9
[05 5F] 60E9
[05 68] D3D11Present initialised
[05 6E] [ %.0fM ]
[05 74] [hp:%d]%dm
[05 36] 48836424380488D4C2458488B5424504C8BC848894C24304C8BC7488D4C2460
[05 36] 741FBA80000FF15607E0085C07510F2F1087801008B8788100EB
[05 36] 40F2AA156F8D2894E9AB4489535D34F9CPOSITION0000COL
[05 7A] FFE090
[05 79] %s00%d00POSITION0000COLOR0000000
[05 36] 8E85765DCDDA452E75BA12B4C7B94872116DB948A1DAA6B948A7676BB948902C
[05 8A] n<assembly xmlsn='urn:schemas-mi
05
и уникальный идентификатор.void memory::pattern_check(void* current_address, MEMORY_BASIC_INFORMATION memory_information)
{
const auto is_user32 = memory_information.allocation_base == GetModuleHandleA("user32.dll"
// ONLY SCAN PRIVATE MEMORY AND USER32 CODE SECTION
if (memory_information.type != MEM_PRIVATE && !is_user32)
continue
for (address = current_address
address != memory_information.base_address + memory_information.region_size
address += PAGE_SIZE) // PAGE_SIZE
{
// READ ENTIRE PAGE FROM LOCAL PROCESS INTO BUFFER
if (NtReadVirtualMemory(GetCurrentProcess(), address, buffer, PAGE_SIZE, 0) < 0)
continue
for (pattern_index = 0 pattern_index < 0x1C/*PATTERN COUNT*/ ++pattern_index)
{
if (pattern[pattern_index].header == 0x57A && !is_user32) // ONLY DO FFE090 SEARCHES WHEN IN USER32
continue
for (offset = 0 pattern[pattern_index].length + offset <= PAGE_SIZE ++offset)
{
const auto pattern_matches =
memory::pattern_match(&address[offset], pattern[pattern_index // BASIC PATTERN MATCH
if (pattern_matches)
{
// PATTERN FOUND IN MEMORY
pattern_report.unknown = 0
pattern_report.report_id = 0x35
pattern_report.type = pattern[index].header
pattern_report.data = &address[offset
pattern_report.base_address = memory_information.base_address
pattern_report.region_size = memory_information.region_size
pattern_report.memory_info =
memory_information.type |
memory_information.protect |
memory_information.state
battleye::report(&pattern_report, sizeof(pattern_report), 0
}
}
}
}
}
void memory::module_specific_check_microsoft(MEMORY_BASIC_INFORMATION memory_information)
{
auto executable =
memory_information.protect == PAGE_EXECUTE ||
memory_information.protect == PAGE_EXECUTE_READ ||
memory_information.protect == PAGE_EXECUTE_READWRITE
auto allocated =
memory_information.state == MEM_COMMIT
if (!allocated || !executable)
continue
auto mmres_handle = GetModuleHandleA("mmres.dll"
auto mshtml_handle = GetModuleHandleA("mshtml.dll"
if (mmres_handle && mmres_handle == memory_information.allocation_base)
{
battleye_module_anomaly_report module_anomaly_report
module_anomaly_report.unknown = 0
module_anomaly_report.report_id = 0x5B
module_anomaly_report.identifier = 0x3480
module_anomaly_report.region_size = memory_information.region_size
battleye::report(&module_anomaly_report, sizeof(module_anomaly_report), 0
}
else if (mshtml_handle && mshtml_handle == memory_information.allocation_base)
{
battleye_module_anomaly_report module_anomaly_report
module_anomaly_report.unknown = 0
module_anomaly_report.report_id = 0x5B
module_anomaly_report.identifier = 0xB480
module_anomaly_report.region_size = memory_information.region_size
battleye::report(&module_anomaly_report, sizeof(module_anomaly_report), 0
}
}
void memory::module_specific_check_unknown(MEMORY_BASIC_INFORMATION memory_information)
{
const auto dos_header = (DOS_HEADER*)module_handle
const auto pe_header = (PE_HEADER*)(module_handle + dos_header->e_lfanew
const auto is_image = memory_information.state == MEM_COMMIT && memory_information.type == MEM_IMAGE
if (!is_image)
return
const auto is_base = memory_information.base_address == memory_information.allocation_base
if (!is_base)
return
const auto match_1 =
time_date_stamp == 0x5B12C900 &&
*(__int8*)(memory_information.base_address + 0x1000) == 0x00 &&
*(__int32*)(memory_information.base_address + 0x501000) != 0x353E900
const auto match_2 =
time_date_stamp == 0x5A180C35 &&
*(__int8*)(memory_information.base_address + 0x1000) != 0x00
const auto match_2 =
time_date_stamp == 0xFC9B9325 &&
*(__int8*)(memory_information.base_address + 0x6D3000) != 0x00
if (!match_1 && !match_2 && !match_3)
return
const auto buffer_offset = 0x00 // OFFSET DEPENDS ON WHICH MODULE MATCHES, RESPECTIVELY 0x501000, 0x1000 AND 0x6D3000
unknown_module_report.unknown1 = 0
unknown_module_report.report_id = 0x46
unknown_module_report.unknown2 = 1
unknown_module_report.data = *(__int128*)(memory_information.base_address + buffer_offset
battleye::report(&unknown_module_report, sizeof(unknown_module_report), 0
}
action_x64.dll
имеет метку времени 0x5B12C900
и содержит область кода, в которую можно выполнять запись; как и говорилось ранее, это можно использовать для эксплойта.void memory::guard_check(void* current_address, MEMORY_BASIC_INFORMATION memory_information)
{
if (memory_information.protect != PAGE_NOACCESS)
{
auto bad_ptr = IsBadReadPtr(current_address, sizeof(temporary_buffer
auto read = NtReadVirtualMemory(
GetCurrentProcess(),
current_address,
temporary_buffer, sizeof(temporary_buffer),
0
if (read < 0 || bad_ptr)
{
auto query = NtQueryVirtualMemory(
GetCurrentProcess(),
current_address,
0,
&new_memory_information, sizeof(new_memory_information),
&return_length
memory_guard_report.guard =
query < 0 ||
new_memory_information.state != memory_information.state ||
new_memory_information.protect != memory_information.protect
if (memory_guard_report.guard)
{
memory_guard_report.unknown = 0
memory_guard_report.report_id = 0x21
memory_guard_report.base_address = memory_information.base_address
memory_guard_report.region_size = (int)memory_information.region_size
memory_guard_report.memory_info =
memory_information.type |
memory_information.protect |
memory_information.state
battleye::report(&memory_guard_report, sizeof(memory_guard_report), 0
}
}
}
}
GetWindowThreadProcessId
. Следовательно, можно привязать соответствующую функцию к ложному владельцу окна, чтобы BattlEye не проверял ваше окно.void window_handler::enumerate()
{
for (auto window_handle = GetTopWindow
window_handle
window_handle = GetWindow(window_handle, GW_HWNDNEXT), // GET WINDOW BELOW
++window_handler::windows_enumerated) // INCREMENT GLOBAL COUNT FOR LATER USAGE
{
auto window_process_pid = 0
GetWindowThreadProcessId(window_handle, &window_process_pid
if (window_process_pid == GetCurrentProcessId())
continue
// APPEND INFORMATION TO THE MISC. REPORT, THIS IS EXPLAINED LATER IN THE ARTICLE
window_handler::handle_summary(window_handle
constexpr auto max_character_count = 0x80
const auto length = GetWindowTextA(window_handle, window_title_report.window_title, max_character_count
// DOES WINDOW TITLE MATCH ANY OF THE BLACKLISTED TITLES?
if (!contains(window_title_report.window_title, "CheatAut") &&
!contains(window_title_report.window_title, "pubg_kh") &&
!contains(window_title_report.window_title, "conl -") &&
!contains(window_title_report.window_title, "PerfectA") &&
!contains(window_title_report.window_title, "AIMWA") &&
!contains(window_title_report.window_title, "PUBG AIM") &&
!contains(window_title_report.window_title, "HyperChe"))
continue
// REPORT WINDOW
window_title_report.unknown_1 = 0
window_title_report.report_id = 0x33
battleye::report(&window_title_report, sizeof(window_title_report) + length, 0
}
}
void window_handler::check_count()
{
if (window_handler::windows_enumerated > 1)
return
// WINDOW ENUMERATION FAILED, MOST LIKELY DUE TO HOOK
window_anomaly_report.unknown_1 = 0
window_anomaly_report.report_id = 0x44
window_anomaly_report.enumerated_windows = windows_enumerated
battleye::report(&window_anomaly_report, sizeof(window_anomaly_report), 0
}
CreateToolhelp32Snapshot
BattlEye перебирает все запущенные процессы, но не обрабатывает никакие ошибки, благодаря чему очень легко пропатчить и избежать выполнения следующих процедур обнаружения:Desktop
Temp
FileRec
Documents
Downloads
Roaming
tmp.ex
notepad.
...\.
cmd.ex
steam.exe [0x01]
explorer.exe [0x02]
lsass.exe [0x08]
cmd.exe [0x10]
QueryLimitedInformation
, то он установит бит флага 0x04
, если причина ошибки при сбое вызова OpenProcess
не равна ERROR_ACCESS_DENIED
, что даёт нам последний контейнер перечисления для соответствующего значения флага:enum BATTLEYE_PROCESS_FLAG
{
STEAM = 0x1,
EXPLORER = 0x2,
ERROR = 0x4,
LSASS = 0x8,
CMD = 0x10
}
0x40
0x38
Имя образа содержит "Loadlibr"
Имя образа содержит "Rng "
Имя образа содержит "A0E7FFFFFF81"
Имя образа содержит "RNG "
Имя образа содержит "90E54355"
Имя образа содержит "2.6.ex"
Имя образа содержит "TempFile.exe"
gameoverlayui.exe
; известно, что его часто используют для эксплойтов рендеринга, потому что довольно легко взломать и выполнять незаконную отрисовку в окне игры. Проверка имеет следующее условие:file size != 0 && image name contains (case insensitive) gameoverlayu
void gameoverlay::pattern_scan(MEMORY_BASIC_INFORMATION memory_information)
{
// PATTERNS:
// Home
// F1
// FFFF83C48C30000000000
// \.pipe%s
// C760000C64730
// 60C01810033D2
// ...
// PATTERN SCAN, ALMOST IDENTICAL CODE TO THE AFOREMENTIONED PATTERN SCANNING ROUTINE
gameoverlay_memory_report.unknown_1 = 0
gameoverlay_memory_report.report_id = 0x35
gameoverlay_memory_report.identifier = 0x56C
gameoverlay_memory_report.data = &buffer[offset
gameoverlay_memory_report.base_address = memory_information.base_address
gameoverlay_memory_report.region_size = (int)memory_information.region_size
gameoverlay_memory_report.memory_info =
memory_information.type |
memory_information.protect |
memory_information.state
battleye::report(&gameoverlay_memory_report, sizeof(gameoverlay_memory_report), 0
}
void gameoverlay::memory_anomaly_scan(MEMORY_BASIC_INFORMATION memory_information)
{
// ...
// ALMOST IDENTICAL ANOMALY SCAN COMPARED TO MEMORY ENUMERATION ROUTINE OF GAME PROCESS
gameoverlay_report.unknown = 0
gameoverlay_report.report_id = 0x3B
gameoverlay_report.base_address = memory_information.base_address
gameoverlay_report.region_size = memory_information.region_size
gameoverlay_report.memory_info = memory_information.type | memory_information.protect | memory_information.state
battleye::report(&gameoverlay_report, sizeof(gameoverlay_report), 0
}
void gameoverlay::protection_check(HANDLE process_handle)
{
auto process_protection = 0
NtQueryInformationProcess(
process_handle, ProcessProtectionInformation,
&process_protection, sizeof(process_protection), nullptr
if (process_protection == 0) // NO PROTECTION
return
gameoverlay_protected_report.unknown = 0
gameoverlay_protected_report.report_id = 0x35
gameoverlay_protected_report.identifier = 0x5B1
gameoverlay_protected_report.data = process_protection
battleye::report(&gameoverlay_protected_report, sizeof(gameoverlay_protected_report), 0
}
3B
.vgui2_s.dll
и gameoverlayui.dll
. Для этих модулей выполняется несколько проверок, начиная с gameoverlayui.dll
.[gameoverlayui.dll+6C779] == 08BE55DC3CCCCB8????????C3CCCCCC
, то шелл-код сканирует vtable по адресу, хранящемуся в байтах ????????
. Если любой из этих элементов vtable находится за пределами исходного модуля gameoverlayui.dll или указывает на инструкцию int 3
, то о пользователе сообщается на сервер с id уведомления 3B
.void gameoverlay::scan_vtable(HANDLE process_handle, char* buffer, MODULEENTRY32 module_entry)
{
char function_buffer[16
for (vtable_index = 0 vtable_index < 20 vtable_index += 4)
{
NtReadVirtualMemory(
process_handle,
*(int*)&buffer[vtable_index],
&function_buffer,
sizeof(function_buffer),
0
if (*(int*)&buffer[vtable_index] < module_entry.modBaseAddr ||
*(int*)&buffer[vtable_index] >= module_entry.modBaseAddr + module_entry.modBaseSize ||
function_buffer[0] == 0xCC ) // FUNCTION PADDING
{
gameoverlay_vtable_report.report_id = 0x3B
gameoverlay_vtable_report.vtable_index = vtable_index
gameoverlay_vtable_report.address = buffer[vtable_index
battleye::report(&gameoverlay_vtable_report, sizeof(gameoverlay_vtable_report), 0
}
}
}
vgui2_s.dll
тоже выполняется специфическая процедура проверки:void vgui::scan()
{
if (!equals(vgui_buffer, "6A08B31FF561C8BD??????????FF96????????8BD????????8B1FF90"))
{
auto could_read = NtReadVirtualMemory(
process_handle, module_entry.modBaseAddr + 0x48338, vgui_buffer, 8, 0) >= 0
constexpr auto pattern_offset = 0x48378
// IF READ DID NOT FAIL AND PATTERN IS FOUND
if (could_read && equals(vgui_buffer, "6A46A06A26A"))
{
vgui_report.unknown_1 = 0
vgui_report.report_id = 0x3B
vgui_report.unknown_2 = 0
vgui_report.address = LODWORD(module_entry.modBaseAddr) + pattern_offset
// READ TARGET BUFFER INTO REPORT
NtReadVirtualMemory(
process_handle,
module_entry.modBaseAddr + pattern_offset,
vgui_report.buffer,
sizeof(vgui_report.buffer),
0
battleye::report(&vgui_report, sizeof(vgui_report), 0
}
}
else if (
// READ ADDRESS FROM CODE
NtReadVirtualMemory(process_handle, *(int*)&vgui_buffer[9], vgui_buffer, 4, 0) >= 0 &&
// READ POINTER TO CLASS
NtReadVirtualMemory(process_handle, *(int*)vgui_buffer, vgui_buffer, 4, 0) >= 0 &&
// READ POINTER TO VIRTUAL TABLE
NtReadVirtualMemory(process_handle, *(int*)vgui_buffer, vgui_buffer, sizeof(vgui_buffer), 0) >= 0)
{
for (vtable_index = 0 vtable_index < 984 vtable_index += 4 ) // 984/4 VTABLE ENTRY COUNT
{
NtReadVirtualMemory(process_handle, *(int*)&vgui_buffer[vtable_index], &vtable_entry, sizeof(vtable_entry), 0
if (*(int*)&vgui_buffer[vtable_index] < module_entry.modBaseAddr ||
*(int*)&vgui_buffer[vtable_index] >= module_entry.modBaseAddr + module_entry.modBaseSize ||
vtable_entry == 0xCC )
{
vgui_vtable_report.unknown = 0
vgui_vtable_report.report_id = 0x3B
vgui_vtable_report.vtable_index = vtable_index
vgui_vtable_report.address = *(int*)&vgui_buffer[vtable_index
battleye::report(&vgui_vtable_report, sizeof(vgui_vtable_report), 0
}
}
}
48378
, которое является расположением области кода:push 04
push offset aCBuildslaveSte_4 ; "c:\buildslave\steam_rel_client_win32"...
push offset aAssertionFaile_7 ; "Assertion Failed: IsValidIndex(elem)"
push 04
push 00
push 02
push ??
void gameoverlay::check_thread(THREADENTRY32 thread_entry)
{
const auto tread_handle = OpenThread(THREAD_SUSPEND_RESUME|THREAD_GET_CONTEXT, 0, thread_entry.th32ThreadID
if (thread_handle)
{
suspend_count = ResumeThread(thread_handle
if (suspend_count > 0)
{
SuspendThread(thread_handle
gameoverlay_thread_report.unknown = 0
gameoverlay_thread_report.report_id = 0x3B
gameoverlay_thread_report.suspend_count = suspend_count
battleye::report(&gameoverlay_thread_report, sizeof(gameoverlay_thread_report), 0
}
if (GetThreadContext(thread_handle, &context) && context.Dr7)
{
gameoverlay_debug_report.unknown = 0
gameoverlay_debug_report.report_id = 0x3B
gameoverlay_debug_report.debug_register = context.Dr0
battleye::report(&gameoverlay_debug_report, sizeof(gameoverlay_debug_report), 0
}
}
}
if (equals(process_entry.executable_path, "lsass.exe"))
{
auto lsass_handle = OpenProcess(QueryInformation, 0, (unsigned int)process_entry.th32ProcessID
if (lsass_handle)
{
for (address = 0
NtQueryVirtualMemory(lsass_handle, address, 0, &lsass_memory_info, 0x30, &bytes_needed) >= 0
address = lsass_memory_info.base_address + lsass_memory_info.region_size)
{
if (lsass_memory_info.state == MEM_COMMIT
&& lsass_memory_info.type == MEM_PRIVATE
&& (lsass_memory_info.protect == PAGE_EXECUTE
|| lsass_memory_info.protect == PAGE_EXECUTE_READ
|| lsass_memory_info.protect == PAGE_EXECUTE_READWRITE))
{
// FOUND EXECUTABLE MEMORY OUTSIDE OF MODULES
lsass_report.unknown = 0
lsass_report.report_id = 0x42
lsass_report.base_address = lsass_memory_info.base_address
lsass_report.region_size = lsass_memory_info.region_size
lsass_report.memory_info =
lsass_memory_info.type | lsass_memory_info.protect | lsass_memory_info.state
battleye::report(&lsass_report, sizeof(lsass_report), 0
}
}
CloseHandle(lsass_handle
}
}
ReadProcessMemory
/WriteProcessMemory
, перенаправляя вызовы на свой драйвер BEDaisy. Далее BEDaisy решает, является ли операция с памятью законной. Если он считает, что операция законна, то он продолжает её, а в противном случае намеренно включает машине синий экран.3C
. Эта информация состоит из следующих элементов:BE_DLL.dll
, если эта библиотека найдена на диске.void noeye::detect()
{
WIN32_FILE_ATTRIBUTE_DATA file_information
if (GetFileAttributesExA("BE_DLL.dll", 0, &file_information))
{
noeye_report.unknown = 0
noeye_report.report_id = 0x3D
noeye_report.file_size = file_information.nFileSizeLow
battleye::report(&noeye_report, sizeof(noeye_report), 0
}
}
void driver::check_beep()
{
auto handle = CreateFileA("\\.\Beep", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0
if (handle != INVALID_HANDLE_VALUE)
{
beep_report.unknown = 0
beep_report.report_id = 0x3E
battleye::report(&beep_report, sizeof(beep_report), 0
CloseHandle(handle
}
}
void driver::check_null()
{
auto handle = CreateFileA("\\.\Null", GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0
if (handle != INVALID_HANDLE_VALUE)
{
null_report.unknown = 0
null_report.report_id = 0x3E
battleye::report(&null_report, sizeof(null_report), 0
CloseHandle(handle
}
}
void sleep::check_delta()
{
const auto tick_count = GetTickCount
Sleep(1000
const auto tick_delta = GetTickCount() - tick_count
if (tick_delta >= 1200)
{
sleep_report.unknown = 0
sleep_report.report_id = 0x45
sleep_report.delta = tick_delta
battleye::report(&sleep_report, sizeof(sleep_report), 0
}
}
void module::check_7zip()
{
constexpr auto sz_7zipdll = "..\..\Plugins\ZipUtility\ThirdParty\7zpp\dll\Win64\7z.dll"
const auto module_handle = GetModuleHandleA(sz_7zipdll
if (module_handle && *(int*)(module_handle + 0x1000) != 0xFF1441C7)
{
sevenzip_report.unknown_1 = 0
sevenzip_report.report_id = 0x46
sevenzip_report.unknown_2 = 0
sevenzip_report.data1 = *(__int64*)(module_handle + 0x1000
sevenzip_report.data2 = *(__int64*)(module_handle + 0x1008
battleye::report(&sevenzip_report, sizeof(sevenzip_report), 0
}
}
void module::check_hal()
{
const auto module_handle = GetModuleHandleA("hal.dll"
if (module_handle)
{
hal_report.unknown_1 = 0
hal_report.report_id = 0x46
hal_report.unknown_2 = 2
hal_report.data1 = *(__int64*)(module_handle + 0x1000
hal_report.data2 = *(__int64*)(module_handle + 0x1008
battleye::report(&hal_report, sizeof(hal_report), 0
}
}
void module::check_nvtoolsext64_1
{
const auto module_handle = GetModuleHandleA("nvToolsExt64_1.dll"
if (module_handle)
{
nvtools_report.unknown = 0
nvtools_report.report_id = 0x48
nvtools_report.module_id = 0x5A8
nvtools_report.size_of_image = (PE_HEADER*)(module_handle + (DOS_HEADER*)(module_handle)->e_lfanew))->SizeOfImage
battleye::report(&nvtools_report, sizeof(nvtools_report), 0
}
}
void module::check_ws2detour_x96
{
const auto module_handle = GetModuleHandleA("ws2detour_x96.dll"
if (module_handle)
{
ws2detour_report.unknown = 0
ws2detour_report.report_id = 0x48
ws2detour_report.module_id = 0x5B5
ws2detour_report.size_of_image = (PE_HEADER*)(module_handle + (DOS_HEADER*)(module_handle)->e_lfanew))->SizeOfImage
battleye::report(&ws2detour_report, sizeof(ws2detour_report), 0
}
}
void module::check_networkdllx64
{
const auto module_handle = GetModuleHandleA("networkdllx64.dll"
if (module_handle)
{
const auto dos_header = (DOS_HEADER*)module_handle
const auto pe_header = (PE_HEADER*)(module_handle + dos_header->e_lfanew
const auto size_of_image = pe_header->SizeOfImage
if (size_of_image < 0x200000 || size_of_image >= 0x400000)
{
if (pe_header->sections[DEBUG_DIRECTORY].size == 0x1B20)
{
networkdll64_report.unknown = 0
networkdll64_report.report_id = 0x48
networkdll64_report.module_id = 0x5B7
networkdll64_report.data = pe_header->TimeDatestamp
battleye::report(&networkdll64_report, sizeof(networkdll64_report), 0
}
}
else
{
networkdll64_report.unknown = 0
networkdll64_report.report_id = 0x48
networkdll64_report.module_id = 0x5B7
networkdll64_report.data = pe_header->sections[DEBUG_DIRECTORY].size
battleye::report(&networkdll64_report, sizeof(networkdll64_report), 0
}
}
}
void module::check_nxdetours_64
{
const auto module_handle = GetModuleHandleA("nxdetours_64.dll"
if (module_handle)
{
nxdetours64_report.unknown = 0
nxdetours64_report.report_id = 0x48
nxdetours64_report.module_id = 0x5B8
nxdetours64_report.size_of_image = (PE_HEADER*)(module_handle + (DOS_HEADER*)(module_handle)->e_lfanew))->SizeOfImage
battleye::report(&nxdetours64_report, sizeof(nxdetours64_report), 0
}
}
void module::check_nvcompiler
{
const auto module_handle = GetModuleHandleA("nvcompiler.dll"
if (module_handle)
{
nvcompiler_report.unknown = 0
nvcompiler_report.report_id = 0x48
nvcompiler_report.module_id = 0x5BC
nvcompiler_report.data = *(int*)(module_handle + 0x1000
battleye::report(&nvcompiler_report, sizeof(nvcompiler_report), 0
}
}
void module::check_wmp
{
const auto module_handle = GetModuleHandleA("wmp.dll"
if (module_handle)
{
wmp_report.unknown = 0
wmp_report.report_id = 0x48
wmp_report.module_id = 0x5BE
wmp_report.data = *(int*)(module_handle + 0x1000
battleye::report(&wmp_report, sizeof(wmp_report), 0
}
}
enum module_id
{
nvtoolsext64 = 0x5A8,
ws2detour_x96 = 0x5B5,
networkdll64 = 0x5B7,
nxdetours_64 = 0x5B8,
nvcompiler = 0x5BC,
wmp = 0x5BE
void network::scan_tcp_table
{
memset(local_port_buffer, 0, sizeof(local_port_buffer
for (iteration_index = 0 iteration_index < 500 ++iteration_index)
{
// GET NECESSARY SIZE OF TCP TABLE
auto table_size = 0
GetExtendedTcpTable(0, &table_size, false, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0
// ALLOCATE BUFFER OF PROPER SIZE FOR TCP TABLE
auto allocated_ip_table = (MIB_TCPTABLE_OWNER_MODULE*)malloc(table_size
if (GetExtendedTcpTable(allocated_ip_table, &table_size, false, AF_INET, TCP_TABLE_OWNER_MODULE_ALL, 0) != NO_ERROR)
goto cleanup
for (entry_index = 0 entry_index < allocated_ip_table->dwNumEntries ++entry_index)
{
const auto ip_address_match_1 =
allocated_ip_table->table[entry_index].dwRemoteAddr == 0x656B1468 // 104.20.107.101
const auto ip_address_match_2 =
allocated_ip_table->table[entry_index].dwRemoteAddr == 0x656C1468 // 104.20.108.101
const auto port_match =
allocated_ip_table->table[entry_index].dwRemotePort == 20480
if ( (!ip_address_match_1 && !ip_address_match_2) || !port_match)
continue
for (port_index = 0
port_index < 10 &&
allocated_ip_table->table[entry_index].dwLocalPort !=
local_port_buffer[port_index
++port_index)
{
if (local_port_buffer[port_index])
continue
tcp_table_report.unknown = 0
tcp_table_report.report_id = 0x48
tcp_table_report.module_id = 0x5B9
tcp_table_report.data =
BYTE1(allocated_ip_table->table[entry_index].dwLocalPort) |
(LOBYTE(allocated_ip_table->table[entry_index.dwLocalPort) << 8
battleye::report(&tcp_table_report, sizeof(tcp_table_report), 0
local_port_buffer[port_index] = allocated_ip_table->table[entry_index].dwLocalPort
break
}
}
cleanup:
// FREE TABLE AND SLEEP
free(allocated_ip_table
Sleep(10
}
}
enum BATTLEYE_REPORT_ID
{
MEMORY_GUARD = 0x21,
MEMORY_SUSPICIOUS = 0x2F,
WINDOW_TITLE = 0x33,
MEMORY = 0x35,
PROCESS_ANOMALY = 0x38,
DRIVER_BEEP_PRESENCE = 0x3E,
DRIVER_NULL_PRESENCE = 0x3F,
MISCELLANEOUS_ANOMALY = 0x3B,
PROCESS_SUSPICIOUS = 0x40,
LSASS_MEMORY = 0x42,
SLEEP_ANOMALY = 0x45,
MEMORY_MODULE_SPECIFIC = 0x46,
GENERIC_ANOMALY = 0x48,
MEMORY_MODULE_SPECIFIC2 = 0x5B,
}
К сожалению, не доступен сервер mySQL