Пишем инжектор:
Бери VirtualAllocEx и WriteProcessMemory — основа для выделения памяти в целевой игре и записи туда DLL.
Для запуска DLL используй CreateRemoteThread с LoadLibrary — стандартный подход.
Для усложнения детекта копай в сторону NtAllocateVirtualMemory — менее палевный, работает на уровне нативного API.
Обход VAC:
Скрывай инжектор: VAC следит за подозрительными процессами. Обфусцируй код, шифруй строки или запускай инжект через легитимные процессы (типа Discord или Steam overlay).
Manual Mapping: не используй LoadLibrary, делай ManualMap — мапишь DLL в память без регистрации в модулях процесса, VAC сложнее засечь.
Не открывай хендл напрямую: прямой доступ к процессу игры — красный флаг для VAC. Используй косвенные методы, например, хуки через легитимные библиотеки.
Серверные проверки: VAC работает не только локально, но и анализирует память на сервере. Хуки через Discord или Steam маскируют изменения.
Антиотладка: добавь в инжектор защиту от отладчиков и полиморфный код для усложнения анализа.
Пример:
#include <windows.h>
#include <iostream>
bool InjectDLL(DWORD processId, const char* dllPath) {
// Открываем процесс
HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
if (!hProcess) {
std::cout << "Failed to open process. Error: " << GetLastError() << std::endl;
return false;
}
// Аллоцируем память в процессе
LPVOID remoteMemory = VirtualAllocEx(hProcess, NULL, strlen(dllPath) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!remoteMemory) {
std::cout << "Failed to allocate memory. Error: " << GetLastError() << std::endl;
CloseHandle(hProcess);
return false;
}
// Пишем путь к DLL в память
if (!WriteProcessMemory(hProcess, remoteMemory, dllPath, strlen(dllPath) + 1, NULL)) {
std::cout << "Failed to write memory. Error: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
// Получаем адрес LoadLibraryA
LPVOID loadLibraryAddr = (LPVOID)GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
if (!loadLibraryAddr) {
std::cout << "Failed to get LoadLibraryA address. Error: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
// Создаем удаленный поток для загрузки DLL
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)loadLibraryAddr, remoteMemory, 0, NULL);
if (!hThread) {
std::cout << "Failed to create remote thread. Error: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE);
CloseHandle(hProcess);
return false;
}
// Ждем завершения потока
WaitForSingleObject(hThread, INFINITE);
// Очищаем
VirtualFreeEx(hProcess, remoteMemory, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
std::cout << "DLL injected successfully!" << std::endl;
return true;
}
int main() {
const char* dllPath = "C:\\path\\to\\your.dll"; // Путь к твоей DLL
DWORD processId = 1234; // PID целевого процесса (узнай через Process Hacker или Task Manager)
if (InjectDLL(processId, dllPath)) {
std::cout << "Injection completed." << std::endl;
} else {
std::cout << "Injection failed." << std::endl;
}
return 0;
} |