Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include <windows.h>
- #include <tlhelp32.h>
- #include <winternl.h>
- #include <iostream>
- #include <vector>
- #include <string>
- #include <memory>
- #include <functional>
- // ======== OFFSETS (Obfuscated) ========
- namespace RobloxOffsets {
- constexpr DWORD GetTaskScheduler = 0x2F12F20;
- constexpr DWORD Luau_execute = 0x247D910;
- constexpr DWORD GetGlobalState = 0xDE3860;
- constexpr DWORD JobsStart = 0x1F82A40;
- constexpr DWORD DataModel = 0x2E9A4C0;
- constexpr DWORD ScriptContext = 0x1DA3F20;
- constexpr DWORD GCStep = 0x1CF6110;
- constexpr DWORD JobsEnd = 0x1F82A48;
- }
- // ======== STRING ENCRYPTION ========
- template<size_t N, uint8_t KEY>
- class EncryptedString {
- private:
- char data[N];
- public:
- constexpr EncryptedString(const char* str) : data{} {
- for (size_t i = 0; i < N - 1; i++) {
- data[i] = str[i] ^ KEY;
- }
- }
- std::string decrypt() const {
- std::string result(N - 1, 0);
- for (size_t i = 0; i < N - 1; i++) {
- result[i] = data[i] ^ KEY;
- }
- return result;
- }
- };
- #define ENCRYPT_STR(str, key) (EncryptedString<sizeof(str), key>(str).decrypt())
- // ======== ERROR HANDLING ========
- class InjectionError : public std::exception {
- private:
- std::string m_message;
- DWORD m_lastError;
- public:
- InjectionError(const std::string& message) :
- m_message(message),
- m_lastError(GetLastError()) {}
- const char* what() const noexcept override {
- return m_message.c_str();
- }
- DWORD getWindowsError() const {
- return m_lastError;
- }
- std::string getFormattedError() const {
- char buffer[256] = {0};
- FormatMessageA(
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- m_lastError,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buffer,
- sizeof(buffer),
- NULL
- );
- return std::string(buffer);
- }
- };
- // ======== MEMORY TOOLS ========
- class Memory {
- public:
- static DWORD GetRobloxPID() {
- HWND hWnd = FindWindowA(ENCRYPT_STR("ROBLOX", 0x55).c_str(), nullptr);
- if (!hWnd) {
- hWnd = FindWindowA(ENCRYPT_STR("RobloxApp", 0x55).c_str(), nullptr);
- }
- if (!hWnd) {
- throw InjectionError("Roblox window not found");
- }
- DWORD pid = 0;
- GetWindowThreadProcessId(hWnd, &pid);
- if (!pid) {
- throw InjectionError("Failed to get Roblox process ID");
- }
- return pid;
- }
- static DWORD GetBaseAddress(DWORD pid) {
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, pid);
- if (snapshot == INVALID_HANDLE_VALUE) {
- throw InjectionError("Failed to create module snapshot");
- }
- MODULEENTRY32 moduleEntry;
- moduleEntry.dwSize = sizeof(moduleEntry);
- if (Module32First(snapshot, &moduleEntry)) {
- DWORD baseAddress = (DWORD)moduleEntry.modBaseAddr;
- CloseHandle(snapshot);
- return baseAddress;
- }
- CloseHandle(snapshot);
- throw InjectionError("Failed to get base address");
- }
- template<typename T>
- static T Read(HANDLE hProc, DWORD addr) {
- T val;
- if (!ReadProcessMemory(hProc, (LPCVOID)addr, &val, sizeof(T), nullptr)) {
- throw InjectionError("Failed to read process memory");
- }
- return val;
- }
- static std::vector<uint8_t> ReadBytes(HANDLE hProc, DWORD addr, size_t size) {
- std::vector<uint8_t> buffer(size);
- if (!ReadProcessMemory(hProc, (LPCVOID)addr, buffer.data(), size, nullptr)) {
- throw InjectionError("Failed to read process memory bytes");
- }
- return buffer;
- }
- static void Write(HANDLE hProc, DWORD addr, LPCVOID data, size_t size) {
- DWORD oldProtect;
- if (!VirtualProtectEx(hProc, (LPVOID)addr, size, PAGE_EXECUTE_READWRITE, &oldProtect)) {
- throw InjectionError("Failed to modify memory protection");
- }
- if (!WriteProcessMemory(hProc, (LPVOID)addr, data, size, nullptr)) {
- throw InjectionError("Failed to write process memory");
- }
- VirtualProtectEx(hProc, (LPVOID)addr, size, oldProtect, &oldProtect);
- }
- template<typename T>
- static void Write(HANDLE hProc, DWORD addr, const T& value) {
- Write(hProc, addr, &value, sizeof(T));
- }
- static LPVOID AllocateMemory(HANDLE hProc, size_t size, DWORD protection = PAGE_EXECUTE_READWRITE) {
- LPVOID addr = VirtualAllocEx(hProc, nullptr, size, MEM_COMMIT | MEM_RESERVE, protection);
- if (!addr) {
- throw InjectionError("Failed to allocate memory in target process");
- }
- return addr;
- }
- static void FreeMemory(HANDLE hProc, LPVOID addr) {
- if (!VirtualFreeEx(hProc, addr, 0, MEM_RELEASE)) {
- throw InjectionError("Failed to free memory in target process");
- }
- }
- };
- // ======== INJECTION ENGINE ========
- class Injector {
- private:
- struct DllInfo {
- BYTE* data;
- DWORD size;
- IMAGE_NT_HEADERS* ntHeaders;
- ~DllInfo() {
- if (data) delete[] data;
- }
- };
- static DllInfo LoadDll(const std::string& path) {
- DllInfo info = {nullptr, 0, nullptr};
- HANDLE hFile = CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
- OPEN_EXISTING, 0, nullptr);
- if (hFile == INVALID_HANDLE_VALUE) {
- throw InjectionError("Failed to open DLL file");
- }
- info.size = GetFileSize(hFile, nullptr);
- if (info.size == INVALID_FILE_SIZE) {
- CloseHandle(hFile);
- throw InjectionError("Failed to get DLL file size");
- }
- info.data = new BYTE[info.size];
- DWORD bytesRead;
- if (!ReadFile(hFile, info.data, info.size, &bytesRead, nullptr) || bytesRead != info.size) {
- CloseHandle(hFile);
- throw InjectionError("Failed to read DLL file");
- }
- CloseHandle(hFile);
- // Parse PE Headers
- IMAGE_DOS_HEADER* dosHeader = (IMAGE_DOS_HEADER*)info.data;
- if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- throw InjectionError("Invalid DOS header signature");
- }
- info.ntHeaders = (IMAGE_NT_HEADERS*)(info.data + dosHeader->e_lfanew);
- if (info.ntHeaders->Signature != IMAGE_NT_SIGNATURE) {
- throw InjectionError("Invalid NT header signature");
- }
- return info;
- }
- static DWORD GetProcAddressManual(HANDLE hProc, DWORD moduleBase, const char* procName) {
- IMAGE_DOS_HEADER dosHeader = Memory::Read<IMAGE_DOS_HEADER>(hProc, moduleBase);
- IMAGE_NT_HEADERS ntHeaders = Memory::Read<IMAGE_NT_HEADERS>(hProc, moduleBase + dosHeader.e_lfanew);
- DWORD exportDirRVA = ntHeaders.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress;
- if (!exportDirRVA) {
- throw InjectionError("Module has no export directory");
- }
- IMAGE_EXPORT_DIRECTORY exportDir = Memory::Read<IMAGE_EXPORT_DIRECTORY>(hProc, moduleBase + exportDirRVA);
- std::vector<DWORD> functions = Memory::ReadBytes<DWORD>(hProc, moduleBase + exportDir.AddressOfFunctions, exportDir.NumberOfFunctions * sizeof(DWORD));
- std::vector<DWORD> names = Memory::ReadBytes<DWORD>(hProc, moduleBase + exportDir.AddressOfNames, exportDir.NumberOfNames * sizeof(DWORD));
- std::vector<WORD> ordinals = Memory::ReadBytes<WORD>(hProc, moduleBase + exportDir.AddressOfNameOrdinals, exportDir.NumberOfNames * sizeof(WORD));
- for (DWORD i = 0; i < exportDir.NumberOfNames; i++) {
- char name[256] = {0};
- ReadProcessMemory(hProc, (LPCVOID)(moduleBase + names[i]), name, sizeof(name), nullptr);
- if (strcmp(name, procName) == 0) {
- return moduleBase + functions[ordinals[i]];
- }
- }
- throw InjectionError("Function not found in module");
- }
- static void FixImports(HANDLE hProc, DWORD baseAddr, const DllInfo& dllInfo) {
- IMAGE_DATA_DIRECTORY importDir = dllInfo.ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
- if (!importDir.VirtualAddress) {
- return; // No imports
- }
- IMAGE_IMPORT_DESCRIPTOR* importDesc = (IMAGE_IMPORT_DESCRIPTOR*)(dllInfo.data + importDir.VirtualAddress);
- for (; importDesc->Name; importDesc++) {
- char moduleName[256] = {0};
- memcpy(moduleName, dllInfo.data + importDesc->Name, sizeof(moduleName) - 1);
- DWORD moduleHandle = (DWORD)GetModuleHandleA(moduleName);
- if (!moduleHandle) {
- moduleHandle = (DWORD)LoadLibraryA(moduleName);
- if (!moduleHandle) {
- throw InjectionError(std::string("Failed to load required DLL: ") + moduleName);
- }
- }
- IMAGE_THUNK_DATA* thunkData = (IMAGE_THUNK_DATA*)(dllInfo.data + importDesc->FirstThunk);
- IMAGE_THUNK_DATA* originalThunk = importDesc->OriginalFirstThunk ?
- (IMAGE_THUNK_DATA*)(dllInfo.data + importDesc->OriginalFirstThunk) : nullptr;
- for (DWORD i = 0; thunkData[i].u1.AddressOfData; i++) {
- DWORD funcAddr = 0;
- if (originalThunk && originalThunk[i].u1.Ordinal & IMAGE_ORDINAL_FLAG) {
- // Import by ordinal
- WORD ordinal = (WORD)(originalThunk[i].u1.Ordinal & 0xFFFF);
- funcAddr = (DWORD)GetProcAddress((HMODULE)moduleHandle, (LPCSTR)ordinal);
- } else {
- // Import by name
- IMAGE_IMPORT_BY_NAME* importByName = (IMAGE_IMPORT_BY_NAME*)(dllInfo.data + thunkData[i].u1.AddressOfData);
- char funcName[256] = {0};
- memcpy(funcName, importByName->Name, sizeof(funcName) - 1);
- funcAddr = (DWORD)GetProcAddress((HMODULE)moduleHandle, funcName);
- }
- if (!funcAddr) {
- throw InjectionError("Failed to resolve imported function");
- }
- Memory::Write<DWORD>(hProc, baseAddr + importDesc->FirstThunk + i * sizeof(DWORD), funcAddr);
- }
- }
- }
- static void FixRelocations(HANDLE hProc, DWORD baseAddr, const DllInfo& dllInfo) {
- DWORD delta = baseAddr - dllInfo.ntHeaders->OptionalHeader.ImageBase;
- if (!delta) {
- return; // No relocations needed
- }
- IMAGE_DATA_DIRECTORY relocDir = dllInfo.ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
- if (!relocDir.VirtualAddress) {
- return; // No relocations
- }
- DWORD relocOffset = 0;
- while (relocOffset < relocDir.Size) {
- IMAGE_BASE_RELOCATION* relocBlock = (IMAGE_BASE_RELOCATION*)(dllInfo.data + relocDir.VirtualAddress + relocOffset);
- DWORD blockSize = relocBlock->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION);
- WORD* relocData = (WORD*)((BYTE*)relocBlock + sizeof(IMAGE_BASE_RELOCATION));
- DWORD numRelocs = blockSize / sizeof(WORD);
- DWORD pageRVA = relocBlock->VirtualAddress;
- for (DWORD i = 0; i < numRelocs; i++) {
- WORD entry = relocData[i];
- BYTE type = (entry >> 12) & 0xF;
- WORD offset = entry & 0xFFF;
- if (type == IMAGE_REL_BASED_HIGHLOW) {
- DWORD* addr = (DWORD*)(dllInfo.data + pageRVA + offset);
- DWORD value = *addr + delta;
- Memory::Write<DWORD>(hProc, baseAddr + pageRVA + offset, value);
- }
- }
- relocOffset += relocBlock->SizeOfBlock;
- }
- }
- public:
- static bool ManualMap(HANDLE hProc, const std::string& dllPath) {
- try {
- DllInfo dllInfo = LoadDll(dllPath);
- // Allocate memory in target process
- DWORD imageSize = dllInfo.ntHeaders->OptionalHeader.SizeOfImage;
- LPVOID baseAddr = Memory::AllocateMemory(hProc, imageSize);
- // Map sections
- IMAGE_SECTION_HEADER* sectionHeader = IMAGE_FIRST_SECTION(dllInfo.ntHeaders);
- for (WORD i = 0; i < dllInfo.ntHeaders->FileHeader.NumberOfSections; i++) {
- DWORD sectionVA = (DWORD)baseAddr + sectionHeader[i].VirtualAddress;
- DWORD sectionSize = sectionHeader[i].SizeOfRawData;
- DWORD sectionDataOffset = sectionHeader[i].PointerToRawData;
- if (sectionSize > 0) {
- Memory::Write(hProc, sectionVA, dllInfo.data + sectionDataOffset, sectionSize);
- }
- }
- // Fix imports
- FixImports(hProc, (DWORD)baseAddr, dllInfo);
- // Fix relocations
- FixRelocations(hProc, (DWORD)baseAddr, dllInfo);
- // Execute DllMain
- DWORD entryPoint = (DWORD)baseAddr + dllInfo.ntHeaders->OptionalHeader.AddressOfEntryPoint;
- // Create remote thread to call DllMain
- HANDLE hThread = CreateRemoteThread(hProc, nullptr, 0,
- (LPTHREAD_START_ROUTINE)entryPoint, baseAddr, 0, nullptr);
- if (!hThread) {
- Memory::FreeMemory(hProc, baseAddr);
- throw InjectionError("Failed to create remote thread for DllMain");
- }
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- return true;
- }
- catch (const InjectionError& e) {
- std::cerr << "Manual mapping failed: " << e.what() << " (Error: "
- << e.getWindowsError() << " - " << e.getFormattedError() << ")" << std::endl;
- return false;
- }
- }
- static bool InjectSyscall(DWORD pid, const std::string& dllPath) {
- try {
- HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
- if (!hProc) {
- throw InjectionError("Failed to open target process");
- }
- LPVOID pDllPath = Memory::AllocateMemory(hProc, dllPath.length() + 1, PAGE_READWRITE);
- Memory::Write(hProc, (DWORD)pDllPath, dllPath.c_str(), dllPath.length() + 1);
- // Use syscall to avoid detection
- typedef NTSTATUS(NTAPI* pNtCreateThreadEx)(
- OUT PHANDLE hThread,
- IN ACCESS_MASK DesiredAccess,
- IN LPVOID ObjectAttributes,
- IN HANDLE ProcessHandle,
- IN LPTHREAD_START_ROUTINE lpStartAddress,
- IN LPVOID lpParameter,
- IN BOOL CreateSuspended,
- IN SIZE_T StackZeroBits,
- IN SIZE_T SizeOfStackCommit,
- IN SIZE_T SizeOfStackReserve,
- OUT LPVOID lpBytesBuffer
- );
- HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
- if (!hNtdll) {
- CloseHandle(hProc);
- throw InjectionError("Failed to get ntdll.dll handle");
- }
- pNtCreateThreadEx NtCreateThreadEx = (pNtCreateThreadEx)GetProcAddress(hNtdll, "NtCreateThreadEx");
- if (!NtCreateThreadEx) {
- CloseHandle(hProc);
- throw InjectionError("Failed to get NtCreateThreadEx address");
- }
- HANDLE hThread = nullptr;
- NTSTATUS status = NtCreateThreadEx(
- &hThread,
- THREAD_ALL_ACCESS,
- nullptr,
- hProc,
- (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA"),
- pDllPath,
- FALSE,
- 0,
- 0,
- 0,
- nullptr
- );
- if (status != 0 || !hThread) {
- Memory::FreeMemory(hProc, pDllPath);
- CloseHandle(hProc);
- throw InjectionError("NtCreateThreadEx failed with status: " + std::to_string(status));
- }
- WaitForSingleObject(hThread, INFINITE);
- DWORD exitCode = 0;
- GetExitCodeThread(hThread, &exitCode);
- Memory::FreeMemory(hProc, pDllPath);
- CloseHandle(hThread);
- CloseHandle(hProc);
- return exitCode != 0;
- }
- catch (const InjectionError& e) {
- std::cerr << "Syscall injection failed: " << e.what() << " (Error: "
- << e.getWindowsError() << " - " << e.getFormattedError() << ")" << std::endl;
- return false;
- }
- }
- static bool ThreadHijacking(DWORD pid, const std::string& dllPath) {
- try {
- HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);
- if (!hProc) {
- throw InjectionError("Failed to open target process");
- }
- // Find a thread to hijack
- HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
- if (hSnapshot == INVALID_HANDLE_VALUE) {
- CloseHandle(hProc);
- throw InjectionError("Failed to create thread snapshot");
- }
- THREADENTRY32 te;
- te.dwSize = sizeof(THREADENTRY32);
- HANDLE hThread = nullptr;
- if (Thread32First(hSnapshot, &te)) {
- do {
- if (te.th32OwnerProcessID == pid) {
- hThread = OpenThread(THREAD_GET_CONTEXT | THREAD_SET_CONTEXT | THREAD_SUSPEND_RESUME, FALSE, te.th32ThreadID);
- if (hThread) break;
- }
- } while (Thread32Next(hSnapshot, &te));
- }
- CloseHandle(hSnapshot);
- if (!hThread) {
- CloseHandle(hProc);
- throw InjectionError("Failed to find suitable thread for hijacking");
- }
- // Allocate memory for DLL path
- LPVOID pDllPath = Memory::AllocateMemory(hProc, dllPath.length() + 1, PAGE_READWRITE);
- Memory::Write(hProc, (DWORD)pDllPath, dllPath.c_str(), dllPath.length() + 1);
- // Prepare shellcode to load the DLL
- const char shellcodeTemplate[] =
- "\x60" // PUSHAD
- "\x9C" // PUSHFD
- "\x68\x00\x00\x00\x00" // PUSH dllPath
- "\xB8\x00\x00\x00\x00" // MOV EAX, LoadLibraryA
- "\xFF\xD0" // CALL EAX
- "\x9D" // POPFD
- "\x61" // POPAD
- "\x68\x00\x00\x00\x00" // PUSH original_eip
- "\xC3"; // RET
- char shellcode[sizeof(shellcodeTemplate)];
- memcpy(shellcode, shellcodeTemplate, sizeof(shellcodeTemplate));
- // Fill in the placeholders
- *(DWORD*)(shellcode + 3) = (DWORD)pDllPath;
- *(DWORD*)(shellcode + 8) = (DWORD)GetProcAddress(GetModuleHandleA("kernel32.dll"), "LoadLibraryA");
- // Allocate memory for shellcode
- LPVOID pShellcode = Memory::AllocateMemory(hProc, sizeof(shellcode), PAGE_EXECUTE_READWRITE);
- // Suspend thread
- SuspendThread(hThread);
- // Get thread context
- CONTEXT ctx;
- ctx.ContextFlags = CONTEXT_FULL;
- if (!GetThreadContext(hThread, &ctx)) {
- ResumeThread(hThread);
- CloseHandle(hThread);
- CloseHandle(hProc);
- throw InjectionError("Failed to get thread context");
- }
- // Update shellcode with original EIP
- *(DWORD*)(shellcode + 15) = ctx.Eip;
- // Write shellcode
- Memory::Write(hProc, (DWORD)pShellcode, shellcode, sizeof(shellcode));
- // Update EIP to point to shellcode
- ctx.Eip = (DWORD)pShellcode;
- // Set thread context
- if (!SetThreadContext(hThread, &ctx)) {
- ResumeThread(hThread);
- CloseHandle(hThread);
- CloseHandle(hProc);
- throw InjectionError("Failed to set thread context");
- }
- // Resume thread
- ResumeThread(hThread);
- // Clean up
- CloseHandle(hThread);
- CloseHandle(hProc);
- return true;
- }
- catch (const InjectionError& e) {
- std::cerr << "Thread hijacking failed: " << e.what() << " (Error: "
- << e.getWindowsError() << " - " << e.getFormattedError() << ")" << std::endl;
- return false;
- }
- }
- };
- // ======== LUA EXECUTION ========
- class LuaExecutor {
- private:
- HANDLE m_hProcess;
- DWORD m_baseAddress;
- DWORD m_luaState;
- public:
- LuaExecutor(HANDLE hProc, DWORD baseAddress) :
- m_hProcess(hProc),
- m_baseAddress(baseAddress) {
- m_luaState = Memory::Read<DWORD>(m_hProcess, m_baseAddress + RobloxOffsets::GetGlobalState);
- }
- void ExecuteScript(const std::string& script) {
- try {
- // Allocate memory for the script
- LPVOID pScript = Memory::AllocateMemory(m_hProcess, script.length() + 1, PAGE_READWRITE);
- Memory::Write(m_hProcess, (DWORD)pScript, script.c_str(), script.length() + 1);
- // Prepare function arguments
- struct {
- DWORD luaState;
- DWORD scriptPtr;
- DWORD scriptSize;
- DWORD chunkName;
- DWORD environment;
- } args;
- args.luaState = m_luaState;
- args.scriptPtr = (DWORD)pScript;
- args.scriptSize = script.length();
- args.chunkName = 0; // NULL
- args.environment = 0; // 0 = use global environment
- // Create the remote thread to execute the Lua script
- DWORD luauExecute = m_baseAddress + RobloxOffsets::Luau_execute;
- HANDLE hThread = CreateRemoteThread(m_hProcess, nullptr, 0,
- (LPTHREAD_START_ROUTINE)luauExecute, &args, 0, nullptr);
- if (!hThread) {
- Memory::FreeMemory(m_hProcess, pScript);
- throw InjectionError("Failed to create remote thread for Lua execution");
- }
- WaitForSingleObject(hThread, INFINITE);
- DWORD exitCode;
- GetExitCodeThread(hThread, &exitCode);
- CloseHandle(hThread);
- Memory::FreeMemory(m_hProcess, pScript);
- if (exitCode != 0) {
- throw InjectionError("Lua execution failed with exit code: " + std::to_string(exitCode));
- }
- }
- catch (const InjectionError& e) {
- std::cerr << "Script execution failed: " << e.what() << std::endl;
- throw;
- }
- }
- DWORD GetTaskScheduler() {
- return Memory::Read<DWORD>(m_hProcess, m_baseAddress + RobloxOffsets::GetTaskScheduler);
- }
- DWORD GetDataModel() {
- return Memory::Read<DWORD>(m_hProcess, m_baseAddress + RobloxOffsets::DataModel);
- }
- DWORD GetScriptContext() {
- return Memory::Read<DWORD>(m_hProcess, m_baseAddress + RobloxOffsets::ScriptContext);
- }
- };
- // ======== ANTI-DETECTION ========
- namespace AntiDetect {
- bool IsDebugged() {
- // Check multiple ways
- bool debuggerPresent = false;
- // Method 1: IsDebuggerPresent
- if (IsDebuggerPresent()) {
- return true;
- }
- // Method 2: CheckRemoteDebuggerPresent
- CheckRemoteDebuggerPresent(GetCurrentProcess(), &debuggerPresent);
- if (debuggerPresent) {
- return true;
- }
- // Method 3: INT 3
- __try {
- __asm { int 3 };
- return true;
- }
- __except (EXCEPTION_EXECUTE_HANDLER) {
- // No debugger
- }
- // Method 4: Timing check
- LARGE_INTEGER freq, start, end;
- QueryPerformanceFrequency(&freq);
- QueryPerformanceCounter(&start);
- // Some heavy operation that should complete quickly
- for (volatile int i = 0; i < 10000; i++);
- QueryPerformanceCounter(&end);
- double elapsed = (double)(end.QuadPart - start.QuadPart) / freq.QuadPart;
- // If elapsed time is suspiciously long, likely debugging
- if (elapsed > 0.1) {
- return true;
- }
- // Method 5: Check for common debugging tools
- HANDLE hToolHelp = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hToolHelp != INVALID_HANDLE_VALUE) {
- PROCESSENTRY32 pe;
- pe.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(hToolHelp, &pe)) {
- do {
- if (strstr(pe.szExeFile, "ida") ||
- strstr(pe.szExeFile, "olly") ||
- strstr(pe.szExeFile, "x64dbg") ||
- strstr(pe.szExeFile, "windbg")) {
- CloseHandle(hToolHelp);
- return true;
- }
- } while (Process32Next(hToolHelp, &pe));
- }
- CloseHandle(hToolHelp);
- }
- return false;
- }
- void ScrambleMemory() {
- // Use secure CRT functions
- std::vector<volatile int> junk(100);
- for (size_t i = 0; i < junk.size(); i++) {
- junk[i] = rand() ^ (DWORD)&junk[i];
- }
- // More sophisticated memory scrambling
- for (size_t i = 0; i < junk.size(); i++) {
- junk[i] = junk[i] ^ (junk[(i + 1) % junk.size()]);
- }
- // Allocate and deallocate memory in patterns to confuse memory scanners
- std::vector<LPVOID> allocations;
- for (int i = 0; i < 5; i++) {
- allocations.push_back(VirtualAlloc(nullptr, 4096 * (rand() % 10 + 1), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE));
- }
- for (size_t i = 0; i < allocations.size(); i++) {
- if (allocations[i]) {
- memset(allocations[i], rand() % 256, 4096);
- VirtualFree(allocations[i], 0, MEM_RELEASE);
- }
- }
- }
- void DisableWindowsDefender() {
- // Registry modifications to temporarily disable real-time protection
- // Note: This requires administrative privileges
- HKEY hKey;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
- "SOFTWARE\\Policies\\Microsoft\\Windows Defender",
- 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
- DWORD value = 1;
- RegSetValueExA(hKey, "DisableAntiSpyware", 0, REG_DWORD, (BYTE*)&value, sizeof(value));
- RegCloseKey(hKey);
- }
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
- "SOFTWARE\\Policies\\Microsoft\\Windows Defender\\Real-Time Protection",
- 0, KEY_ALL_ACCESS, &hKey) == ERROR_SUCCESS) {
- DWORD value = 1;
- RegSetValueExA(hKey, "DisableRealtimeMonitoring", 0, REG_DWORD, (BYTE*)&value, sizeof(value));
- RegSetValueExA(hKey, "DisableBehaviorMonitoring", 0, REG_DWORD, (BYTE*)&value, sizeof(value));
- RegSetValueExA(hKey, "DisableScanOnRealtimeEnable", 0, REG_DWORD, (BYTE*)&value, sizeof(value));
- RegCloseKey(hKey);
- }
- }
- bool IsProcessHooked() {
- // Check for common hooking techniques
- HMODULE hNtdll = GetModuleHandleA("ntdll.dll");
- if (!hNtdll) return true;
- // Check for modifications to critical functions
- BYTE* pWriteProcessMemory = (BYTE*)GetProcAddress(GetModuleHandleA("kernel32.dll"), "WriteProcessMemory");
- if (!pWriteProcessMemory) return true;
- // First few bytes of a hooked function often contain a JMP instruction
- if (pWriteProcessMemory[0] == 0xE9 || pWriteProcessMemory[0] == 0xFF) {
- return true;
- }
- return false;
- }
- void ObfuscateStrings() {
- // This function doesn't actually do anything at runtime
- // It's meant to demonstrate how string obfuscation works
- // Actual string obfuscation is handled by the ENCRYPT_STR macro
- const char* original = "Suspicious String";
- std::string encrypted = ENCRYPT_STR("Suspicious String", 0x42);
- // In real usage, only the encrypted version would exist in binary
- }
- bool CheckVirtualMachine() {
- bool isVM = false;
- // Check for VM-specific registry keys
- HKEY hKey;
- if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\ControlSet001\\Services\\Disk\\Enum", 0, KEY_READ, &hKey) == ERROR_SUCCESS) {
- char buffer[1024] = {0};
- DWORD bufferSize = sizeof(buffer);
- if (RegQueryValueExA(hKey, "0", NULL, NULL, (BYTE*)buffer, &bufferSize) == ERROR_SUCCESS) {
- if (strstr(buffer, "VMware") ||
- strstr(buffer, "VBOX") ||
- strstr(buffer, "QEMU") ||
- strstr(buffer, "Virtual")) {
- isVM = true;
- }
- }
- RegCloseKey(hKey);
- }
- // Check for VM-specific processes
- HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnapshot != INVALID_HANDLE_VALUE) {
- PROCESSENTRY32 pe;
- pe.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(hSnapshot, &pe)) {
- do {
- if (strstr(pe.szExeFile, "vmtoolsd.exe") ||
- strstr(pe.szExeFile, "VBoxService.exe")) {
- isVM = true;
- break;
- }
- } while (Process32Next(hSnapshot, &pe));
- }
- CloseHandle(hSnapshot);
- }
- return isVM;
- }
- }
- // ======== PROCESS HANDLING ========
- class ProcessManager {
- public:
- static std::vector<DWORD> FindProcessesByName(const std::string& name) {
- std::vector<DWORD> processes;
- HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnapshot != INVALID_HANDLE_VALUE) {
- PROCESSENTRY32 pe;
- pe.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(hSnapshot, &pe)) {
- do {
- if (_stricmp(pe.szExeFile, name.c_str()) == 0) {
- processes.push_back(pe.th32ProcessID);
- }
- } while (Process32Next(hSnapshot, &pe));
- }
- CloseHandle(hSnapshot);
- }
- return processes;
- }
- static bool TerminateProcessById(DWORD pid) {
- HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
- if (!hProcess) {
- return false;
- }
- bool result = TerminateProcess(hProcess, 0);
- CloseHandle(hProcess);
- return result;
- }
- static bool ElevatePrivileges() {
- HANDLE hToken;
- TOKEN_PRIVILEGES tp;
- LUID luid;
- if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken)) {
- return false;
- }
- if (!LookupPrivilegeValueA(nullptr, "SeDebugPrivilege", &luid)) {
- CloseHandle(hToken);
- return false;
- }
- tp.PrivilegeCount = 1;
- tp.Privileges[0].Luid = luid;
- tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
- bool result = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES), nullptr, nullptr);
- CloseHandle(hToken);
- return result && GetLastError() != ERROR_NOT_ALL_ASSIGNED;
- }
- };
- // ======== INJECTOR MANAGER ========
- class InjectorManager {
- private:
- HANDLE m_hProcess;
- DWORD m_pid;
- DWORD m_baseAddress;
- std::unique_ptr<LuaExecutor> m_luaExecutor;
- public:
- InjectorManager() : m_hProcess(nullptr), m_pid(0), m_baseAddress(0), m_luaExecutor(nullptr) {}
- ~InjectorManager() {
- if (m_hProcess) {
- CloseHandle(m_hProcess);
- }
- }
- bool Initialize() {
- try {
- // Elevate privileges if possible
- ProcessManager::ElevatePrivileges();
- // Check for debugger or VM
- if (AntiDetect::IsDebugged()) {
- throw InjectionError("Debugger detected");
- }
- if (AntiDetect::CheckVirtualMachine()) {
- // Just a warning, not fatal
- std::cout << "Warning: Virtual machine detected" << std::endl;
- }
- // Scramble memory to avoid detection
- AntiDetect::ScrambleMemory();
- // Get Roblox process
- m_pid = Memory::GetRobloxPID();
- m_hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, m_pid);
- if (!m_hProcess) {
- throw InjectionError("Failed to open Roblox process");
- }
- // Get base address
- m_baseAddress = Memory::GetBaseAddress(m_pid);
- // Initialize Lua executor
- m_luaExecutor = std::make_unique<LuaExecutor>(m_hProcess, m_baseAddress);
- return true;
- }
- catch (const InjectionError& e) {
- std::cerr << "Initialization failed: " << e.what() << std::endl;
- return false;
- }
- }
- bool InjectDLL(const std::string& dllPath, InjectMethod method = InjectMethod::Syscall) {
- try {
- if (!m_hProcess) {
- throw InjectionError("Injector not initialized");
- }
- switch (method) {
- case InjectMethod::ManualMap:
- return Injector::ManualMap(m_hProcess, dllPath);
- case InjectMethod::Syscall:
- return Injector::InjectSyscall(m_pid, dllPath);
- case InjectMethod::ThreadHijack:
- return Injector::ThreadHijacking(m_pid, dllPath);
- default:
- throw InjectionError("Unknown injection method");
- }
- }
- catch (const InjectionError& e) {
- std::cerr << "Injection failed: " << e.what() << std::endl;
- return false;
- }
- }
- bool ExecuteLuaScript(const std::string& script) {
- try {
- if (!m_luaExecutor) {
- throw InjectionError("Lua executor not initialized");
- }
- m_luaExecutor->ExecuteScript(script);
- return true;
- }
- catch (const InjectionError& e) {
- std::cerr << "Script execution failed: " << e.what() << std::endl;
- return false;
- }
- }
- DWORD GetRobloxPID() const {
- return m_pid;
- }
- DWORD GetBaseAddress() const {
- return m_baseAddress;
- }
- enum class InjectMethod {
- ManualMap,
- Syscall,
- ThreadHijack
- };
- };
- // ======== SECURITY ========
- namespace Security {
- std::string GenerateRandomString(size_t length) {
- const char charset[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
- std::string result;
- result.resize(length);
- for (size_t i = 0; i < length; i++) {
- result[i] = charset[rand() % (sizeof(charset) - 1)];
- }
- return result;
- }
- void InitializeSecurityContext() {
- // Seed random number generator
- srand(static_cast<unsigned int>(time(nullptr) ^ GetCurrentProcessId()));
- // Make sure critical DLLs are loaded
- LoadLibraryA("ntdll.dll");
- LoadLibraryA("kernel32.dll");
- LoadLibraryA("user32.dll");
- // Initialize encryption if needed
- // (placeholder for more advanced implementations)
- }
- };
- // ======== UTILITIES ========
- namespace Utils {
- std::string FormatErrorMessage(DWORD error) {
- char buffer[256] = {0};
- FormatMessageA(
- FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- error,
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
- buffer,
- sizeof(buffer),
- NULL
- );
- return std::string(buffer);
- }
- std::string GetCurrentDirectory() {
- char buffer[MAX_PATH] = {0};
- GetCurrentDirectoryA(MAX_PATH, buffer);
- return std::string(buffer);
- }
- bool FileExists(const std::string& path) {
- return GetFileAttributesA(path.c_str()) != INVALID_FILE_ATTRIBUTES;
- }
- bool DirectoryExists(const std::string& path) {
- DWORD attributes = GetFileAttributesA(path.c_str());
- return (attributes != INVALID_FILE_ATTRIBUTES &&
- (attributes & FILE_ATTRIBUTE_DIRECTORY));
- }
- std::string ReadFileToString(const std::string& path) {
- std::string content;
- HANDLE hFile = CreateFileA(path.c_str(), GENERIC_READ, FILE_SHARE_READ, nullptr,
- OPEN_EXISTING, 0, nullptr);
- if (hFile == INVALID_HANDLE_VALUE) {
- return "";
- }
- DWORD fileSize = GetFileSize(hFile, nullptr);
- if (fileSize == INVALID_FILE_SIZE) {
- CloseHandle(hFile);
- return "";
- }
- content.resize(fileSize);
- DWORD bytesRead;
- if (!ReadFile(hFile, &content[0], fileSize, &bytesRead, nullptr) || bytesRead != fileSize) {
- content.clear();
- }
- CloseHandle(hFile);
- return content;
- }
- bool WriteStringToFile(const std::string& path, const std::string& content) {
- HANDLE hFile = CreateFileA(path.c_str(), GENERIC_WRITE, 0, nullptr,
- CREATE_ALWAYS, 0, nullptr);
- if (hFile == INVALID_HANDLE_VALUE) {
- return false;
- }
- DWORD bytesWritten;
- bool result = WriteFile(hFile, content.c_str(), content.length(), &bytesWritten, nullptr) &&
- bytesWritten == content.length();
- CloseHandle(hFile);
- return result;
- }
- };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement