////////////////////////////////////////////
//Подяка
//sc6ut | за те сказав як записати у пам'яті строку
//PanSeek | за те що одобрюе теми та цікаві книжки <3
//ARMOR | за те що помог с тестами на інших версіях
//Musaigen | за функцію котра шукає адрес по сигнатурі
///////////////////////////////////////////
#include <iostream>
#include <Windows.h>
inline void writeString(char* memory,const char* str) {
DWORD NewProtection;
VirtualProtect(memory, sizeof(str), PAGE_EXECUTE_READWRITE, &NewProtection);
std::strcpy(memory, str); //sc6ut блэт
VirtualProtect(memory, sizeof(str), NewProtection, &NewProtection);
}
static uintptr_t search_memory_pattern(std::string_view mod, std::string_view pattern, std::string_view mask) {
uint32_t handle =
reinterpret_cast<uint32_t>(GetModuleHandle(mod.data()));
if (!handle)
return 0;
MEMORY_BASIC_INFORMATION mbi{ 0 };
if (!VirtualQuery(reinterpret_cast<LPCVOID>(handle), &mbi, sizeof(mbi)))
return 0;
auto dos = reinterpret_cast<IMAGE_DOS_HEADER*>(mbi.AllocationBase);
auto pe = reinterpret_cast<IMAGE_NT_HEADERS*>(
reinterpret_cast<uint32_t>(dos) + dos->e_lfanew);
if (pe->Signature != IMAGE_NT_SIGNATURE)
return 0;
auto now = reinterpret_cast<uint8_t*>(mbi.AllocationBase);
auto end = now + pe->OptionalHeader.SizeOfImage;
size_t i{ 0 };
while (now < end) {
for (i = 0; i < mask.size(); i++) {
if (&now[i] >= end)
break;
auto character = mask[i];
auto byte = static_cast<uint8_t>(pattern[i]);
if (character == '?')
continue;
if (now[i] != byte)
break;
}
if (!mask[i])
return reinterpret_cast<uintptr_t>(now);
++now;
}
return 0;
}
constexpr std::string_view string[21] = {
"[Айді: %d, Тип: %d Підтип: %d Здоров'я: %.1f Попередньо завантажений: %u]\n\
Відстань: %.2fm\n\
Пасажирські сидіння : %u\n\
Клієнтське положення: %.3f, %.3f, %.3f\n\
Положення спавна: %.3f, %.3f, %.3f",
"Підключення до гри...",
"Втрачено з'єднання з сервером",
"Сервер перезавантажується..",
"Сервер не відповів. Повторна спроба...",
"Сервер закрив з'єднання.",
"Сервер заповнений",
"Ви забанені на цьому сервері.",
"Підключення до %s:%d...",
"Зроблено знімок - sa-mp-%03i.png",
"Не вдалося зберегти знімок.",
"Підключено до {B9C9BF}%.64s",
"Повернення до вибору класу після наступної смерті",
"Статистика клієнтської мережі",
"Видалено гравця %u через помилку.",
"-> Рухи головою Увімкнено",
"-> Рухи головою Вимкнено",
"-> Обмежувач кадрів: %u.",
"-> Обмежувач кадрів: допустимі значення 20-90",
"NameTag граців: Увімкнено",
"NameTag граців: Вимкнено",
};
constexpr std::string_view signature[21]{
//dl
"\x5B\x69\x64\x3A\x20\x25\x64\x2C\x20\x74\x79\x70\x65\x3A\x20\x25\x64\x20\x73\x75\x62\x74\x79\x70\x65\x3A\x20\x25\x64\x20\x48\x65\x61\x6C\x74\x68\x3A\x20\x25\x2E\x31\x66\x20\x70\x72\x65\x6C\x6F\x61\x64\x65\x64\x3A\x20\x25\x75\x5D\x0A\x44\x69\x73\x74\x61\x6E\x63\x65\x3A\x20\x25\x2E\x32\x66\x6D\x0A\x50\x61\x73\x73\x65\x6E\x67\x65\x72\x53\x65\x61\x74\x73\x3A\x20\x25\x75\x0A\x63\x50\x6F\x73\x3A\x20\x25\x2E\x33\x66\x2C\x25\x2E\x33\x66\x2C\x25\x2E\x33\x66\x0A\x73\x50\x6F\x73\x3A\x20\x25\x2E\x33\x66\x2C\x25\x2E\x33\x66\x2C\x25\x2E\x33\x66\x00",
//connect to game
"\x43\x6F\x6E\x6E\x65\x63\x74\x65\x64\x2E\x20\x4A\x6F\x69\x6E\x69\x6E\x67\x20\x74\x68\x65\x20\x67\x61\x6D\x65\x2E\x2E\x2E\x00",
//Lost connection
"\x4C\x6F\x73\x74\x20\x63\x6F\x6E\x6E\x65\x63\x74\x69\x6F\x6E\x20\x74\x6F\x20\x74\x68\x65\x20\x73\x65\x72\x76\x65\x72\x2E\x20\x52\x65\x63\x6F\x6E\x6E\x65\x63\x74\x69\x6E\x67\x2E\x2E\x00",
//server restarting
"\x54\x68\x65\x20\x73\x65\x72\x76\x65\x72\x20\x69\x73\x20\x72\x65\x73\x74\x61\x72\x74\x69\x6E\x67\x2E\x2E\x00",
//server didnt respond
"\x54\x68\x65\x20\x73\x65\x72\x76\x65\x72\x20\x64\x69\x64\x6E\x27\x74\x20\x72\x65\x73\x70\x6F\x6E\x64\x2E\x20\x52\x65\x74\x72\x79\x69\x6E\x67\x2E\x2E\x00",
//server closed connection
"\x53\x65\x72\x76\x65\x72\x20\x63\x6C\x6F\x73\x65\x64\x20\x74\x68\x65\x20\x63\x6F\x6E\x6E\x65\x63\x74\x69\x6F\x6E\x2E\x00",
//server full
"\x54\x68\x65\x20\x73\x65\x72\x76\x65\x72\x20\x69\x73\x20\x66\x75\x6C\x6C\x2E\x20\x52\x65\x74\x72\x79\x69\x6E\x67\x2E\x2E\x2E\x00",
//you banned
"\x59\x6F\x75\x20\x61\x72\x65\x20\x62\x61\x6E\x6E\x65\x64\x20\x66\x72\x6F\x6D\x20\x74\x68\x69\x73\x20\x73\x65\x72\x76\x65\x72\x2E\x00",
//connecting to
"\x43\x6F\x6E\x6E\x65\x63\x74\x69\x6E\x67\x20\x74\x6F\x20\x25\x73\x3A\x25\x64\x2E\x2E\x2E\x00",
//cum shot taken
"\x53\x63\x72\x65\x65\x6E\x73\x68\x6F\x74\x20\x54\x61\x6B\x65\x6E\x20\x2D\x20\x73\x61\x2D\x6D\x70\x2D\x25\x30\x33\x69\x2E\x70\x6E\x67\x00",
//unable to cum shot
"\x55\x6E\x61\x62\x6C\x65\x20\x74\x6F\x20\x73\x61\x76\x65\x20\x73\x63\x72\x65\x65\x6E\x73\x68\x6F\x74\x2E\x00",
//connecting to...
"\x43\x6F\x6E\x6E\x65\x63\x74\x65\x64\x20\x74\x6F\x20\x7B\x42\x39\x43\x39\x42\x46\x7D\x25\x2E\x36\x34\x73\x00",
//returning to class
"\x52\x65\x74\x75\x72\x6E\x69\x6E\x67\x20\x74\x6F\x20\x63\x6C\x61\x73\x73\x20\x73\x65\x6C\x65\x63\x74\x69\x6F\x6E\x20\x61\x66\x74\x65\x72\x20\x6E\x65\x78\x74\x20\x64\x65\x61\x74\x68\x00",
//client network state
"\x43\x6C\x69\x65\x6E\x74\x20\x4E\x65\x74\x77\x6F\x72\x6B\x20\x53\x74\x61\x74\x73\x00",
//removed player
"\x52\x65\x6D\x6F\x76\x65\x64\x20\x70\x6C\x61\x79\x65\x72\x20\x25\x75\x20\x64\x75\x65\x20\x74\x6F\x20\x65\x72\x72\x6F\x72\x2E\x00",
//head enabled
"\x2D\x3E\x20\x48\x65\x61\x64\x20\x6D\x6F\x76\x65\x6D\x65\x6E\x74\x73\x20\x65\x6E\x61\x62\x6C\x65\x64\x00",
//head disabled
"\x2D\x3E\x20\x48\x65\x61\x64\x20\x6D\x6F\x76\x65\x6D\x65\x6E\x74\x73\x20\x64\x69\x73\x61\x62\x6C\x65\x64\x00",
//frame limiter
"\x2D\x3E\x20\x46\x72\x61\x6D\x65\x20\x4C\x69\x6D\x69\x74\x65\x72\x3A\x20\x25\x75\x00",
//frame limiter valid
"\x2D\x3E\x20\x46\x72\x61\x6D\x65\x20\x4C\x69\x6D\x69\x74\x65\x72\x3A\x20\x76\x61\x6C\x69\x64\x20\x61\x6D\x6F\x75\x6E\x74\x73\x20\x61\x72\x65\x20\x32\x30\x2D\x39\x30\x00",
//nametag on
"\x4E\x61\x6D\x65\x54\x61\x67\x20\x50\x6C\x61\x79\x65\x72\x20\x53\x74\x61\x74\x75\x73\x3A\x20\x4F\x4E\x00",
//nametag off
"\x4E\x61\x6D\x65\x54\x61\x67\x20\x50\x6C\x61\x79\x65\x72\x20\x53\x74\x61\x74\x75\x73\x3A\x20\x4F\x46\x46\x00"
};
constexpr std::string_view mask[21] {
//dl
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//connect to game
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//Lost connection
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//server restarting
"xxxxxxxxxxxxxxxxxxxxxxxxxx",
//server didnt respond
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//server closed connection
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//server full
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//you banned
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//connecting to
"xxxxxxxxxxxxxxxxxxxxxx",
//cum shot taken
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//unable to cum shot
"xxxxxxxxxxxxxxxxxxxxxxxxxx",
//connecting to...
"xxxxxxxxxxxxxxxxxxxxxxxxxx",
//returning to class
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//client network state
"xxxxxxxxxxxxxxxxxxxx",
//removed player
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//head enabled
"xxxxxxxxxxxxxxxxxxxxxxxxx",
//head disabled
"xxxxxxxxxxxxxxxxxxxxxxxxxx",
//frame limiter
"xxxxxxxxxxxxxxxxxxxx",
//frame limiter valid
"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
//nametag on
"xxxxxxxxxxxxxxxxxxxxxxxxx",
//nametag off
"xxxxxxxxxxxxxxxxxxxxxxxxxx"
};
struct sMain {
sMain() {
for (std::uint8_t iter = 0; iter < 21; iter++) {
writeString(reinterpret_cast<char*>(search_memory_pattern("samp.dll", signature[iter], mask[iter])), string[iter].data());
}
};
}plugin;