-1

Here is some code this is supposed to inject my DLL and run it in notepad.exe but as the title states the CreateRemoteThread call returns null MyGetProcessId works just fine I made it and checked its results to see if the pid was right and it was.

#define DLL_PATH "C:\\Users\\tkina\\Desktop\\3\\Dll1\\Debug\\Dll1.dll"
#include <Windows.h>
#include <iostream>
#include <tlhelp32.h>

DWORD MyGetProcessId(LPCTSTR ProcessName);

int main()
{
    TCHAR Buffer[MAX_PATH];
    DWORD err;

    // Get full path of DLL to inject
    DWORD pathLen = GetFullPathName(TEXT("mydll.dll"), MAX_PATH, Buffer, NULL);
    PVOID addrLoadLibrary = (PVOID)GetProcAddress(GetModuleHandle(Buffer), "LoadLibraryA");
    DWORD pID = MyGetProcessId(TEXT("Notepad.exe"));
    // Open remote process
    HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pID);
    if (!proc)
    {
        std::cout << "Could not open the process!\n";
        system("pause");
    }
    // Get a pointer to memory location in remote process,
    // big enough to store DLL path
    PVOID memAddr = (PVOID)VirtualAllocEx(proc, 0, strlen(DLL_PATH)+1, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    if (NULL == memAddr) {
        err = GetLastError();
        return 0;
    }
    // Write DLL name to remote process memory
    BOOL check = WriteProcessMemory(proc, memAddr, (LPVOID)DLL_PATH, strlen(DLL_PATH) + 1, NULL);
    if (0 == check) {
        err = GetLastError();
        return 0;
    }
    // Open remote thread, while executing LoadLibrary
    // with parameter DLL name, will trigger DLLMain
    HANDLE hRemote = CreateRemoteThread(proc, 0, 0, (LPTHREAD_START_ROUTINE)GetProcAddress(GetModuleHandleA("Kernel32.dll"),
        "LoadLibraryA"), (LPVOID)memAddr, 0,0);
    if (NULL == hRemote) {
        err = GetLastError();
        return 0;
    }
    WaitForSingleObject(hRemote, INFINITE);
    check = CloseHandle(hRemote);
    VirtualFreeEx(proc, memAddr, strlen(DLL_PATH) + 1, MEM_RELEASE);
    system("pause");
    return 0;
}

The call to GetLastError returned 5.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • 1
    What is the error returned by `GetLastError`? – 1201ProgramAlarm Mar 14 '20 at 21:31
  • 2
    [Error 5](https://learn.microsoft.com/en-us/windows/win32/debug/system-error-codes--0-499-) is Access Denied. Do you have all the correct permissions? – 1201ProgramAlarm Mar 14 '20 at 21:47
  • 4
    The path of your compiled DLL suggests you're building a 32-bit version. If you're on a 64-bit Windows, then notepad.exe is also 64-bit. You can't mix 32/64 bit. – rustyx Mar 14 '20 at 21:51
  • @rustyx i dont know what you mean by that i built a basic dll on VS i dont know if its 64-bit or 32-bit am on 64-bit windows 10 btw – tameer kenaan Mar 14 '20 at 21:57

1 Answers1

3

The lpStartAddress parameter of the function CreateRemoteProcess requires the address of the function in the virtual address space of the target process (notepad.exe). However, you are passing the address of this function in the address space of the injector program.

This wouldn't be a problem if the address of the function were the same in the virtual address space of both processes. In current versions of Windows, kernel32.dll is loaded to the same address for all 32-bit processes and it is also loaded to the same address for all 64-bit processes. However, the address it is loaded to is different for 32-bit and 64-bit processes. Therefore, the address of the function LoadLibraryA in kernel32.dll will also be different if one process is 32-bit and the other is 64-bit.

By passing the address of LoadLibraryA in its own address space to the call to CreateRemoteThread, your injector program is assuming that kernel32.dll is loaded to the same address in both its address space and in the address space of the target program (notepad.exe). However, as stated above, this assumption is only true if both processes are 32-bit or both are 64-bit.

Judging by your comments in the comments section, it seems that your injector program is 32-bit whereas the target process (notepad.exe) is 64-bit. Therefore, to fix this problem, you should change the build target in Visual Studio from "x86" (32-bit) to "x64" (64-bit).

Another problem is that the DLL that you are injecting must also be 64-bit. As stated in this StackOverflow question, it is not possible to load a 32-bit DLL as executable code into a 64-bit process.

Andreas Wenzel
  • 22,760
  • 4
  • 24
  • 39