EFTCheatPVE/operator/operator.cpp

526 lines
No EOL
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <windows.h>
#include <shellapi.h>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <thread>
#include <regex>
#include <tlhelp32.h>
#include <shlwapi.h>
#pragma comment(lib, "shlwapi.lib")
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, * PUNICODE_STRING;
typedef struct _RTL_USER_PROCESS_PARAMETERS {
BYTE Reserved1[16];
PVOID Reserved2[10];
UNICODE_STRING ImagePathName;
UNICODE_STRING CommandLine;
} RTL_USER_PROCESS_PARAMETERS, * PRTL_USER_PROCESS_PARAMETERS;
typedef struct _PEB {
BYTE Reserved1[2];
BYTE BeingDebugged;
BYTE Reserved2[1];
PVOID Reserved3[2];
PVOID Ldr;
PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
} PEB, * PPEB;
typedef struct _PROCESS_BASIC_INFORMATION {
PVOID Reserved1;
PPEB PebBaseAddress;
PVOID Reserved2[2];
ULONG_PTR UniqueProcessId;
PVOID Reserved3;
} PROCESS_BASIC_INFORMATION;
// ProcessBasicInformation = 0
#ifndef ProcessBasicInformation
#define ProcessBasicInformation 0
#endif
std::wstring GetCommandLine(DWORD pid)
{
std::wstring result;
HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ, FALSE, pid);
if (!hProcess) return result;
// Load ntdll
auto ntdll = GetModuleHandleA("ntdll.dll");
auto NtQueryInformationProcess = (LONG(WINAPI*)(HANDLE, int, PVOID, ULONG, PULONG))GetProcAddress(ntdll, "NtQueryInformationProcess");
if (!NtQueryInformationProcess) {
CloseHandle(hProcess);
return result;
}
PROCESS_BASIC_INFORMATION pbi{};
ULONG len;
if (NtQueryInformationProcess(hProcess, 0, &pbi, sizeof(pbi), &len) == 0)
{
PEB peb{};
RTL_USER_PROCESS_PARAMETERS upp{};
if (ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(peb), nullptr))
{
if (ReadProcessMemory(hProcess, peb.ProcessParameters, &upp, sizeof(upp), nullptr))
{
wchar_t* buffer = new wchar_t[8192];
if (ReadProcessMemory(hProcess, upp.CommandLine.Buffer, buffer, upp.CommandLine.Length, nullptr))
{
result = std::wstring(buffer, upp.CommandLine.Length / sizeof(wchar_t));
}
delete[] buffer;
}
}
}
CloseHandle(hProcess);
return result;
}
std::string GetExeDirectory()
{
wchar_t path[MAX_PATH] = { 0 };
GetModuleFileNameW(nullptr, path, MAX_PATH);
std::wstring wpath(path);
size_t pos = wpath.rfind(L'\\');
if (pos != std::wstring::npos) {
wpath.resize(pos + 1);
}
else {
wpath.clear();
}
int size = WideCharToMultiByte(CP_UTF8, 0, wpath.c_str(), -1, nullptr, 0, nullptr, nullptr);
std::string result(size - 1, 0);
WideCharToMultiByte(CP_UTF8, 0, wpath.c_str(), -1, result.data(), size, nullptr, nullptr);
return result;
}
static std::wstring Utf8ToW(const std::string& s)
{
if (s.empty()) return {};
int n = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, nullptr, 0);
if (n == 0) return {};
std::wstring w(n - 1, L'\0');
MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, w.data(), n);
return w;
}
bool isProcessRunning(const std::string& processName) {
std::string command = "tasklist | findstr " + processName;
FILE* pipe = _popen(command.c_str(), "r");
if (!pipe) {
std::cerr << "Failed to run command\n";
return false;
}
char buffer[128];
bool found = false;
while (fgets(buffer, sizeof(buffer), pipe)) {
if (strstr(buffer, processName.c_str())) {
found = true;
break;
}
}
_pclose(pipe);
return found;
}
BOOL IsRunAsAdministrator()
{
BOOL fIsRunAsAdmin = FALSE;
PSID pAdministratorsGroup = NULL;
SID_IDENTIFIER_AUTHORITY NtAuthority = SECURITY_NT_AUTHORITY;
if (!AllocateAndInitializeSid(&NtAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorsGroup))
{
return FALSE;
}
if (!CheckTokenMembership(NULL, pAdministratorsGroup, &fIsRunAsAdmin))
{
FreeSid(pAdministratorsGroup);
return FALSE;
}
FreeSid(pAdministratorsGroup);
return fIsRunAsAdmin;
}
BOOL ElevateNow()
{
if (IsRunAsAdministrator())
return true;
WCHAR szPath[MAX_PATH];
if (!GetModuleFileName(NULL, szPath, ARRAYSIZE(szPath)))
return false;
SHELLEXECUTEINFO sei = { sizeof(sei) };
sei.lpVerb = L"runas";
sei.lpFile = szPath;
sei.hwnd = NULL;
sei.nShow = SW_SHOWDEFAULT;
if (ShellExecuteEx(&sei))
exit(1);
DWORD dwError = GetLastError();
if (dwError == ERROR_CANCELLED)
return false;
return true;
}
static bool WaitForServiceDeletion(SC_HANDLE scm, const std::wstring& svcName, DWORD timeoutMs = 10000)
{
const DWORD interval = 500;
DWORD waited = 0;
std::cout << "Waiting for service deletion";
while (waited < timeoutMs) {
std::cout << ".";
SC_HANDLE h = OpenServiceW(scm, svcName.c_str(), SERVICE_QUERY_STATUS);
if (!h) {
DWORD err = GetLastError();
if (err == ERROR_SERVICE_DOES_NOT_EXIST)
return true;
}
else {
CloseServiceHandle(h);
}
Sleep(interval);
waited += interval;
}
std::cout << std::endl;
return false;
}
void verifyServiceDeletion(const std::wstring& svcName)
{
SC_HANDLE scm = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
if (!scm) {
std::cerr << "OpenSCManager failed: " << GetLastError() << std::endl;
exit(-1);
}
SC_HANDLE hExisting = OpenServiceW(scm, svcName.c_str(), SERVICE_STOP | DELETE | SERVICE_QUERY_STATUS | SERVICE_ENUMERATE_DEPENDENTS);
if (!hExisting)
return;
SERVICE_STATUS status{};
if (ControlService(hExisting, SERVICE_CONTROL_STOP, &status)) {
long long start = GetTickCount64();
std::cout << "Waiting for BEService to stop";
while (status.dwCurrentState != SERVICE_STOPPED && GetTickCount64() - start < 10000) {
Sleep(500);
std::cout << ".";
if (!QueryServiceStatus(hExisting, &status)) break;
}
std::cout << std::endl;
}
if (!DeleteService(hExisting)) {
DWORD err = GetLastError();
std::cerr << "DeleteService failed: " << err << std::endl;
}
CloseServiceHandle(hExisting);
if (!WaitForServiceDeletion(scm, svcName, 10000)) {
std::cerr << "Service still marked for deletion after waiting. Error 1072 may occur if you try to recreate it immediately.\n";
CloseServiceHandle(scm);
exit(-2);
}
}
BOOL InjectDLL(DWORD processId, const char* dllPath)
{
HANDLE hProcess = OpenProcess(
PROCESS_QUERY_INFORMATION | PROCESS_CREATE_THREAD |
PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ,
FALSE, processId);
if (!hProcess) {
std::cout << "[-] OpenProcess failed: " << GetLastError() << std::endl;
return FALSE;
}
SIZE_T pathLen = strlen(dllPath) + 1;
LPVOID remoteMem = VirtualAllocEx(hProcess, nullptr, pathLen, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
if (!remoteMem) {
std::cout << "[-] VirtualAllocEx failed: " << GetLastError() << std::endl;
CloseHandle(hProcess);
return FALSE;
}
if (!WriteProcessMemory(hProcess, remoteMem, dllPath, pathLen, nullptr)) {
std::cout << "[-] WriteProcessMemory failed: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return FALSE;
}
HMODULE hKernel32 = GetModuleHandleA("kernel32.dll");
if (!hKernel32) {
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return FALSE;
}
LPTHREAD_START_ROUTINE pLoadLibrary = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA");
HANDLE hThread = CreateRemoteThread(hProcess, nullptr, 0, pLoadLibrary, remoteMem, 0, nullptr);
if (!hThread) {
std::cout << "[-] CreateRemoteThread failed: " << GetLastError() << std::endl;
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
return FALSE;
}
WaitForSingleObject(hThread, 10000);
DWORD exitCode = 0;
GetExitCodeThread(hThread, &exitCode);
CloseHandle(hThread);
VirtualFreeEx(hProcess, remoteMem, 0, MEM_RELEASE);
CloseHandle(hProcess);
if (exitCode != 0) {
std::cout << "[+] Injected successfully! (hModule = 0x"
<< std::hex << exitCode << std::dec << ")\n";
return TRUE;
}
std::cout << "[-] LoadLibraryA returned NULL in target process\n";
return FALSE;
}
BOOL StealAndKillBE(std::wstring& outCmdLine, DWORD& outPid)
{
HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hSnap == INVALID_HANDLE_VALUE) return false;
PROCESSENTRY32 pe{ .dwSize = sizeof(pe) };
bool found = false;
if (!Process32First(hSnap, &pe))
goto not_found;
do {
if (_wcsicmp(pe.szExeFile, L"EscapeFromTarkov_BE.exe") != 0)
continue;
std::cout << std::endl;
found = true;
outPid = pe.th32ProcessID;
std::wcout << L"[+] Found BE process (PID: " << outPid << L") - Stealing command line...\n";
// 1. STEAL COMMAND LINE FIRST
outCmdLine = GetCommandLine(outPid);
if (outCmdLine.empty()) {
std::wcout << L"[-] Failed to read command line from PID " << outPid << L"\n";
continue; // try next instance
}
std::wcout << L"[+] Command line stolen successfully!\n";
// 2. NOW KILL IT
HANDLE hProc = OpenProcess(PROCESS_TERMINATE, FALSE, outPid);
if (hProc) {
TerminateProcess(hProc, 0);
CloseHandle(hProc);
std::cout << "[+] BE process terminated.\n";
}
// Don't break — kill ALL BE instances (in case of multiple)
} while (Process32Next(hSnap, &pe));
not_found:
CloseHandle(hSnap);
return found && !outCmdLine.empty();
}
BOOL Battleyent()
{
std::wstring stolenCmdLine;
DWORD bePid = 0;
// ── 1. Wait for BE and steal command line ───────────────────────
std::cout << "[.] Waiting for EscapeFromTarkov_BE.exe to appear";
while (!StealAndKillBE(stolenCmdLine, bePid))
{
std::cout << ".";
std::this_thread::sleep_for(std::chrono::seconds(1));
}
// ── 2. Replace BE executable with clean one ───────────────────
std::wstring cleanCmdLine = std::regex_replace(
stolenCmdLine,
std::wregex(L"EscapeFromTarkov_BE\\.exe", std::regex_constants::icase),
L"EscapeFromTarkov.exe");
// ── 3. Extract real executable path (remove quotes if any) ─────
std::wsmatch match;
std::wstring exeFullPath;
if (std::regex_search(cleanCmdLine, match, std::wregex(L"\"([^\"]+)\"")))
{
exeFullPath = match[1].str();
cleanCmdLine = std::regex_replace(cleanCmdLine,
std::wregex(L"\"[^\"]+\""),
exeFullPath,
std::regex_constants::format_first_only);
}
else if (cleanCmdLine.find(L' ') != std::wstring::npos)
{
exeFullPath = cleanCmdLine.substr(0, cleanCmdLine.find(L' '));
}
else
{
exeFullPath = cleanCmdLine;
}
// ── 4. Build correct working directory ───────────────────────
const std::wstring gameWorkingDir = exeFullPath.substr(0, exeFullPath.find_last_of(L"\\/"));
std::wcout << L"[+] Game path : " << exeFullPath << L'\n';
std::wcout << L"[+] Working directory: " << gameWorkingDir << L'\n';
std::wcout << L"[+] Final cmdline : " << cleanCmdLine << L'\n';
// ── 5. Launch the clean game (suspended) ─────────────────────
STARTUPINFOW si = { sizeof(si) };
PROCESS_INFORMATION pi = { };
const BOOL created = CreateProcessW(
nullptr,
cleanCmdLine.data(),
nullptr, nullptr,
FALSE,
CREATE_SUSPENDED, // start suspended -> safe injection
nullptr,
gameWorkingDir.c_str(), // avoid consistency crashes
&si,
&pi
);
if (!created)
{
std::cerr << "[-] CreateProcessW failed: " << GetLastError() << std::endl;
return FALSE;
}
std::cout << "[+] EscapeFromTarkov.exe launched (PID: " << pi.dwProcessId << ")\n";
// ── 6. Resume main thread ─────
ResumeThread(pi.hThread);
// ── 7. Inject our DLL ───────────────────────────────────────
const std::string dllPath = GetExeDirectory() + "\\iOperator.dll";
if (!InjectDLL(pi.dwProcessId, dllPath.c_str()))
{
std::cout << "[-] Injection failed!\n";
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return FALSE;
}
// ── 8. Success ───────────────────────────────────────────────
std::cout << "[+] iOperator.dll injected successfully!\n";
std::cout << "[+] Bootstrap done. Enjoy your raids!\n";
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
Sleep(3000);
return TRUE;
}
int main()
{
std::cout << "EFT PvE Operator for il2cpp\n\n"
<< "Credits:\nBEService bypass - rqhz\nbattleyen't for il2cpp - Suchi96\n\n"
<< "This cheat is free on UnknownCheats.me . If you payed for it, you've been scammed!\n"
<< "此作弊程序在UnknownCheats.me上免费发布。如果您付费购买此作弊程序您被骗了。请检举卖家。\n";
while (!ElevateNow())
{
std::cout << "This cheat requires administrator permissions to work. Press Enter to try again or close this window and run operator as administrator.\n";
system("pause");
}
Sleep(2000);
std::cout << "\nSetting up services.\n";
system("taskkill /f /im service.exe");
system("sc stop BEService");
system("sc delete BEService");
system("sc stop BEDaisy");
system("sc delete BEDaisy");
std::string exeDir = GetExeDirectory();
std::wstring svcName = L"BEService";
std::wstring svcDisplay = L"BattlEye Service";
std::wstring svcExePathW = Utf8ToW(exeDir) + L"service.exe";
verifyServiceDeletion(svcName);
SC_HANDLE scm = OpenSCManagerW(nullptr, nullptr, SC_MANAGER_CONNECT | SC_MANAGER_CREATE_SERVICE);
if (!scm) {
std::cerr << "OpenSCManager failed: " << GetLastError() << std::endl;
exit(-1);
}
SC_HANDLE hNew = CreateServiceW(
scm,
svcName.c_str(),
svcDisplay.c_str(),
SERVICE_ALL_ACCESS,
SERVICE_WIN32_OWN_PROCESS,
SERVICE_AUTO_START,
SERVICE_ERROR_NORMAL,
svcExePathW.c_str(),
nullptr,
nullptr,
nullptr,
nullptr,
nullptr);
if (!hNew) {
DWORD err = GetLastError();
std::cerr << "CreateServiceW failed: " << err << std::endl;
CloseServiceHandle(scm);
return -3;
}
if (!StartServiceW(hNew, 0, nullptr)) {
DWORD err = GetLastError();
if (err != ERROR_SERVICE_ALREADY_RUNNING) {
std::cerr << "StartServiceW failed: " << err << std::endl;
}
}
CloseServiceHandle(hNew);
CloseServiceHandle(scm);
std::cout << std::endl;
std::cout << "Spinning up. Launch EFT from launcher.\n";
while (!Battleyent());
std::cout << "Waiting for the game to start";
while (!isProcessRunning("EscapeFromTarkov.exe"))
{
std::cout << ".";
Sleep(500);
}
return 0;
}