Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <Windows.h>
- #include <TlHelp32.h>
- #include <Psapi.h>
- #include <iostream>
- #include <string>
- #include <memory>
- // For direct syscalls
- typedef NTSTATUS(NTAPI* pNtCreateThreadEx)(
- OUT PHANDLE hThread,
- IN ACCESS_MASK DesiredAccess,
- IN PVOID ObjectAttributes,
- IN HANDLE ProcessHandle,
- IN PVOID lpStartAddress,
- IN PVOID lpParameter,
- IN ULONG Flags,
- IN SIZE_T StackZeroBits,
- IN SIZE_T SizeOfStackCommit,
- IN SIZE_T SizeOfStackReserve,
- OUT PVOID lpBytesBuffer
- );
- typedef NTSTATUS(NTAPI* pNtWriteVirtualMemory)(
- IN HANDLE ProcessHandle,
- IN PVOID BaseAddress,
- IN PVOID Buffer,
- IN SIZE_T NumberOfBytesToWrite,
- OUT PSIZE_T NumberOfBytesWritten OPTIONAL
- );
- // Structure for storing syscall function pointers
- struct SYSCALLS {
- pNtCreateThreadEx NtCreateThreadEx;
- pNtWriteVirtualMemory NtWriteVirtualMemory;
- };
- SYSCALLS syscalls;
- // Initialize syscall pointers
- bool InitializeSyscalls() {
- HMODULE hNtdll = GetModuleHandleW(L"ntdll.dll");
- if (!hNtdll) return false;
- syscalls.NtCreateThreadEx = (pNtCreateThreadEx)GetProcAddress(hNtdll, "NtCreateThreadEx");
- syscalls.NtWriteVirtualMemory = (pNtWriteVirtualMemory)GetProcAddress(hNtdll, "NtWriteVirtualMemory");
- return (syscalls.NtCreateThreadEx && syscalls.NtWriteVirtualMemory);
- }
- // Structure for injection parameters
- struct INJECTION_DATA {
- HANDLE hProcess;
- wchar_t dllPath[MAX_PATH];
- bool completed;
- };
- // Function to detect the Roblox process ID
- DWORD GetRobloxProcessId() {
- DWORD processId = 0;
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnap == INVALID_HANDLE_VALUE) {
- return 0;
- }
- PROCESSENTRY32 pe32 = { 0 };
- pe32.dwSize = sizeof(PROCESSENTRY32);
- if (Process32First(hSnap, &pe32)) {
- do {
- if (_wcsicmp(pe32.szExeFile, L"RobloxPlayerBeta.exe") == 0) {
- processId = pe32.th32ProcessID;
- break;
- }
- } while (Process32Next(hSnap, &pe32));
- }
- CloseHandle(hSnap);
- return processId;
- }
- // Function to suspend threads using ntdll.dll (and spoof its state)
- void SuspendAndSpoofThreads(HANDLE hProcess) {
- DWORD processId = GetProcessId(hProcess);
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
- if (hSnap == INVALID_HANDLE_VALUE) return;
- THREADENTRY32 te32 = { 0 };
- te32.dwSize = sizeof(THREADENTRY32);
- if (Thread32First(hSnap, &te32)) {
- do {
- // Check if the thread belongs to the target process
- if (te32.th32OwnerProcessID == processId) {
- HANDLE hThread = OpenThread(THREAD_SUSPEND_RESUME | THREAD_QUERY_INFORMATION, FALSE, te32.th32ThreadID);
- if (hThread) {
- SuspendThread(hThread);
- CloseHandle(hThread);
- }
- }
- } while (Thread32Next(hSnap, &te32));
- }
- CloseHandle(hSnap);
- }
- // Remove NTDLL but spoof its presence
- void SpoofNtDll(HANDLE hProcess) {
- HMODULE hNtDll = GetModuleHandleW(L"ntdll.dll");
- if (!hNtDll) return;
- // Get the base address of ntdll
- MODULEINFO modInfo;
- GetModuleInformation(GetCurrentProcess(), hNtDll, &modInfo, sizeof(modInfo));
- LPVOID ntdllBase = modInfo.lpBaseOfDll;
- // Get the ntdll base address in the target process
- LPVOID remoteNtdllBase = NULL;
- HANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32, GetProcessId(hProcess));
- if (hSnap != INVALID_HANDLE_VALUE) {
- MODULEENTRY32W me32 = { 0 };
- me32.dwSize = sizeof(MODULEENTRY32W);
- if (Module32FirstW(hSnap, &me32)) {
- do {
- if (_wcsicmp(me32.szModule, L"ntdll.dll") == 0) {
- remoteNtdllBase = me32.modBaseAddr;
- break;
- }
- } while (Module32NextW(hSnap, &me32));
- }
- CloseHandle(hSnap);
- }
- if (remoteNtdllBase) {
- // Zero out NTDLL memory in the target process
- SIZE_T bytesWritten;
- BYTE zeroBuffer[4096] = { 0 };
- for (SIZE_T i = 0; i < modInfo.SizeOfImage; i += sizeof(zeroBuffer)) {
- syscalls.NtWriteVirtualMemory(hProcess, (LPVOID)((BYTE*)remoteNtdllBase + i),
- zeroBuffer, sizeof(zeroBuffer), &bytesWritten);
- }
- }
- }
- // Manual mapping function
- LPVOID ManualMap(HANDLE hProcess, const wchar_t* dllPath) {
- // Read DLL file
- HANDLE hFile = CreateFileW(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- printf("Failed to open DLL file: %d\n", GetLastError());
- return NULL;
- }
- DWORD fileSize = GetFileSize(hFile, NULL);
- if (fileSize == INVALID_FILE_SIZE) {
- CloseHandle(hFile);
- printf("Failed to get file size: %d\n", GetLastError());
- return NULL;
- }
- LPVOID fileBuffer = VirtualAlloc(NULL, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- if (!fileBuffer) {
- CloseHandle(hFile);
- printf("Failed to allocate memory for DLL: %d\n", GetLastError());
- return NULL;
- }
- DWORD bytesRead;
- if (!ReadFile(hFile, fileBuffer, fileSize, &bytesRead, NULL) || bytesRead != fileSize) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- CloseHandle(hFile);
- printf("Failed to read DLL file: %d\n", GetLastError());
- return NULL;
- }
- CloseHandle(hFile);
- // Parse PE headers
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
- if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Invalid DOS signature\n");
- return NULL;
- }
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)fileBuffer + dosHeader->e_lfanew);
- if (ntHeader->Signature != IMAGE_NT_SIGNATURE) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Invalid NT signature\n");
- return NULL;
- }
- // Allocate memory in the target process
- LPVOID remoteImage = VirtualAllocEx(hProcess, NULL, ntHeader->OptionalHeader.SizeOfImage,
- MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if (!remoteImage) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to allocate memory in target process: %d\n", GetLastError());
- return NULL;
- }
- // Copy headers
- SIZE_T bytesWritten;
- syscalls.NtWriteVirtualMemory(hProcess, remoteImage, fileBuffer,
- ntHeader->OptionalHeader.SizeOfHeaders, &bytesWritten);
- // Copy sections
- PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeader);
- for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) {
- LPVOID destination = (LPVOID)((BYTE*)remoteImage + sectionHeader[i].VirtualAddress);
- LPVOID source = (LPVOID)((BYTE*)fileBuffer + sectionHeader[i].PointerToRawData);
- syscalls.NtWriteVirtualMemory(hProcess, destination, source,
- sectionHeader[i].SizeOfRawData, &bytesWritten);
- }
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- return remoteImage;
- }
- // Helper function for NtCreateThreadEx
- HANDLE CreateRemoteThreadEx(HANDLE hProcess, LPVOID lpStartAddress, LPVOID lpParameter) {
- HANDLE hThread = NULL;
- NTSTATUS status = syscalls.NtCreateThreadEx(
- &hThread,
- THREAD_ALL_ACCESS,
- NULL,
- hProcess,
- lpStartAddress,
- lpParameter,
- 0,
- 0,
- 0,
- 0,
- NULL
- );
- if (status != 0) {
- return NULL;
- }
- return hThread;
- }
- // Thread pool callback
- VOID CALLBACK InjectionCallback(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
- INJECTION_DATA* data = (INJECTION_DATA*)Parameter;
- SpoofNtDll(data->hProcess); // Hide ntdll
- SuspendAndSpoofThreads(data->hProcess); // Suspend and spoof ntdll-related threads
- LPVOID remoteBase = ManualMap(data->hProcess, data->dllPath);
- if (remoteBase) {
- HMODULE hLocalModule = LoadLibraryW(data->dllPath);
- if (hLocalModule) {
- FARPROC localDllMain = GetProcAddress(hLocalModule, "DllMain");
- if (localDllMain) {
- DWORD dllMainOffset = (DWORD)((BYTE*)localDllMain - (BYTE*)hLocalModule);
- LPVOID remoteDllMain = (LPVOID)((BYTE*)remoteBase + dllMainOffset);
- // Create remote thread to execute DllMain
- HANDLE hThread = CreateRemoteThreadEx(data->hProcess, remoteDllMain, remoteBase);
- if (hThread) {
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- printf("DLL entry point executed\n");
- }
- else {
- printf("Failed to create remote thread: %d\n", GetLastError());
- }
- }
- FreeLibrary(hLocalModule);
- }
- else {
- printf("Failed to load local DLL: %d\n", GetLastError());
- }
- }
- else {
- printf("Manual mapping failed\n");
- }
- data->completed = true;
- }
- // Main injection function
- bool InjectDLL(DWORD processId, const wchar_t* dllPath) {
- if (!InitializeSyscalls()) {
- printf("Failed to initialize syscalls\n");
- return false;
- }
- HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
- if (!hProcess) {
- printf("Failed to open process: %d\n", GetLastError());
- return false;
- }
- INJECTION_DATA data = { 0 };
- data.hProcess = hProcess;
- wcscpy_s(data.dllPath, dllPath);
- data.completed = false;
- PTP_WORK work = CreateThreadpoolWork(InjectionCallback, &data, NULL);
- if (!work) {
- CloseHandle(hProcess);
- printf("Failed to create thread pool work: %d\n", GetLastError());
- return false;
- }
- SubmitThreadpoolWork(work);
- // Wait for injection to complete
- while (!data.completed) {
- Sleep(100);
- }
- CloseThreadpoolWork(work);
- CloseHandle(hProcess);
- return true;
- }
- int main() {
- SetConsoleTitle(L"DLL Injector");
- printf("DLL Injector - Starting...\n");
- DWORD processId = GetRobloxProcessId(); // Automatically get Roblox process ID
- if (processId == 0) {
- printf("Roblox process not found! Please make sure Roblox is running.\n");
- printf("Press any key to exit...");
- getchar();
- return 1;
- }
- printf("Found Roblox process with ID: %d\n", processId);
- wchar_t dllPath[MAX_PATH] = L"";
- // Ask for DLL path
- printf("Enter path to DLL (or press Enter for default path): ");
- char tempPath[MAX_PATH] = "";
- fgets(tempPath, MAX_PATH, stdin);
- // Remove newline character
- tempPath[strcspn(tempPath, "\n")] = 0;
- if (strlen(tempPath) > 0) {
- // Convert to wide string
- MultiByteToWideChar(CP_ACP, 0, tempPath, -1, dllPath, MAX_PATH);
- }
- else {
- // Use default path
- wcscpy_s(dllPath, L"C:\\path\\to\\your\\dll.dll");
- }
- printf("Starting injection...\n");
- if (InjectDLL(processId, dllPath)) {
- printf("Injection successful!\n");
- }
- else {
- printf("Injection failed!\n");
- }
- printf("Press any key to exit...");
- getchar();
- return 0;
- }
- // Additional helper functions for manual mapping
- // Process relocations for the remote DLL
- bool ProcessRelocations(HANDLE hProcess, LPVOID remoteBase, LPVOID fileBuffer) {
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)fileBuffer + dosHeader->e_lfanew);
- // Calculate the delta between preferred base and actual base
- DWORD_PTR deltaBase = (DWORD_PTR)remoteBase - ntHeader->OptionalHeader.ImageBase;
- // No need for relocations if we're at the preferred base
- if (deltaBase == 0) {
- return true;
- }
- // Get the relocation directory
- PIMAGE_DATA_DIRECTORY relocDir = &ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
- if (relocDir->Size == 0) {
- // No relocations
- return true;
- }
- // Process each relocation block
- DWORD_PTR relocBase = (DWORD_PTR)fileBuffer + relocDir->VirtualAddress;
- DWORD relocSize = relocDir->Size;
- DWORD relocProcessed = 0;
- while (relocProcessed < relocSize) {
- PIMAGE_BASE_RELOCATION relocBlock = (PIMAGE_BASE_RELOCATION)(relocBase + relocProcessed);
- if (relocBlock->SizeOfBlock == 0) {
- break;
- }
- // Calculate number of entries in this block
- DWORD numEntries = (relocBlock->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
- WORD* relocEntries = (WORD*)((BYTE*)relocBlock + sizeof(IMAGE_BASE_RELOCATION));
- // Process each entry
- for (DWORD i = 0; i < numEntries; i++) {
- WORD relocData = relocEntries[i];
- DWORD relocType = relocData >> 12;
- DWORD offset = relocData & 0xFFF;
- // We only care about IMAGE_REL_BASED_HIGHLOW (x86) or IMAGE_REL_BASED_DIR64 (x64)
- if (relocType == IMAGE_REL_BASED_HIGHLOW || relocType == IMAGE_REL_BASED_DIR64) {
- // Calculate address that needs to be adjusted
- DWORD_PTR relocAddress = (DWORD_PTR)fileBuffer + relocBlock->VirtualAddress + offset;
- // Read the value
- DWORD_PTR valueToFix = 0;
- if (relocType == IMAGE_REL_BASED_HIGHLOW) {
- valueToFix = *(DWORD*)relocAddress;
- }
- else {
- valueToFix = *(DWORD_PTR*)relocAddress;
- }
- // Apply delta
- valueToFix += deltaBase;
- // Write adjusted value back to memory
- SIZE_T bytesWritten;
- DWORD_PTR remoteRelocAddress = (DWORD_PTR)remoteBase + relocBlock->VirtualAddress + offset;
- if (relocType == IMAGE_REL_BASED_HIGHLOW) {
- // 32-bit adjustment
- DWORD value32 = (DWORD)valueToFix;
- syscalls.NtWriteVirtualMemory(hProcess, (PVOID)remoteRelocAddress, &value32, sizeof(DWORD), &bytesWritten);
- }
- else {
- // 64-bit adjustment
- syscalls.NtWriteVirtualMemory(hProcess, (PVOID)remoteRelocAddress, &valueToFix, sizeof(DWORD_PTR), &bytesWritten);
- }
- }
- }
- // Move to next block
- relocProcessed += relocBlock->SizeOfBlock;
- }
- return true;
- }
- // Fix import table of the remote DLL
- bool ProcessImports(HANDLE hProcess, LPVOID remoteBase, LPVOID fileBuffer) {
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)fileBuffer + dosHeader->e_lfanew);
- // Get the import directory
- PIMAGE_DATA_DIRECTORY importDir = &ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
- if (importDir->Size == 0) {
- // No imports
- return true;
- }
- // Process each imported DLL
- PIMAGE_IMPORT_DESCRIPTOR importDesc = (PIMAGE_IMPORT_DESCRIPTOR)((BYTE*)fileBuffer + importDir->VirtualAddress);
- for (; importDesc->Name != 0; importDesc++) {
- // Get the name of the DLL
- const char* dllName = (const char*)((BYTE*)fileBuffer + importDesc->Name);
- // Load the DLL
- HMODULE hModule = LoadLibraryA(dllName);
- if (!hModule) {
- printf("Failed to load library: %s\n", dllName);
- continue;
- }
- // Process the IAT (Import Address Table)
- PIMAGE_THUNK_DATA thunk = NULL;
- PIMAGE_THUNK_DATA origThunk = NULL;
- if (importDesc->OriginalFirstThunk) {
- origThunk = (PIMAGE_THUNK_DATA)((BYTE*)fileBuffer + importDesc->OriginalFirstThunk);
- thunk = (PIMAGE_THUNK_DATA)((BYTE*)fileBuffer + importDesc->FirstThunk);
- }
- else {
- // No OriginalFirstThunk? Use FirstThunk for both
- origThunk = (PIMAGE_THUNK_DATA)((BYTE*)fileBuffer + importDesc->FirstThunk);
- thunk = (PIMAGE_THUNK_DATA)((BYTE*)fileBuffer + importDesc->FirstThunk);
- }
- // Process each function
- for (; origThunk->u1.AddressOfData != 0; origThunk++, thunk++) {
- FARPROC functionAddress = NULL;
- // Check if import by ordinal
- if (IMAGE_SNAP_BY_ORDINAL(origThunk->u1.Ordinal)) {
- functionAddress = GetProcAddress(hModule, (LPCSTR)IMAGE_ORDINAL(origThunk->u1.Ordinal));
- }
- else {
- // Import by name
- PIMAGE_IMPORT_BY_NAME importByName = (PIMAGE_IMPORT_BY_NAME)((BYTE*)fileBuffer + origThunk->u1.AddressOfData);
- functionAddress = GetProcAddress(hModule, (LPCSTR)importByName->Name);
- }
- if (!functionAddress) {
- printf("Failed to get function address\n");
- continue;
- }
- // Calculate the address in the remote process
- DWORD_PTR remoteAddress = (DWORD_PTR)remoteBase + importDesc->FirstThunk +
- ((BYTE*)thunk - (BYTE*)((BYTE*)fileBuffer + importDesc->FirstThunk));
- // Write the function address to the remote IAT
- SIZE_T bytesWritten;
- syscalls.NtWriteVirtualMemory(hProcess, (PVOID)remoteAddress, &functionAddress, sizeof(FARPROC), &bytesWritten);
- }
- }
- return true;
- }
- // Enhanced manual mapping function
- LPVOID EnhancedManualMap(HANDLE hProcess, const wchar_t* dllPath) {
- // Read DLL file
- HANDLE hFile = CreateFileW(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- printf("Failed to open DLL file: %d\n", GetLastError());
- return NULL;
- }
- DWORD fileSize = GetFileSize(hFile, NULL);
- if (fileSize == INVALID_FILE_SIZE) {
- CloseHandle(hFile);
- printf("Failed to get file size: %d\n", GetLastError());
- return NULL;
- }
- LPVOID fileBuffer = VirtualAlloc(NULL, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- if (!fileBuffer) {
- CloseHandle(hFile);
- printf("Failed to allocate memory for DLL: %d\n", GetLastError());
- return NULL;
- }
- DWORD bytesRead;
- if (!ReadFile(hFile, fileBuffer, fileSize, &bytesRead, NULL) || bytesRead != fileSize) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- CloseHandle(hFile);
- printf("Failed to read DLL file: %d\n", GetLastError());
- return NULL;
- }
- CloseHandle(hFile);
- // Parse PE headers
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
- if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Invalid DOS signature\n");
- return NULL;
- }
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)fileBuffer + dosHeader->e_lfanew);
- if (ntHeader->Signature != IMAGE_NT_SIGNATURE) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Invalid NT signature\n");
- return NULL;
- }
- // Allocate memory in the target process
- LPVOID remoteImage = VirtualAllocEx(hProcess, NULL, ntHeader->OptionalHeader.SizeOfImage,
- MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
- if (!remoteImage) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to allocate memory in target process: %d\n", GetLastError());
- return NULL;
- }
- printf("Remote image base: 0x%p\n", remoteImage);
- // Create a local copy of the image sections
- LPVOID localImage = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage,
- MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- if (!localImage) {
- VirtualFreeEx(hProcess, remoteImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to allocate local memory for image sections\n");
- return NULL;
- }
- // Copy headers to local image
- memcpy(localImage, fileBuffer, ntHeader->OptionalHeader.SizeOfHeaders);
- // Copy sections to local image
- PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeader);
- for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) {
- if (sectionHeader[i].SizeOfRawData > 0) {
- memcpy(
- (BYTE*)localImage + sectionHeader[i].VirtualAddress,
- (BYTE*)fileBuffer + sectionHeader[i].PointerToRawData,
- sectionHeader[i].SizeOfRawData
- );
- }
- }
- // Process relocations
- if (!ProcessRelocations(hProcess, remoteImage, localImage)) {
- VirtualFreeEx(hProcess, remoteImage, 0, MEM_RELEASE);
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to process relocations\n");
- return NULL;
- }
- // Process imports
- if (!ProcessImports(hProcess, remoteImage, localImage)) {
- VirtualFreeEx(hProcess, remoteImage, 0, MEM_RELEASE);
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to process imports\n");
- return NULL;
- }
- // Write the entire image to the remote process
- SIZE_T bytesWritten;
- if (!WriteProcessMemory(hProcess, remoteImage, localImage, ntHeader->OptionalHeader.SizeOfImage, &bytesWritten)) {
- VirtualFreeEx(hProcess, remoteImage, 0, MEM_RELEASE);
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to write final image to remote process: %d\n", GetLastError());
- return NULL;
- }
- // Clean up local memory
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- return remoteImage;
- }
- // Updated thread pool callback using enhanced manual mapping
- VOID CALLBACK EnhancedInjectionCallback(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
- INJECTION_DATA* data = (INJECTION_DATA*)Parameter;
- printf("Starting injection process...\n");
- // Spoof NTDLL and suspend threads first
- printf("Applying anti-detection measures...\n");
- SpoofNtDll(data->hProcess);
- SuspendAndSpoofThreads(data->hProcess);
- printf("Performing manual mapping...\n");
- LPVOID remoteBase = EnhancedManualMap(data->hProcess, data->dllPath);
- if (remoteBase) {
- HMODULE hLocalModule = LoadLibraryW(data->dllPath);
- if (hLocalModule) {
- FARPROC localDllMain = GetProcAddress(hLocalModule, "DllMain");
- if (localDllMain) {
- DWORD dllMainOffset = (DWORD)((BYTE*)localDllMain - (BYTE*)hLocalModule);
- LPVOID remoteDllMain = (LPVOID)((BYTE*)remoteBase + dllMainOffset);
- printf("Executing remote DllMain at 0x%p...\n", remoteDllMain);
- // Create remote thread to execute DllMain with proper parameters
- HANDLE hThread = CreateRemoteThreadEx(
- data->hProcess,
- remoteDllMain,
- remoteBase
- );
- if (hThread) {
- printf("Waiting for DllMain execution...\n");
- WaitForSingleObject(hThread, INFINITE);
- DWORD exitCode = 0;
- GetExitCodeThread(hThread, &exitCode);
- printf("DllMain execution completed with exit code: %d\n", exitCode);
- CloseHandle(hThread);
- }
- else {
- printf("Failed to create remote thread: %d\n", GetLastError());
- }
- }
- else {
- printf("Warning: DllMain not found in the DLL\n");
- }
- FreeLibrary(hLocalModule);
- }
- else {
- printf("Failed to load local DLL: %d\n", GetLastError());
- }
- }
- else {
- printf("Manual mapping failed\n");
- }
- data->completed = true;
- }
- // Update
- // Advanced protection feature: Detect debuggers and anti-cheat systems
- bool IsBeingDebugged(HANDLE hProcess) {
- BOOL isDebuggerPresent = FALSE;
- // Check for user-mode debugger
- if (CheckRemoteDebuggerPresent(hProcess, &isDebuggerPresent) && isDebuggerPresent) {
- return true;
- }
- // Check for system debugger flags in PEB
- PROCESS_BASIC_INFORMATION pbi;
- ULONG returnLength;
- typedef NTSTATUS(NTAPI* pNtQueryInformationProcess)(
- IN HANDLE ProcessHandle,
- IN PROCESSINFOCLASS ProcessInformationClass,
- OUT PVOID ProcessInformation,
- IN ULONG ProcessInformationLength,
- OUT PULONG ReturnLength OPTIONAL
- );
- pNtQueryInformationProcess NtQueryInformationProcess = (pNtQueryInformationProcess)
- GetProcAddress(GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
- if (NtQueryInformationProcess &&
- NT_SUCCESS(NtQueryInformationProcess(
- hProcess,
- ProcessBasicInformation,
- &pbi,
- sizeof(PROCESS_BASIC_INFORMATION),
- &returnLength))) {
- // Get PEB address
- PEB peb;
- SIZE_T bytesRead;
- if (ReadProcessMemory(hProcess, pbi.PebBaseAddress, &peb, sizeof(PEB), &bytesRead)) {
- // Check BeingDebugged flag
- if (peb.BeingDebugged) {
- return true;
- }
- // Check NtGlobalFlag (0x70 is the debug flag combination)
- DWORD ntGlobalFlag = 0;
- if (ReadProcessMemory(hProcess,
- (PVOID)((PBYTE)pbi.PebBaseAddress + offsetof(PEB, NtGlobalFlag)),
- &ntGlobalFlag, sizeof(DWORD), &bytesRead)) {
- if (ntGlobalFlag & 0x70) {
- return true;
- }
- }
- }
- }
- return false;
- }
- // Check for common anti-cheat processes
- bool DetectAntiCheat() {
- const wchar_t* antiCheatProcesses[] = {
- L"BEService.exe", // BattlEye
- L"EasyAntiCheat.exe", // EAC
- L"vanguard.exe", // Riot Vanguard
- L"faceit-ac-client.exe", // FACEIT
- L"mhyprot2.sys", // miHoYo
- L"xigncode3.exe", // XIGNCODE3
- L"GameGuard.des", // NProtect GameGuard
- NULL
- };
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (snapshot == INVALID_HANDLE_VALUE) {
- return false;
- }
- PROCESSENTRY32W entry;
- entry.dwSize = sizeof(PROCESSENTRY32W);
- bool found = false;
- if (Process32FirstW(snapshot, &entry)) {
- do {
- // Check against our list of known anti-cheat processes
- for (int i = 0; antiCheatProcesses[i] != NULL; i++) {
- if (_wcsicmp(entry.szExeFile, antiCheatProcesses[i]) == 0) {
- printf("Detected anti-cheat: %ws\n", entry.szExeFile);
- found = true;
- break;
- }
- }
- if (found) break;
- } while (Process32NextW(snapshot, &entry));
- }
- CloseHandle(snapshot);
- return found;
- }
- // Enhanced injection function with anti-cheat detection and safety features
- bool EnhancedInjectDLL(DWORD processId, const wchar_t* dllPath) {
- if (!InitializeSyscalls()) {
- printf("Failed to initialize syscalls\n");
- return false;
- }
- // Check for anti-cheat systems
- if (DetectAntiCheat()) {
- printf("WARNING: Anti-cheat software detected! Injection may be detected.\nContinue? (y/n): ");
- char response;
- scanf_s(" %c", &response, 1);
- if (response != 'y' && response != 'Y') {
- printf("Injection aborted by user.\n");
- return false;
- }
- }
- HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
- if (!hProcess) {
- printf("Failed to open process: %d\n", GetLastError());
- return false;
- }
- // Check if process is being debugged
- if (IsBeingDebugged(hProcess)) {
- printf("WARNING: Target process appears to be debugged! This may affect injection.\n");
- printf("Continue? (y/n): ");
- char response;
- scanf_s(" %c", &response, 1);
- if (response != 'y' && response != 'Y') {
- CloseHandle(hProcess);
- printf("Injection aborted by user.\n");
- return false;
- }
- }
- // Set up injection data
- INJECTION_DATA data = { 0 };
- data.hProcess = hProcess;
- wcscpy_s(data.dllPath, dllPath);
- data.completed = false;
- // Create thread pool work
- PTP_WORK work = CreateThreadpoolWork(EnhancedInjectionCallback, &data, NULL);
- if (!work) {
- CloseHandle(hProcess);
- printf("Failed to create thread pool work: %d\n", GetLastError());
- return false;
- }
- printf("Submitting injection task to thread pool...\n");
- SubmitThreadpoolWork(work);
- // Wait for injection to complete with progress indicator
- int dots = 0;
- while (!data.completed) {
- printf("\rWaiting for injection completion%.*s ", dots, "...");
- dots = (dots + 1) % 4;
- Sleep(250);
- }
- printf("\rInjection process completed \n");
- CloseThreadpoolWork(work);
- CloseHandle(hProcess);
- return true;
- }
- // File system validation
- bool ValidateDllFile(const wchar_t* dllPath) {
- // Check if file exists
- if (GetFileAttributesW(dllPath) == INVALID_FILE_ATTRIBUTES) {
- printf("Error: DLL file does not exist.\n");
- return false;
- }
- // Verify it's a DLL file (check PE header)
- HANDLE hFile = CreateFileW(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- printf("Error: Could not open DLL file.\n");
- return false;
- }
- bool valid = false;
- // Read DOS header
- IMAGE_DOS_HEADER dosHeader = { 0 };
- DWORD bytesRead = 0;
- if (ReadFile(hFile, &dosHeader, sizeof(IMAGE_DOS_HEADER), &bytesRead, NULL) &&
- bytesRead == sizeof(IMAGE_DOS_HEADER)) {
- // Check DOS signature
- if (dosHeader.e_magic == IMAGE_DOS_SIGNATURE) {
- // Seek to PE header
- SetFilePointer(hFile, dosHeader.e_lfanew, NULL, FILE_BEGIN);
- // Read NT header signature
- DWORD ntSignature = 0;
- if (ReadFile(hFile, &ntSignature, sizeof(DWORD), &bytesRead, NULL) &&
- bytesRead == sizeof(DWORD)) {
- // Check NT signature
- if (ntSignature == IMAGE_NT_SIGNATURE) {
- valid = true;
- }
- else {
- printf("Error: Not a valid PE file (invalid NT signature).\n");
- }
- }
- }
- else {
- printf("Error: Not a valid PE file (invalid DOS signature).\n");
- }
- }
- CloseHandle(hFile);
- return valid;
- }
- // Main function with improved UI
- int main() {
- SetConsoleTitle(L"Advanced DLL Injector");
- // Console UI enhancements
- HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- GetConsoleScreenBufferInfo(hConsole, &csbi);
- // Set console text colors
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
- printf("===========================================\n");
- printf(" ADVANCED DLL INJECTOR v1.0 \n");
- printf("===========================================\n\n");
- // Reset colors
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- // Process selection
- DWORD processId = 0;
- int choice = 0;
- printf("Select target process:\n");
- printf("1. Automatic (Roblox)\n");
- printf("2. Manual (Enter PID)\n");
- printf("Choice: ");
- scanf_s("%d", &choice);
- // Clear input buffer
- while (getchar() != '\n');
- if (choice == 1) {
- // Automatic (Roblox)
- processId = GetRobloxProcessId();
- if (processId == 0) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nRoblox process not found! Please make sure Roblox is running.\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
- printf("\nFound Roblox process with ID: %d\n", processId);
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- }
- else if (choice == 2) {
- // Manual (Enter PID)
- printf("\nEnter process ID (PID): ");
- scanf_s("%d", &processId);
- // Clear input buffer
- while (getchar() != '\n');
- // Verify the process exists
- HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
- if (!hProcess) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nError: Process with ID %d not found or access denied.\n", processId);
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- CloseHandle(hProcess);
- }
- else {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nInvalid choice!\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- // DLL selection
- wchar_t dllPath[MAX_PATH] = L"";
- printf("\nEnter path to DLL (or press Enter for default path): ");
- // Get input (support spaces in path)
- char tempPath[MAX_PATH] = "";
- fgets(tempPath, MAX_PATH, stdin);
- // Remove newline character
- tempPath[strcspn(tempPath, "\n")] = 0;
- if (strlen(tempPath) > 0) {
- // Convert to wide string
- MultiByteToWideChar(CP_ACP, 0, tempPath, -1, dllPath, MAX_PATH);
- }
- else {
- // Use default path
- wcscpy_s(dllPath, L"C:\\path\\to\\your\\dll.dll");
- }
- // Validate DLL file
- if (!ValidateDllFile(dllPath)) {
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- // Start injection process
- SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
- printf("\nStarting injection process...\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- if (EnhancedInjectDLL(processId, dllPath)) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
- printf("\nInjection successful!\n");
- }
- else {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nInjection failed!\n");
- }
- // Reset colors
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 0;
- }
- // Add definition for PEB structure
- typedef struct _PEB {
- BYTE Reserved1[2];
- BYTE BeingDebugged;
- BYTE Reserved2[1];
- PVOID Reserved3[2];
- PVOID Ldr;
- PVOID ProcessParameters;
- PVOID Reserved4[3];
- PVOID AtlThunkSListPtr;
- PVOID Reserved5;
- ULONG Reserved6;
- PVOID Reserved7;
- ULONG Reserved8;
- ULONG AtlThunkSListPtr32;
- PVOID Reserved9[45];
- BYTE Reserved10[96];
- PVOID PostProcessInitRoutine;
- BYTE Reserved11[128];
- PVOID Reserved12[1];
- ULONG SessionId;
- } PEB, * PPEB;
- // Define ProcessInformationClass enum
- typedef enum _PROCESSINFOCLASS {
- ProcessBasicInformation = 0,
- // Other values omitted for brevity
- } PROCESSINFOCLASS;
- // Define PROCESS_BASIC_INFORMATION structure
- typedef struct _PROCESS_BASIC_INFORMATION {
- PVOID Reserved1;
- PPEB PebBaseAddress;
- PVOID Reserved2[2];
- ULONG_PTR UniqueProcessId;
- PVOID Reserved3;
- } PROCESS_BASIC_INFORMATION;
- // Define NT_SUCCESS macro
- #define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
- // Advanced feature: Handling TLS callbacks
- bool ProcessTlsCallbacks(HANDLE hProcess, LPVOID remoteBase, LPVOID fileBuffer) {
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)fileBuffer + dosHeader->e_lfanew);
- // Get the TLS directory
- PIMAGE_DATA_DIRECTORY tlsDir = &ntHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_TLS];
- if (tlsDir->Size == 0) {
- // No TLS callbacks
- return true;
- }
- // Get the TLS directory
- PIMAGE_TLS_DIRECTORY tlsDirectory = (PIMAGE_TLS_DIRECTORY)((BYTE*)fileBuffer + tlsDir->VirtualAddress);
- // Check if there are callbacks
- if (tlsDirectory->AddressOfCallBacks == 0) {
- return true;
- }
- // Calculate the remote address of the TLS callbacks
- DWORD_PTR localCallbacksAddr = tlsDirectory->AddressOfCallBacks;
- DWORD_PTR remoteCallbacksAddr = (DWORD_PTR)remoteBase +
- (localCallbacksAddr - (DWORD_PTR)fileBuffer);
- // Execute each TLS callback
- PIMAGE_TLS_CALLBACK* callbacks = (PIMAGE_TLS_CALLBACK*)localCallbacksAddr;
- for (int i = 0; callbacks[i] != NULL; i++) {
- DWORD_PTR callbackRVA = (DWORD_PTR)callbacks[i] - (DWORD_PTR)fileBuffer;
- LPVOID remoteCallback = (LPVOID)((BYTE*)remoteBase + callbackRVA);
- // Create a thread to execute the TLS callback
- HANDLE hThread = CreateRemoteThreadEx(
- hProcess,
- remoteCallback,
- remoteBase
- );
- if (hThread) {
- WaitForSingleObject(hThread, INFINITE);
- CloseHandle(hThread);
- }
- else {
- printf("Warning: Failed to execute TLS callback at 0x%p\n", remoteCallback);
- }
- }
- return true;
- }
- // Add memory protection features
- bool SetProperMemoryProtections(HANDLE hProcess, LPVOID remoteBase, LPVOID fileBuffer) {
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)fileBuffer + dosHeader->e_lfanew);
- // Set proper memory protection for each section
- PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeader);
- for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) {
- DWORD protection = PAGE_NOACCESS; // Default
- DWORD characteristics = sectionHeader[i].Characteristics;
- // Determine protection based on section characteristics
- if (characteristics & IMAGE_SCN_MEM_EXECUTE) {
- if (characteristics & IMAGE_SCN_MEM_WRITE) {
- protection = PAGE_EXECUTE_READWRITE;
- }
- else if (characteristics & IMAGE_SCN_MEM_READ) {
- protection = PAGE_EXECUTE_READ;
- }
- else {
- protection = PAGE_EXECUTE;
- }
- }
- else if (characteristics & IMAGE_SCN_MEM_WRITE) {
- protection = PAGE_READWRITE;
- }
- else if (characteristics & IMAGE_SCN_MEM_READ) {
- protection = PAGE_READONLY;
- }
- // Apply memory protection
- LPVOID sectionAddress = (LPVOID)((BYTE*)remoteBase + sectionHeader[i].VirtualAddress);
- DWORD oldProtection;
- if (!VirtualProtectEx(
- hProcess,
- sectionAddress,
- sectionHeader[i].Misc.VirtualSize,
- protection,
- &oldProtection)) {
- printf("Warning: Failed to set proper memory protection for section %d\n", i);
- }
- }
- return true;
- }
- // Complete enhanced manual mapping process
- LPVOID CompleteManualMap(HANDLE hProcess, const wchar_t* dllPath) {
- // Read DLL file
- HANDLE hFile = CreateFileW(dllPath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
- if (hFile == INVALID_HANDLE_VALUE) {
- printf("Failed to open DLL file: %d\n", GetLastError());
- return NULL;
- }
- DWORD fileSize = GetFileSize(hFile, NULL);
- if (fileSize == INVALID_FILE_SIZE) {
- CloseHandle(hFile);
- printf("Failed to get file size: %d\n", GetLastError());
- return NULL;
- }
- LPVOID fileBuffer = VirtualAlloc(NULL, fileSize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- if (!fileBuffer) {
- CloseHandle(hFile);
- printf("Failed to allocate memory for DLL: %d\n", GetLastError());
- return NULL;
- }
- DWORD bytesRead;
- if (!ReadFile(hFile, fileBuffer, fileSize, &bytesRead, NULL) || bytesRead != fileSize) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- CloseHandle(hFile);
- printf("Failed to read DLL file: %d\n", GetLastError());
- return NULL;
- }
- CloseHandle(hFile);
- // Parse PE headers
- PIMAGE_DOS_HEADER dosHeader = (PIMAGE_DOS_HEADER)fileBuffer;
- if (dosHeader->e_magic != IMAGE_DOS_SIGNATURE) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Invalid DOS signature\n");
- return NULL;
- }
- PIMAGE_NT_HEADERS ntHeader = (PIMAGE_NT_HEADERS)((BYTE*)fileBuffer + dosHeader->e_lfanew);
- if (ntHeader->Signature != IMAGE_NT_SIGNATURE) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Invalid NT signature\n");
- return NULL;
- }
- // Check architecture compatibility
- if (ntHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_AMD64 &&
- ntHeader->FileHeader.Machine != IMAGE_FILE_MACHINE_I386) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Unsupported architecture: 0x%04X\n", ntHeader->FileHeader.Machine);
- return NULL;
- }
- printf("DLL architecture: %s\n",
- ntHeader->FileHeader.Machine == IMAGE_FILE_MACHINE_AMD64 ? "x64" : "x86");
- // Create local image
- LPVOID localImage = VirtualAlloc(NULL, ntHeader->OptionalHeader.SizeOfImage,
- MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
- if (!localImage) {
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to allocate memory for local image\n");
- return NULL;
- }
- // Copy headers to local image
- memcpy(localImage, fileBuffer, ntHeader->OptionalHeader.SizeOfHeaders);
- // Copy sections to local image
- PIMAGE_SECTION_HEADER sectionHeader = IMAGE_FIRST_SECTION(ntHeader);
- for (int i = 0; i < ntHeader->FileHeader.NumberOfSections; i++) {
- if (sectionHeader[i].SizeOfRawData > 0) {
- memcpy(
- (BYTE*)localImage + sectionHeader[i].VirtualAddress,
- (BYTE*)fileBuffer + sectionHeader[i].PointerToRawData,
- sectionHeader[i].SizeOfRawData
- );
- }
- }
- // Allocate memory in target process
- LPVOID remoteImage = VirtualAllocEx(
- hProcess,
- NULL,
- ntHeader->OptionalHeader.SizeOfImage,
- MEM_COMMIT | MEM_RESERVE,
- PAGE_EXECUTE_READWRITE
- );
- if (!remoteImage) {
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to allocate memory in target process: %d\n", GetLastError());
- return NULL;
- }
- printf("Remote image allocated at 0x%p\n", remoteImage);
- // Process relocations
- if (!ProcessRelocations(hProcess, remoteImage, localImage)) {
- VirtualFreeEx(hProcess, remoteImage, 0, MEM_RELEASE);
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to process relocations\n");
- return NULL;
- }
- // Process imports
- if (!ProcessImports(hProcess, remoteImage, localImage)) {
- VirtualFreeEx(hProcess, remoteImage, 0, MEM_RELEASE);
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to process imports\n");
- return NULL;
- }
- // Write the processed image to the target process
- SIZE_T bytesWritten;
- if (!WriteProcessMemory(
- hProcess,
- remoteImage,
- localImage,
- ntHeader->OptionalHeader.SizeOfImage,
- &bytesWritten)) {
- VirtualFreeEx(hProcess, remoteImage, 0, MEM_RELEASE);
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- printf("Failed to write image to remote process: %d\n", GetLastError());
- return NULL;
- }
- // Process TLS callbacks
- ProcessTlsCallbacks(hProcess, remoteImage, localImage);
- // Set proper memory protections
- SetProperMemoryProtections(hProcess, remoteImage, localImage);
- // Calculate entry point address
- LPVOID remoteEntryPoint = (LPVOID)((BYTE*)remoteImage + ntHeader->OptionalHeader.AddressOfEntryPoint);
- printf("DLL entry point at 0x%p\n", remoteEntryPoint);
- // Clean up local memory
- VirtualFree(localImage, 0, MEM_RELEASE);
- VirtualFree(fileBuffer, 0, MEM_RELEASE);
- return remoteImage;
- }
- // Complete injection callback
- VOID CALLBACK CompleteInjectionCallback(PTP_CALLBACK_INSTANCE Instance, PVOID Parameter, PTP_WORK Work) {
- INJECTION_DATA* data = (INJECTION_DATA*)Parameter;
- printf("Starting enhanced injection process...\n");
- // Apply anti-detection measures
- printf("Applying anti-detection measures...\n");
- SpoofNtDll(data->hProcess);
- SuspendAndSpoofThreads(data->hProcess);
- printf("Performing complete manual mapping...\n");
- LPVOID remoteBase = CompleteManualMap(data->hProcess, data->dllPath);
- if (remoteBase) {
- // Calculate DllMain offset and address
- HMODULE hLocalModule = LoadLibraryW(data->dllPath);
- if (hLocalModule) {
- FARPROC localDllMain = GetProcAddress(hLocalModule, "DllMain");
- if (localDllMain) {
- DWORD dllMainOffset = (DWORD)((BYTE*)localDllMain - (BYTE*)hLocalModule);
- LPVOID remoteDllMain = (LPVOID)((BYTE*)remoteBase + dllMainOffset);
- printf("Executing DllMain at 0x%p...\n", remoteDllMain);
- // Create remote thread to execute DllMain with proper parameters (DLL_PROCESS_ATTACH)
- HANDLE hThread = CreateRemoteThreadEx(
- data->hProcess,
- remoteDllMain,
- (LPVOID)((DWORD_PTR)remoteBase | 1) // DLL_PROCESS_ATTACH = 1
- );
- if (hThread) {
- printf("Waiting for DllMain execution...\n");
- WaitForSingleObject(hThread, INFINITE);
- DWORD exitCode = 0;
- GetExitCodeThread(hThread, &exitCode);
- printf("DllMain execution completed with exit code: %d\n", exitCode);
- CloseHandle(hThread);
- }
- else {
- printf("Failed to create remote thread: %d\n", GetLastError());
- }
- }
- else {
- printf("Warning: DllMain not found in the DLL\n");
- }
- FreeLibrary(hLocalModule);
- }
- else {
- printf("Failed to load local DLL: %d\n", GetLastError());
- }
- }
- else {
- printf("Complete manual mapping failed\n");
- }
- data->completed = true;
- }
- // Final injection function that uses the most complete implementation
- bool FinalInjectDLL(DWORD processId, const wchar_t* dllPath) {
- if (!InitializeSyscalls()) {
- printf("Failed to initialize syscalls\n");
- return false;
- }
- // Check for anti-cheat systems
- if (DetectAntiCheat()) {
- printf("WARNING: Anti-cheat software detected! Injection may be detected.\nContinue? (y/n): ");
- char response;
- scanf_s(" %c", &response, 1);
- if (response != 'y' && response != 'Y') {
- printf("Injection aborted by user.\n");
- return false;
- }
- }
- HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processId);
- if (!hProcess) {
- printf("Failed to open process: %d\n", GetLastError());
- return false;
- }
- // Check if process is being debugged
- if (IsBeingDebugged(hProcess)) {
- printf("WARNING: Target process appears to be debugged! This may affect injection.\n");
- printf("Continue? (y/n): ");
- char response;
- scanf_s(" %c", &response, 1);
- if (response != 'y' && response != 'Y') {
- CloseHandle(hProcess);
- printf("Injection aborted by user.\n");
- return false;
- }
- }
- // Set up injection data
- INJECTION_DATA data = { 0 };
- data.hProcess = hProcess;
- wcscpy_s(data.dllPath, dllPath);
- data.completed = false;
- // Create thread pool work
- PTP_WORK work = CreateThreadpoolWork(CompleteInjectionCallback, &data, NULL);
- if (!work) {
- CloseHandle(hProcess);
- printf("Failed to create thread pool work: %d\n", GetLastError());
- return false;
- }
- // idk if the code below is looping or not but i tried to get claude in another conversation to
- // finish it
- printf("Submitting final injection task to thread pool...\n");
- SubmitThreadpoolWork(work);
- // Wait for injection to complete with animated progress indicator
- int dots = 0;
- const char* spinner = "|/-\\";
- int spinnerPos = 0;
- while (!data.completed) {
- printf("\rInjection in progress %c %.*s ",
- spinner[spinnerPos], dots, "...");
- spinnerPos = (spinnerPos + 1) % 4;
- dots = (dots + 1) % 4;
- Sleep(100);
- }
- printf("\rInjection process completed \n");
- CloseThreadpoolWork(work);
- CloseHandle(hProcess);
- return true;
- }
- // Updated main function with the most robust injection method
- int main() {
- SetConsoleTitle(L"Ultimate DLL Injector");
- // Console UI enhancements
- HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
- CONSOLE_SCREEN_BUFFER_INFO csbi;
- GetConsoleScreenBufferInfo(hConsole, &csbi);
- // Set console text colors - heading
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_INTENSITY);
- printf("===========================================\n");
- printf(" ULTIMATE DLL INJECTOR v2.0 \n");
- printf("===========================================\n\n");
- // Reset colors
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- // Process selection
- DWORD processId = 0;
- int choice = 0;
- printf("Select target process:\n");
- printf("1. Automatic (Roblox)\n");
- printf("2. Manual (Enter PID)\n");
- printf("3. Select from process list\n");
- printf("Choice: ");
- scanf_s("%d", &choice);
- // Clear input buffer
- while (getchar() != '\n');
- if (choice == 1) {
- // Automatic (Roblox)
- processId = GetRobloxProcessId();
- if (processId == 0) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nRoblox process not found! Please make sure Roblox is running.\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
- printf("\nFound Roblox process with ID: %d\n", processId);
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- }
- else if (choice == 2) {
- // Manual (Enter PID)
- printf("\nEnter process ID (PID): ");
- scanf_s("%d", &processId);
- // Clear input buffer
- while (getchar() != '\n');
- // Verify the process exists
- HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, processId);
- if (!hProcess) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nError: Process with ID %d not found or access denied.\n", processId);
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- // Get process name
- wchar_t processName[MAX_PATH] = L"<unknown>";
- DWORD size = MAX_PATH;
- QueryFullProcessImageNameW(hProcess, 0, processName, &size);
- CloseHandle(hProcess);
- printf("Selected process: %ls\n", processName);
- }
- else if (choice == 3) {
- // Show process list
- printf("\nAvailable processes:\n");
- printf("--------------------\n");
- HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (snapshot == INVALID_HANDLE_VALUE) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("Error: Failed to get process list.\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- PROCESSENTRY32W entry;
- entry.dwSize = sizeof(PROCESSENTRY32W);
- int count = 0;
- const int MAX_DISPLAY = 20;
- std::vector<DWORD> processIds;
- std::vector<std::wstring> processNames;
- if (Process32FirstW(snapshot, &entry)) {
- do {
- // Skip system processes
- HANDLE hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, FALSE, entry.th32ProcessID);
- if (hProcess) {
- // Store process info
- processIds.push_back(entry.th32ProcessID);
- processNames.push_back(entry.szExeFile);
- printf("%d. %ls (PID: %d)\n", ++count, entry.szExeFile, entry.th32ProcessID);
- CloseHandle(hProcess);
- if (count >= MAX_DISPLAY) {
- printf("... (More processes not shown)\n");
- break;
- }
- }
- } while (Process32NextW(snapshot, &entry));
- }
- CloseHandle(snapshot);
- int processChoice = 0;
- printf("\nSelect process number (1-%d): ", count);
- scanf_s("%d", &processChoice);
- // Clear input buffer
- while (getchar() != '\n');
- if (processChoice < 1 || processChoice > count) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("Invalid selection!\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- processId = processIds[processChoice - 1];
- printf("Selected process: %ls (PID: %d)\n", processNames[processChoice - 1].c_str(), processId);
- }
- else {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nInvalid choice!\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- // DLL selection
- wchar_t dllPath[MAX_PATH] = L"";
- printf("\nEnter path to DLL (or press Enter for file browser): ");
- // Get input (support spaces in path)
- char tempPath[MAX_PATH] = "";
- fgets(tempPath, MAX_PATH, stdin);
- // Remove newline character
- tempPath[strcspn(tempPath, "\n")] = 0;
- if (strlen(tempPath) > 0) {
- // Convert to wide string
- MultiByteToWideChar(CP_ACP, 0, tempPath, -1, dllPath, MAX_PATH);
- }
- else {
- // Use file browser dialog
- OPENFILENAMEW ofn = { 0 };
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = NULL;
- ofn.lpstrFilter = L"DLL Files (*.dll)\0*.dll\0All Files (*.*)\0*.*\0";
- ofn.lpstrFile = dllPath;
- ofn.nMaxFile = MAX_PATH;
- ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY;
- ofn.lpstrDefExt = L"dll";
- if (!GetOpenFileNameW(&ofn)) {
- // User canceled file dialog
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nNo DLL selected. Operation canceled.\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- }
- printf("Selected DLL: %ls\n", dllPath);
- // Validate DLL file
- if (!ValidateDllFile(dllPath)) {
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 1;
- }
- // Injection method selection
- int injectionMethod = 0;
- printf("\nSelect injection method:\n");
- printf("1. Standard (Faster, less stealthy)\n");
- printf("2. Enhanced (Balanced approach)\n");
- printf("3. Complete (Most stealthy, more reliable)\n");
- printf("Choice: ");
- scanf_s("%d", &injectionMethod);
- // Clear input buffer
- while (getchar() != '\n');
- // Start injection process
- SetConsoleTextAttribute(hConsole, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_INTENSITY);
- printf("\nStarting injection process...\n");
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- bool success = false;
- switch (injectionMethod) {
- case 1:
- success = InjectDLL(processId, dllPath);
- break;
- case 2:
- success = EnhancedInjectDLL(processId, dllPath);
- break;
- case 3:
- success = FinalInjectDLL(processId, dllPath);
- break;
- default:
- // Default to most reliable method
- printf("Invalid choice, using Complete injection method...\n");
- success = FinalInjectDLL(processId, dllPath);
- break;
- }
- if (success) {
- SetConsoleTextAttribute(hConsole, FOREGROUND_GREEN | FOREGROUND_INTENSITY);
- printf("\nInjection successful!\n");
- }
- else {
- SetConsoleTextAttribute(hConsole, FOREGROUND_RED | FOREGROUND_INTENSITY);
- printf("\nInjection failed!\n");
- }
- // Reset colors
- SetConsoleTextAttribute(hConsole, csbi.wAttributes);
- printf("\nPress Enter to exit...");
- getchar();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement