diff --git a/EFTCheatPVE1.0.sln b/EFTCheatPVE1.0.sln
index 341c447..24ee7f2 100644
--- a/EFTCheatPVE1.0.sln
+++ b/EFTCheatPVE1.0.sln
@@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 18
VisualStudioVersion = 18.0.11222.15 d18.0
MinimumVisualStudioVersion = 10.0.40219.1
-Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "battleyent", "battleyent\battleyent.vcxproj", "{E27A8A44-4579-488B-9D79-C5634C6A9650}"
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "iOperator", "ioperator\ioperator.vcxproj", "{E27A8A44-4579-488B-9D79-C5634C6A9650}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "operator", "operator\operator.vcxproj", "{74BBBA60-A5FB-4621-8389-40DCEF552CC0}"
EndProject
diff --git a/battleyent/dllmain.cpp b/ioperator/dllmain.cpp
similarity index 99%
rename from battleyent/dllmain.cpp
rename to ioperator/dllmain.cpp
index 45c0fdb..2e747af 100644
--- a/battleyent/dllmain.cpp
+++ b/ioperator/dllmain.cpp
@@ -536,6 +536,14 @@ void start()
{
printf("freopen_s failed\n");
}
+ if (freopen_s(&conout, "CONOUT$", "w", stderr) != 0)
+ {
+ printf("freopen_s failed\n");
+ }
+ if (freopen_s(&conout, "CONIN$", "r", stdin) != 0)
+ {
+ printf("freopen_s failed\n");
+ }
// 1. Wait for GameAssembly.dll to load and get IL2CPP API addresses
HMODULE il2cpp = nullptr;
diff --git a/battleyent/framework.h b/ioperator/framework.h
similarity index 100%
rename from battleyent/framework.h
rename to ioperator/framework.h
diff --git a/battleyent/battleyent.vcxproj b/ioperator/iOperator.vcxproj
similarity index 98%
rename from battleyent/battleyent.vcxproj
rename to ioperator/iOperator.vcxproj
index 29b5a0c..2f88915 100644
--- a/battleyent/battleyent.vcxproj
+++ b/ioperator/iOperator.vcxproj
@@ -24,7 +24,7 @@
{e27a8a44-4579-488b-9d79-c5634c6a9650}
battleyent
10.0
- battleyent_helper
+ iOperator
@@ -43,7 +43,7 @@
DynamicLibrary
true
- v145
+ v143
Unicode
diff --git a/battleyent/battleyent.vcxproj.filters b/ioperator/iOperator.vcxproj.filters
similarity index 100%
rename from battleyent/battleyent.vcxproj.filters
rename to ioperator/iOperator.vcxproj.filters
diff --git a/battleyent/imconfig_custom.h b/ioperator/imconfig_custom.h
similarity index 100%
rename from battleyent/imconfig_custom.h
rename to ioperator/imconfig_custom.h
diff --git a/battleyent/imgui/imconfig.h b/ioperator/imgui/imconfig.h
similarity index 100%
rename from battleyent/imgui/imconfig.h
rename to ioperator/imgui/imconfig.h
diff --git a/battleyent/imgui/imgui.cpp b/ioperator/imgui/imgui.cpp
similarity index 100%
rename from battleyent/imgui/imgui.cpp
rename to ioperator/imgui/imgui.cpp
diff --git a/battleyent/imgui/imgui.h b/ioperator/imgui/imgui.h
similarity index 100%
rename from battleyent/imgui/imgui.h
rename to ioperator/imgui/imgui.h
diff --git a/battleyent/imgui/imgui_draw.cpp b/ioperator/imgui/imgui_draw.cpp
similarity index 100%
rename from battleyent/imgui/imgui_draw.cpp
rename to ioperator/imgui/imgui_draw.cpp
diff --git a/battleyent/imgui/imgui_impl_dx11.cpp b/ioperator/imgui/imgui_impl_dx11.cpp
similarity index 100%
rename from battleyent/imgui/imgui_impl_dx11.cpp
rename to ioperator/imgui/imgui_impl_dx11.cpp
diff --git a/battleyent/imgui/imgui_impl_dx11.h b/ioperator/imgui/imgui_impl_dx11.h
similarity index 100%
rename from battleyent/imgui/imgui_impl_dx11.h
rename to ioperator/imgui/imgui_impl_dx11.h
diff --git a/battleyent/imgui/imgui_impl_win32.cpp b/ioperator/imgui/imgui_impl_win32.cpp
similarity index 100%
rename from battleyent/imgui/imgui_impl_win32.cpp
rename to ioperator/imgui/imgui_impl_win32.cpp
diff --git a/battleyent/imgui/imgui_impl_win32.h b/ioperator/imgui/imgui_impl_win32.h
similarity index 100%
rename from battleyent/imgui/imgui_impl_win32.h
rename to ioperator/imgui/imgui_impl_win32.h
diff --git a/battleyent/imgui/imgui_internal.h b/ioperator/imgui/imgui_internal.h
similarity index 100%
rename from battleyent/imgui/imgui_internal.h
rename to ioperator/imgui/imgui_internal.h
diff --git a/battleyent/imgui/imgui_tables.cpp b/ioperator/imgui/imgui_tables.cpp
similarity index 100%
rename from battleyent/imgui/imgui_tables.cpp
rename to ioperator/imgui/imgui_tables.cpp
diff --git a/battleyent/imgui/imgui_widgets.cpp b/ioperator/imgui/imgui_widgets.cpp
similarity index 100%
rename from battleyent/imgui/imgui_widgets.cpp
rename to ioperator/imgui/imgui_widgets.cpp
diff --git a/battleyent/imgui/imstb_rectpack.h b/ioperator/imgui/imstb_rectpack.h
similarity index 100%
rename from battleyent/imgui/imstb_rectpack.h
rename to ioperator/imgui/imstb_rectpack.h
diff --git a/battleyent/imgui/imstb_textedit.h b/ioperator/imgui/imstb_textedit.h
similarity index 100%
rename from battleyent/imgui/imstb_textedit.h
rename to ioperator/imgui/imstb_textedit.h
diff --git a/battleyent/imgui/imstb_truetype.h b/ioperator/imgui/imstb_truetype.h
similarity index 100%
rename from battleyent/imgui/imstb_truetype.h
rename to ioperator/imgui/imstb_truetype.h
diff --git a/battleyent/kiero/kiero.cpp b/ioperator/kiero/kiero.cpp
similarity index 100%
rename from battleyent/kiero/kiero.cpp
rename to ioperator/kiero/kiero.cpp
diff --git a/battleyent/kiero/kiero.h b/ioperator/kiero/kiero.h
similarity index 100%
rename from battleyent/kiero/kiero.h
rename to ioperator/kiero/kiero.h
diff --git a/battleyent/minhook/include/MinHook.h b/ioperator/minhook/include/MinHook.h
similarity index 100%
rename from battleyent/minhook/include/MinHook.h
rename to ioperator/minhook/include/MinHook.h
diff --git a/battleyent/minhook/lib/libMinHook.x64.lib b/ioperator/minhook/lib/libMinHook.x64.lib
similarity index 100%
rename from battleyent/minhook/lib/libMinHook.x64.lib
rename to ioperator/minhook/lib/libMinHook.x64.lib
diff --git a/battleyent/minhook/lib/libMinHook.x86.lib b/ioperator/minhook/lib/libMinHook.x86.lib
similarity index 100%
rename from battleyent/minhook/lib/libMinHook.x86.lib
rename to ioperator/minhook/lib/libMinHook.x86.lib
diff --git a/battleyent/offsets.h b/ioperator/offsets.h
similarity index 100%
rename from battleyent/offsets.h
rename to ioperator/offsets.h
diff --git a/battleyent/pch.cpp b/ioperator/pch.cpp
similarity index 100%
rename from battleyent/pch.cpp
rename to ioperator/pch.cpp
diff --git a/battleyent/pch.h b/ioperator/pch.h
similarity index 100%
rename from battleyent/pch.h
rename to ioperator/pch.h
diff --git a/operator/operator.cpp b/operator/operator.cpp
index e900b9d..6ac99a0 100644
--- a/operator/operator.cpp
+++ b/operator/operator.cpp
@@ -4,7 +4,87 @@
#include
#include
#include
+#include
+#include
+#include
+#include
+#include
+#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 };
@@ -142,9 +222,9 @@ void verifyServiceDeletion(const std::wstring& svcName)
SERVICE_STATUS status{};
if (ControlService(hExisting, SERVICE_CONTROL_STOP, &status)) {
- DWORD start = GetTickCount();
+ long long start = GetTickCount64();
std::cout << "Waiting for BEService to stop";
- while (status.dwCurrentState != SERVICE_STOPPED && GetTickCount() - start < 10000) {
+ while (status.dwCurrentState != SERVICE_STOPPED && GetTickCount64() - start < 10000) {
Sleep(500);
std::cout << ".";
if (!QueryServiceStatus(hExisting, &status)) break;
@@ -165,6 +245,207 @@ void verifyServiceDeletion(const std::wstring& svcName)
}
}
+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()
{
@@ -229,16 +510,11 @@ int main()
CloseServiceHandle(hNew);
CloseServiceHandle(scm);
-
std::cout << std::endl;
- std::cout << "Spinning up Battleyen't.\n";
- char* path = _strdup(GetExeDirectory().c_str());
- size_t path_buf_size = strlen(path) + strlen("battleyent.exe") + 1;
- path = (char*)realloc(path, path_buf_size);
- if (strcat_s(path, path_buf_size, "battleyent.exe") == 0) {
- system(path);
- }
- free(path);
+
+ std::cout << "Spinning up. Launch EFT from launcher.\n";
+
+ while (!Battleyent());
std::cout << "Waiting for the game to start";
while (!isProcessRunning("EscapeFromTarkov.exe"))
diff --git a/operator/operator.vcxproj b/operator/operator.vcxproj
index 59de797..e662b1f 100644
--- a/operator/operator.vcxproj
+++ b/operator/operator.vcxproj
@@ -42,7 +42,7 @@
Application
true
- v145
+ v143
Unicode
@@ -105,6 +105,7 @@
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
stdcpp20
+ stdclatest
Console
diff --git a/service/service.vcxproj b/service/service.vcxproj
index 892b64c..952a16f 100644
--- a/service/service.vcxproj
+++ b/service/service.vcxproj
@@ -43,7 +43,7 @@
Application
true
- v145
+ v143
Unicode
@@ -106,6 +106,7 @@
_DEBUG;_CONSOLE;%(PreprocessorDefinitions)
true
stdcpp20
+ stdclatest
Console