-
Автор темы
- #1
Перед прочтением основного контента ниже, пожалуйста, обратите внимание на обновление внутри секции Майна на нашем форуме. У нас появились:
- бесплатные читы для Майнкрафт — любое использование на свой страх и риск;
- маркетплейс Майнкрафт — абсолютно любая коммерция, связанная с игрой, за исключением продажи читов (аккаунты, предоставления услуг, поиск кодеров читов и так далее);
- приватные читы для Minecraft — в этом разделе только платные хаки для игры, покупайте группу "Продавец" и выставляйте на продажу свой софт;
- обсуждения и гайды — всё тот же раздел с вопросами, но теперь модернизированный: поиск нужных хаков, пати с игроками-читерами и другая полезная информация.
Спасибо!
DLL Injector с авторизацией, подпиской и функциями Inject / Uniject
Основные возможности:
PHP файлы
Основные возможности:
- Авторизация и регистрация — доступ только для зарегистрированных пользователей с активной подпиской.
- Инъекция DLL — загрузка DLL в целевой процесс через VirtualAllocEx, WriteProcessMemory и CreateRemoteThread.
- Деинъекция DLL — безопасное извлечение DLL с использованием FreeLibrary.
- Система подписок — без активной подписки доступ к функциям заблокирован.
- Инъекция: выделение памяти с VirtualAllocEx, запись пути к DLL через WriteProcessMemory, вызов LoadLibraryW через CreateRemoteThread.
- Деинъекция: аналогичный процесс, но с вызовом FreeLibrary через CreateRemoteThread.
- Авторизация: проверка логина и количества оставшихся дней подписки перед выполнением действий.
Injector code:
#ifndef SECURITY_FLAG_IGNORE_UNKNOWN_CA
#define SECURITY_FLAG_IGNORE_UNKNOWN_CA 0x00000100
#endif
#ifndef SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE
#define SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE 0x00000200
#endif
#ifndef SECURITY_FLAG_IGNORE_CERT_CN_INVALID
#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID 0x00001000
#endif
#ifndef SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID 0x00002000
#endif
#pragma comment(lib, "winhttp.lib")
#pragma comment(lib, "crypt32.lib")
#pragma comment(lib, "advapi32.lib")
#include <iostream>
#include <Windows.h>
#include <TlHelp32.h>
#include <vector>
#include <string>
#include <iomanip>
#include <codecvt>
#include <locale>
#include <winhttp.h>
#include <wincrypt.h>
#include <sstream>
#include <intrin.h>
#include "json.hpp"
#include <conio.h>
using json = nlohmann::json;
using namespace std;
using std::wstring_convert;
using std::codecvt_utf8;
void SetColor(int color);
void ClearScreen();
void PrintHeader();
struct UserData {
bool isLoggedIn = false;
string username;
int subscriptionDays = 0;
};
UserData currentUser;
struct ProcessInfo {
DWORD pid;
wstring name;
};
DWORD g_currentPID = 0;
HANDLE g_currentModule = NULL;
string GetHWID() {
string result;
int cpuInfo[4] = { 0 };
__cpuid(cpuInfo, 0);
char motherboardInfo[1024] = { 0 };
DWORD size = sizeof(motherboardInfo);
GetSystemFirmwareTable('RSMB', 0, motherboardInfo, size);
stringstream ss;
ss << hex << uppercase
<< setfill('0') << setw(8) << cpuInfo[0]
<< setfill('0') << setw(8) << cpuInfo[1]
<< setfill('0') << setw(8) << cpuInfo[2]
<< setfill('0') << setw(8) << cpuInfo[3];
HCRYPTPROV hProv = 0;
HCRYPTHASH hHash = 0;
if (CryptAcquireContext(&hProv, NULL, NULL, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) {
if (CryptCreateHash(hProv, CALG_SHA_256, 0, 0, &hHash)) {
string data = ss.str();
if (CryptHashData(hHash, (BYTE*)data.c_str(), data.length(), 0)) {
BYTE hash[32];
DWORD hashLen = 32;
if (CryptGetHashParam(hHash, HP_HASHVAL, hash, &hashLen, 0)) {
stringstream hashStr;
for (int i = 0; i < 32; i++) {
hashStr << hex << setw(2) << setfill('0') << (int)hash[i];
}
result = hashStr.str();
}
}
CryptDestroyHash(hHash);
}
CryptReleaseContext(hProv, 0);
}
return result;
}
std::string WideStringToUTF8(const std::wstring& wstr) {
if (wstr.empty()) return std::string();
int size_needed = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.length(),
nullptr, 0, nullptr, nullptr);
std::string strTo(size_needed, 0);
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), (int)wstr.length(),
&strTo[0], size_needed, nullptr, nullptr);
return strTo;
}
string PrepareJsonData(const wstring& username, const wstring& password, const wstring& hwid) {
string usernameStr = WideStringToUTF8(username);
string passwordStr = WideStringToUTF8(password);
string hwidStr = WideStringToUTF8(hwid);
auto escapeJson = [](string str) {
string result;
for (char c : str) {
switch (c) {
case '"': result += "\\\""; break;
case '\\': result += "\\\\"; break;
case '\b': result += "\\b"; break;
case '\f': result += "\\f"; break;
case '\n': result += "\\n"; break;
case '\r': result += "\\r"; break;
case '\t': result += "\\t"; break;
default:
if ('\x00' <= c && c <= '\x1f') {
char buf[8];
snprintf(buf, sizeof(buf), "\\u%04x", c);
result += buf;
}
else {
result += c;
}
}
}
return result;
};
string jsonData = "{";
jsonData += "\"action\":\"login\",";
jsonData += "\"username\":\"" + escapeJson(usernameStr) + "\",";
jsonData += "\"password\":\"" + escapeJson(passwordStr) + "\",";
jsonData += "\"hwid\":\"" + escapeJson(hwidStr) + "\"";
jsonData += "}";
return jsonData;
}
bool SendApiRequest(const wstring& endpoint, const string& data, string& response) {
HINTERNET hSession = NULL;
HINTERNET hConnect = NULL;
HINTERNET hRequest = NULL;
bool success = false;
try {
hSession = WinHttpOpen(
L"Jelector/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0
);
if (!hSession) throw runtime_error("WinHttpOpen failed");
DWORD timeout = 30000;
WinHttpSetOption(hSession, WINHTTP_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
WinHttpSetOption(hSession, WINHTTP_OPTION_SEND_TIMEOUT, &timeout, sizeof(timeout));
WinHttpSetOption(hSession, WINHTTP_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
hConnect = WinHttpConnect(
hSession,
L"(ваш сайт на котором будут пхп файлы)",
INTERNET_DEFAULT_HTTPS_PORT,
0
);
if (!hConnect) throw runtime_error("WinHttpConnect failed");
hRequest = WinHttpOpenRequest(
hConnect,
L"POST",
L"/Jelector/api.php",
NULL,
WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
WINHTTP_FLAG_SECURE
);
if (!hRequest) throw runtime_error("WinHttpOpenRequest failed");
wstring headers = L"Content-Type: application/json\r\n"
L"Accept: application/json\r\n"
L"User-Agent: Jelector/1.0\r\n";
DWORD dwFlags = SECURITY_FLAG_IGNORE_UNKNOWN_CA |
SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE |
SECURITY_FLAG_IGNORE_CERT_CN_INVALID |
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID;
WinHttpSetOption(hRequest, WINHTTP_OPTION_SECURITY_FLAGS, &dwFlags, sizeof(dwFlags));
if (!WinHttpSendRequest(
hRequest,
headers.c_str(),
-1L,
(LPVOID)data.c_str(),
data.length(),
data.length(),
0
)) throw runtime_error("WinHttpSendRequest failed");
if (!WinHttpReceiveResponse(hRequest, NULL))
throw runtime_error("WinHttpReceiveResponse failed");
DWORD statusCode = 0;
DWORD statusCodeSize = sizeof(DWORD);
WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER,
NULL,
&statusCode,
&statusCodeSize,
NULL);
if (statusCode != 200)
throw runtime_error("HTTP Error: " + to_string(statusCode));
response.clear();
vector<char> buffer;
DWORD dwSize = 0;
DWORD dwDownloaded = 0;
do {
dwSize = 0;
if (!WinHttpQueryDataAvailable(hRequest, &dwSize)) break;
if (dwSize == 0) break;
buffer.resize(dwSize + 1);
if (!WinHttpReadData(hRequest, &buffer[0], dwSize, &dwDownloaded)) break;
buffer[dwDownloaded] = '\0';
response.append(buffer.data(), dwDownloaded);
} while (dwSize > 0);
success = true;
}
catch (const exception& e) {
SetColor(12);
cout << "\nОшибка: " << e.what() << endl;
SetColor(7);
}
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
return success;
}
bool Login(const string& username, const string& password) {
if (username.empty() || password.empty()) {
SetColor(12);
cout << "\nОшибка: Логин и пароль не могут быть пустыми!\n";
SetColor(7);
return false;
}
string hwid = GetHWID();
json requestData = {
{"action", "login"},
{"username", username},
{"password", password},
{"hwid", hwid},
{"app", "Jelector"},
{"version", "1.0"}
};
string jsonStr = requestData.dump();
string response;
if (!SendApiRequest(L"/Jelector/api.php", jsonStr, response)) {
SetColor(12);
cout << "\nОшибка при отправке запроса!\n";
SetColor(7);
return false;
}
try {
json responseJson = json::parse(response);
if (responseJson.contains("success") && responseJson["success"].get<bool>()) {
currentUser.isLoggedIn = true;
currentUser.username = username;
if (responseJson.contains("subscription_days")) {
currentUser.subscriptionDays = responseJson["subscription_days"].get<int>();
if (currentUser.subscriptionDays <= 0) {
ClearScreen();
PrintHeader();
SetColor(12);
cout << "\n[!] У вас отсутствует активная подписка!" << endl;
cout << "[!] Для использования программы необходимо приобрести подписку." << endl;
cout << "\n[!] Программа будет закрыта через 3 секунды..." << endl;
SetColor(7);
Sleep(3000);
exit(0);
}
}
SetColor(10);
cout << "\nУспешная авторизация!\n";
if (currentUser.subscriptionDays > 0) {
cout << "Дней подписки осталось: " << currentUser.subscriptionDays << "\n";
}
SetColor(7);
return true;
}
else {
string errorMessage = responseJson.contains("message") ?
responseJson["message"].get<string>() : "Неизвестная ошибка";
SetColor(12);
cout << "\nОшибка: " << errorMessage << "\n";
SetColor(7);
return false;
}
}
catch (const json::parse_error& e) {
SetColor(12);
cout << "\nОшибка обработки ответа: " << e.what() << "\n";
SetColor(7);
return false;
}
}
bool SendLoginRequest(const string& username, const string& password) {
string hwid = GetHWID();
json requestData = {
{"action", "login"},
{"username", username},
{"password", password},
{"hwid", hwid}
};
string jsonStr = requestData.dump();
string response;
if (!SendApiRequest(L"/api.php", jsonStr, response)) {
return false;
}
try {
json responseJson = json::parse(response);
if (responseJson["success"].get<bool>()) {
currentUser.isLoggedIn = true;
currentUser.username = username;
if (responseJson.contains("subscription_days")) {
currentUser.subscriptionDays = responseJson["subscription_days"].get<int>();
}
return true;
}
return false;
}
catch (const json::parse_error& e) {
cout << "Ошибка парсинга ответа: " << e.what() << endl;
return false;
}
}
bool SendRegisterRequest(const string& username, const string& password) {
string hwid = GetHWID();
json requestData = {
{"action", "register"},
{"username", username},
{"password", password},
{"hwid", hwid}
};
string jsonStr = requestData.dump();
string response;
if (!SendApiRequest(L"/api.php", jsonStr, response)) {
return false;
}
try {
json responseJson = json::parse(response);
return responseJson["success"].get<bool>();
}
catch (const json::parse_error& e) {
cout << "Ошибка парсинга ответа: " << e.what() << endl;
return false;
}
}
bool CheckSubscription() {
if (!currentUser.isLoggedIn) return false;
string hwid = GetHWID();
json requestData = {
{"action", "check_subscription"},
{"username", currentUser.username},
{"hwid", hwid}
};
string jsonStr = requestData.dump();
string response;
if (!SendApiRequest(L"/api.php", jsonStr, response)) {
return false;
}
try {
json responseJson = json::parse(response);
if (responseJson["success"].get<bool>()) {
currentUser.subscriptionDays = responseJson["subscription_days"].get<int>();
return true;
}
return false;
}
catch (const json::parse_error& e) {
cout << "Ошибка парсинга ответа: " << e.what() << endl;
return false;
}
}
bool Register(const string& username, const string& password) {
if (username.empty() || password.empty()) {
SetColor(12);
cout << "\nОшибка: Логин и пароль не могут быть пустыми!\n";
SetColor(7);
return false;
}
if (SendRegisterRequest(username, password)) {
SetColor(10);
cout << "\nРегистрация успешна!\n";
SetColor(7);
return true;
}
else {
SetColor(12);
cout << "\nОшибка регистрации!\n";
SetColor(7);
return false;
}
}
void SetColor(int color) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
void ClearScreen() {
system("cls");
}
void PrintHeader() {
SetColor(11);
cout << R"(
╔══════════════════════════════════════════════╗
║ Traced DLL Injector v1.0 ║
║ Created by Traced ║
╚══════════════════════════════════════════════╝
)" << endl;
SetColor(7);
}
vector<ProcessInfo> GetProcessList() {
vector<ProcessInfo> processes;
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (snapshot != INVALID_HANDLE_VALUE) {
PROCESSENTRY32W processEntry;
processEntry.dwSize = sizeof(processEntry);
if (Process32FirstW(snapshot, &processEntry)) {
do {
ProcessInfo pi;
pi.pid = processEntry.th32ProcessID;
pi.name = processEntry.szExeFile;
processes.push_back(pi);
} while (Process32NextW(snapshot, &processEntry));
}
CloseHandle(snapshot);
}
return processes;
}
bool InjectDLL(DWORD processId, const wchar_t* dllPath) {
if (!currentUser.isLoggedIn || currentUser.subscriptionDays <= 0) {
SetColor(12);
cout << "\nОшибка: Нет активной подписки!\n";
SetColor(7);
return false;
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if (!hProcess) return false;
size_t pathSize = (wcslen(dllPath) + 1) * sizeof(wchar_t);
LPVOID dllPathAddr = VirtualAllocEx(hProcess, NULL, pathSize,
MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!dllPathAddr) {
CloseHandle(hProcess);
return false;
}
if (!WriteProcessMemory(hProcess, dllPathAddr, dllPath, pathSize, NULL)) {
VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
LPVOID loadLibraryAddr = GetProcAddress(hKernel32, "LoadLibraryW");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)loadLibraryAddr, dllPathAddr, 0, NULL);
if (!hThread) {
VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
WaitForSingleObject(hThread, INFINITE);
DWORD exitCode;
GetExitCodeThread(hThread, &exitCode);
g_currentModule = (HANDLE)exitCode;
g_currentPID = processId;
VirtualFreeEx(hProcess, dllPathAddr, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
return true;
}
bool EjectDLL() {
if (!g_currentPID || !g_currentModule) {
return false;
}
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, g_currentPID);
if (!hProcess) {
return false;
}
HMODULE hKernel32 = GetModuleHandleW(L"kernel32.dll");
LPVOID freeLibraryAddr = GetProcAddress(hKernel32, "FreeLibrary");
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0,
(LPTHREAD_START_ROUTINE)freeLibraryAddr, g_currentModule, 0, NULL);
if (!hThread) {
CloseHandle(hProcess);
return false;
}
WaitForSingleObject(hThread, INFINITE);
CloseHandle(hThread);
CloseHandle(hProcess);
g_currentPID = 0;
g_currentModule = NULL;
return true;
}
void ShowLoginMenu() {
while (!currentUser.isLoggedIn) {
ClearScreen();
PrintHeader();
SetColor(14);
cout << "\n Авторизация:\n\n";
SetColor(7);
cout << " [1] Войти\n";
cout << " [2] Регистрация\n";
cout << " [3] Выход\n\n";
SetColor(14);
cout << " Выбор: ";
SetColor(7);
char choice;
cin >> choice;
switch (choice) {
case '1': {
cout << "\n Введите имя пользователя: ";
string username;
cin >> username;
cout << " Введите пароль: ";
string password;
cin >> password;
if (Login(username, password)) {
SetColor(10);
cout << "\n Успешный вход! Дней подписки: " << currentUser.subscriptionDays << "\n";
SetColor(7);
system("pause");
return;
}
else {
SetColor(12);
cout << "\n Ошибка входа!\n";
SetColor(7);
system("pause");
}
break;
}
case '2': {
cout << "\n Введите новое имя пользователя: ";
string username;
cin >> username;
cout << " Введите новый пароль: ";
string password;
cin >> password;
if (Register(username, password)) {
SetColor(10);
cout << "\n Регистрация успешна!\n";
SetColor(7);
system("pause");
}
else {
SetColor(12);
cout << "\n Ошибка регистрации!\n";
SetColor(7);
system("pause");
}
break;
}
case '3':
exit(0);
}
}
}
void ShowMainMenu() {
while (true) {
if (!currentUser.isLoggedIn) {
ShowLoginMenu();
continue;
}
ClearScreen();
PrintHeader();
SetColor(14);
cout << "\n Пользователь: " << currentUser.username
<< " | Дней подписки: " << currentUser.subscriptionDays << "\n\n";
cout << " Выберите действие:\n\n";
SetColor(7);
cout << " [1] Выбрать процесс\n";
cout << " [2] Указать путь к DLL\n";
cout << " [3] Инжект DLL\n";
cout << " [4] Выгрузить DLL\n";
cout << " [5] Выход\n\n";
SetColor(11);
cout << " Текущий процесс: ";
SetColor(7);
cout << (g_currentPID ? to_string(g_currentPID) : "Не выбран") << "\n";
SetColor(14);
cout << "\n Выбор: ";
SetColor(7);
static wstring dllPath;
char choice;
cin >> choice;
switch (choice) {
case '1': {
ClearScreen();
PrintHeader();
auto processes = GetProcessList();
cout << "\n Доступные процессы:\n\n";
int index = 1;
for (const auto& proc : processes) {
cout << " [" << index++ << "] " << setw(30) << left
<< wstring_convert<codecvt_utf8<wchar_t>>().to_bytes(proc.name)
<< " (PID: " << proc.pid << ")\n";
}
cout << "\n Выберите номер процесса (0 для возврата): ";
int procChoice;
cin >> procChoice;
if (procChoice > 0 && procChoice <= processes.size()) {
g_currentPID = processes[procChoice - 1].pid;
}
break;
}
case '2': {
cout << "\n Введите полный путь к DLL: ";
wcin.ignore();
getline(wcin, dllPath);
break;
}
case '3': {
if (!currentUser.isLoggedIn || currentUser.subscriptionDays <= 0) {
SetColor(12);
cout << "\n Ошибка: Нет активной подписки!\n";
SetColor(7);
system("pause");
break;
}
if (g_currentPID && !dllPath.empty()) {
if (InjectDLL(g_currentPID, dllPath.c_str())) {
SetColor(10);
cout << "\n DLL успешно инжектирована!\n";
}
else {
SetColor(12);
cout << "\n Ошибка при инжекте!\n";
}
SetColor(7);
system("pause");
}
else {
SetColor(12);
cout << "\n Сначала выберите процесс и укажите путь к DLL!\n";
SetColor(7);
system("pause");
}
break;
}
case '4': {
if (g_currentPID && g_currentModule) {
if (EjectDLL()) {
SetColor(10);
cout << "\n DLL успешно выгружена!\n";
}
else {
SetColor(12);
cout << "\n Ошибка при выгрузке DLL!\n";
}
SetColor(7);
system("pause");
}
else {
SetColor(12);
cout << "\n Нет активного инжекта!\n";
SetColor(7);
system("pause");
}
break;
}
case '5': {
currentUser.isLoggedIn = false;
return;
}
}
}
}
int main() {
try {
setlocale(LC_ALL, "Russian");
SetConsoleCP(1251);
SetConsoleOutputCP(1251);
BOOL isElevated = FALSE;
HANDLE hToken = NULL;
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) {
throw runtime_error("Ошибка получения токена процесса");
}
TOKEN_ELEVATION elevation;
DWORD size = sizeof(TOKEN_ELEVATION);
if (!GetTokenInformation(hToken, TokenElevation, &elevation, sizeof(elevation), &size)) {
CloseHandle(hToken);
throw runtime_error("Ошибка получения информации о токене");
}
isElevated = elevation.TokenIsElevated;
CloseHandle(hToken);
if (!isElevated) {
SetColor(12);
cout << "\n ОШИБКА: Требуются права администратора!\n";
SetColor(7);
system("pause");
return 1;
}
while (true) {
ShowMainMenu();
if (!currentUser.isLoggedIn) {
ShowLoginMenu();
}
}
}
catch (const exception& e) {
SetColor(12);
cout << "\nКритическая ошибка: " << e.what() << endl;
SetColor(7);
system("pause");
return 1;
}
return 0;
}
PHP файлы
database.php:
<?php
class Database {
private $conn;
public function __construct() {
try {
$this->conn = new PDO(
"mysql:host=" . DB_HOST . ";dbname=" . DB_NAME,
DB_USER,
DB_PASS,
[
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => false
]
);
$this->createTable();
} catch(PDOException $e) {
throw new Exception('Database connection error');
}
}
private function createTable() {
$this->conn->exec("
CREATE TABLE IF NOT EXISTS users (
id INT AUTO_INCREMENT PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password VARCHAR(255) NOT NULL,
hwid VARCHAR(64),
subscription_days INT DEFAULT 0,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
last_login TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
");
}
private function isHwidRegistered($hwid) {
$stmt = $this->conn->prepare("SELECT COUNT(*) FROM users WHERE hwid = :hwid");
$stmt->execute([':hwid' => $hwid]);
return $stmt->fetchColumn() > 0;
}
private function isValidEmail($email) {
return filter_var($email, FILTER_VALIDATE_EMAIL);
}
public function register($username, $password, $hwid) {
try {
if (strlen($hwid) !== 64) {
return ['success' => false, 'message' => 'Неверный формат HWID'];
}
if ($this->isHwidRegistered($hwid)) {
return ['success' => false, 'message' => 'На этом компьютере уже зарегистрирован аккаунт'];
}
$hashedPassword = password_hash($password, PASSWORD_DEFAULT);
$stmt = $this->conn->prepare("
INSERT INTO users (username, password, hwid)
VALUES (:username, :password, :hwid)
");
$stmt->execute([
':username' => $username,
':password' => $hashedPassword,
':hwid' => $hwid
]);
return ['success' => true, 'message' => 'Регистрация успешно завершена'];
} catch(PDOException $e) {
if ($e->getCode() == 23000) { // Код ошибки дубликата
return ['success' => false, 'message' => 'Пользователь с таким именем уже существует'];
}
return ['success' => false, 'message' => 'Ошибка при регистрации'];
}
}
public function login($username, $password, $hwid) {
try {
$stmt = $this->conn->prepare("
SELECT id, password, hwid, subscription_days
FROM users
WHERE username = :username
");
$stmt->execute([':username' => $username]);
$user = $stmt->fetch(PDO::FETCH_ASSOC);
if ($user && password_verify($password, $user['password'])) {
if ($user['hwid'] && $user['hwid'] !== $hwid) {
return [
'success' => false,
'message' => 'HWID mismatch'
];
}
if (!$user['hwid']) {
$stmt = $this->conn->prepare("
UPDATE users
SET hwid = :hwid, last_login = CURRENT_TIMESTAMP
WHERE id = :id
");
$stmt->execute([
':hwid' => $hwid,
':id' => $user['id']
]);
}
return [
'success' => true,
'message' => 'Login successful',
'subscription_days' => $user['subscription_days']
];
}
return ['success' => false, 'message' => 'Invalid credentials'];
} catch(PDOException $e) {
return ['success' => false, 'message' => 'Login error'];
}
}
}
api.php:
<?php
if (!isset($_SERVER['HTTPS']) || $_SERVER['HTTPS'] !== 'on') {
header("Location: https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit();
}
error_reporting(0);
header('Content-Type: application/json; charset=utf-8');
header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, OPTIONS');
header('Access-Control-Allow-Headers: Content-Type');
// Обработка preflight запросов
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
http_response_code(200);
exit();
}
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
echo json_encode([
'success' => false,
'message' => 'Only POST method is allowed'
]);
exit();
}
// Подключаем конфигурацию и класс базы данных
require_once 'config.php';
require_once 'database.php';
$json = file_get_contents('php://input');
$data = json_decode($json, true);
function logError($error, $data = null) {
$logFile = 'api_errors.log';
$timestamp = date('Y-m-d H:i:s');
$logMessage = "[{$timestamp}] {$error}\n";
if ($data) {
$logMessage .= "Data: " . print_r($data, true) . "\n";
}
file_put_contents($logFile, $logMessage, FILE_APPEND);
}
if (json_last_error() !== JSON_ERROR_NONE) {
$error = 'JSON Error: ' . json_last_error_msg();
logError($error, $json);
echo json_encode([
'success' => false,
'message' => $error,
'received_data' => $json
]);
exit;
}
if (!isset($data['action'])) {
echo json_encode([
'success' => false,
'message' => 'Missing action parameter'
]);
exit;
}
try {
$db = new Database();
} catch (Exception $e) {
logError('Database initialization error: ' . $e->getMessage());
echo json_encode([
'success' => false,
'message' => 'Database initialization error'
]);
exit;
}
function validateInput($data) {
if (empty($data)) return false;
return htmlspecialchars(strip_tags(trim($data)));
}
switch ($data['action']) {
case 'login':
if (!isset($data['username']) || !isset($data['password']) || !isset($data['hwid'])) {
echo json_encode([
'success' => false,
'message' => 'Missing required parameters'
]);
exit;
}
$username = validateInput($data['username']);
$password = validateInput($data['password']);
$hwid = validateInput($data['hwid']);
if (!$username || !$password || !$hwid) {
echo json_encode([
'success' => false,
'message' => 'Invalid input data'
]);
exit;
}
$result = $db->login($username, $password, $hwid);
if (!$result['success']) {
logError('Failed login attempt', [
'username' => $username,
'ip' => $_SERVER['REMOTE_ADDR'],
'reason' => $result['message']
]);
}
echo json_encode($result);
break;
case 'register':
if (!isset($data['username']) || !isset($data['password']) || !isset($data['hwid'])) {
echo json_encode([
'success' => false,
'message' => 'Missing required parameters'
]);
exit;
}
$username = validateInput($data['username']);
$password = validateInput($data['password']);
$hwid = validateInput($data['hwid']);
if (!$username || !$password || !$hwid) {
echo json_encode([
'success' => false,
'message' => 'Invalid input data'
]);
exit;
}
if (strlen($username) < 3 || strlen($username) > 20) {
echo json_encode([
'success' => false,
'message' => 'Username must be between 3 and 20 characters'
]);
exit;
}
if (strlen($password) < 6) {
echo json_encode([
'success' => false,
'message' => 'Password must be at least 6 characters'
]);
exit;
}
$result = $db->register($username, $password, $hwid);
if (!$result['success']) {
logError('Failed registration attempt', [
'username' => $username,
'ip' => $_SERVER['REMOTE_ADDR'],
'reason' => $result['message']
]);
}
echo json_encode($result);
break;
case 'check_subscription':
if (!isset($data['username']) || !isset($data['hwid'])) {
echo json_encode([
'success' => false,
'message' => 'Missing required parameters'
]);
exit;
}
$username = validateInput($data['username']);
$hwid = validateInput($data['hwid']);
if (!$username || !$hwid) {
echo json_encode([
'success' => false,
'message' => 'Invalid input data'
]);
exit;
}
$result = $db->checkSubscription($username, $hwid);
echo json_encode($result);
break;
case 'update_subscription':
if (!isset($data['username']) || !isset($data['days'])) {
echo json_encode([
'success' => false,
'message' => 'Missing required parameters'
]);
exit;
}
$username = validateInput($data['username']);
$days = intval($data['days']);
if (!$username || $days <= 0) {
echo json_encode([
'success' => false,
'message' => 'Invalid input data'
]);
exit;
}
$result = $db->updateSubscription($username, $days);
echo json_encode($result);
break;
default:
echo json_encode([
'success' => false,
'message' => 'Unknown action'
]);
}
?>
config.php:
<?php
define('DB_HOST', '');
define('DB_NAME', '');
define('DB_USER', '');
define('DB_PASS', '');
?>