c++winapidll-injection

CreateRemoteThread + LoadLibraryA doesn't do anything despite succeeding


Despite the fact that memory allocation/write, finding LoadLibraryA address and creating a remote thread return valid (not NULL) results, absolutely nothing happens after that (mainly, the DllMain of the loaded DLL doesn't seem to get called).

#define PROC_NAME L"TestConsole.exe"
#define DLL_NAME "TestLib.dll\0"

HANDLE GetProcessByName(const wchar_t* name);

int main()
{
    const char dllName[] = DLL_NAME;
    int dllNameSize = strlen(dllName) + 1;

    HANDLE process = GetProcessByName(PROC_NAME);

    LPVOID allocMem = VirtualAllocEx(process, NULL, dllNameSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);

    WriteProcessMemory(process, allocMem, dllName, dllNameSize, NULL);

    // Just to make sure
    char buff[20];
    ReadProcessMemory(process, allocMem, buff, dllNameSize, NULL);
    printf("Data: %s\n", buff);

    LPVOID libraryAddress =
        (LPVOID)GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryA");

    HANDLE remoteThread = CreateRemoteThread(process, NULL, NULL, (LPTHREAD_START_ROUTINE)libraryAddress, allocMem, NULL, NULL);
}

HANDLE GetProcessByName(const wchar_t* name)
{
    PROCESSENTRY32 entry;
    entry.dwSize = sizeof(PROCESSENTRY32);

    HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, NULL);

    if (Process32First(snapshot, &entry) == TRUE)
    {
        while (Process32Next(snapshot, &entry) == TRUE)
        {
            if (wcscmp(entry.szExeFile, name) == 0)
            {
                return OpenProcess(PROCESS_ALL_ACCESS, FALSE, entry.th32ParentProcessID);
            }
        }
    }

    return NULL;
}

Things I know/checked:


Solution

  • The entry.th32ParentProcessID is the identifier of the process that created this process (its parent process). which means you did inject into the parent process of the target process (explorer.exe in my test). You should use entry.th32ProcessID instead.

    In addition, the open permission PROCESS_ALL_ACCESS used in OpenProcess is too large, you only need to use what the CreateRemoteThread document requires: PROCESS_CREATE_THREAD | PROCESS_QUERY_INFORMATION | PROCESS_VM_OPERATION | PROCESS_VM_WRITE | PROCESS_VM_READ