I am having a problem with CreateRemoteThread(). I spent the last 3 days trying to figure it out and I am loosing my mind.
When I use the function CreateRemoteThread() the function returns NULL and if I use getLastError() I get error 6 (which means invalid handle). I was trying to inject my own dll into a notepad.exe process and I got this error and the injection did not happened. I used the following in order to get the process handle => HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,processID);
Then I tried the following HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS,FALSE,GetCurrentPoccessID()); which is exact the same except the dll is being injected into the current process being executed and it worked. I am kind of assuming it's a permission issue, but I have turned off all AVs including windows defender. I really want to know what is preventing me from performing the injection as everyone else seams to be able to perform the injection using a similar code. I am using a windows 11 64bits system. find below the injection code and dll code. Note
1: .dll and .exe are x64 bits
2: I am running it as adm
3: how I compiled the .dll x86_64-w64-mingw32-g++ -shared -o mydll.dll mydll.cpp
4: vs code compiler configurations:
{
"configurations": [
{
"name": "Win64",
"includePath": [
"${workspaceFolder}/**",
"c:/**"
],
"defines": [
"_DEBUG",
"UNICODE",
"_UNICODE"
],
"compilerPath": "C:\\msys64\\mingw64\\bin\\gcc.exe",
"cStandard": "c17",
"cppStandard": "gnu++17",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}
[UPDATE] *I created a process and compiled it the same way I compiled the injector.cpp, I was able to inject to the process :D.. So the issue is how I am complying the .dll * here is my system details: 64-bit operating system, ARM-based processor
injection.cpp
#include <windows.h>
#include <iostream>
int main(int argc, char* argv[])
{if (argc < 2) {
printf("(--) usage: dll.exe <pid>");
return EXIT_FAILURE;
}
DWORD PID = atoi(argv[1]);
// Path to the target process
const char* targetProcess = "C:\\Windows\\System32\\notepad.exe";
// Path to the DLL to inject
const char* dllPath = "C:\\Users\\fagner\\Desktop\\windowsM\\dll\\dlli2.dll";
// Load the target process
HANDLE hProcess = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION | PROCESS_CREATE_THREAD, FALSE,PID);// if I replace process ID with GetCurrentProcessId() it works
if (hProcess == NULL)
{
std::cout << GetLastError() << std::endl;
return 1;
}
std::cout<<"id: "<<hProcess<<std::endl;
// Allocate memory for the DLL path in the target process
LPVOID dllPathAddress = VirtualAllocEx(hProcess, NULL, strlen(dllPath) + 1, MEM_COMMIT, PAGE_READWRITE);
if (dllPathAddress == NULL)
{
std::cout << GetLastError() << std::endl;
CloseHandle(hProcess);
return 1;
}
// Write the DLL path into the target process
if (!WriteProcessMemory(hProcess, dllPathAddress, dllPath, strlen(dllPath) + 1, NULL))
{ std::cout << GetLastError() << std::endl;
VirtualFreeEx(hProcess, dllPathAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}
// Get the address of the LoadLibraryA function
HMODULE hKernel32 = GetModuleHandle(TEXT("kernel32.dll"));
if (hKernel32 == NULL)
{
std::cout << GetLastError() << std::endl;
VirtualFreeEx(hProcess, dllPathAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}
LPTHREAD_START_ROUTINE loadLibraryAddr = (LPTHREAD_START_ROUTINE)GetProcAddress(hKernel32, "LoadLibraryA");
if (loadLibraryAddr == NULL)
{
std::cout << GetLastError() << std::endl;
VirtualFreeEx(hProcess, dllPathAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}
// Create a remote thread in the target process to load the DLL
HANDLE hThread = CreateRemoteThread(hProcess, NULL, 0, loadLibraryAddr, dllPathAddress, 0, NULL);
// when I use another process such as notepad createRemoteThread returns NULL
if (hThread == NULL)
{
// when I target any other porcess GetLasterror() returns 6 which mean "invalid error"
std::cout << GetLastError() << std::endl;
VirtualFreeEx(hProcess, dllPathAddress, 0, MEM_RELEASE);
CloseHandle(hProcess);
return 1;
}
std::cout << "DLL injected successfully!" << std::endl;
// Wait for the remote thread to finish
WaitForSingleObject(hThread, INFINITE);
// Clean up resources
VirtualFreeEx(hProcess, dllPathAddress, 0, MEM_RELEASE);
CloseHandle(hThread);
CloseHandle(hProcess);
return 0;
}
dlli.dll
#include <Windows.h>
#include <fstream>
BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch (ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
// Create a file called "injected.txt" in the current directory
std::ofstream file("injected.txt");
if (file.is_open())
{
file << "DLL Injected Successfully!" << std::endl;
file.close();
}
break;
}
return TRUE;
}```
It looks like windows 11 does not allow remote threads to be created into process signed by Microsoft. As I was testing dll injection in a new windows VM I only had Microsoft process to test on. I was able to inject into Several other process that weren't signed by Microsoft.