Search code examples
cdll-injection

DLL injection using C crash notepad


I created a DLL injector program using C and a DLL. When I am trying to run the program the target process crash (I tried a notepad and cmd). I am compiling the injector as 64 bit and the DLL as well. the program and the DLL compiled with Visual Studio.

After some checks a saw if I remove the CreateRemoteThread The program will not crash, and the DLL injected (of course without executing the DLL).

I tried to use RUNDLL32.exe to check if the DLL is the problem and I have been able to see the message box.

Injector:

#include <Windows.h>
#include <stdio.h>

int main() {
    // The DLL path we want to inject and the target process id.
    LPCSTR dllpath = "C:\\Users\\....\\hello-world.dll";
    int processID = 2980;

    printf("#### Starting ####\n");

    // Open target process handle    
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, processID);
    if (hProcess == NULL) {

        //close handles
        CloseHandle(hProcess);

        printf("[!] Unable to find the target process id: %d\n" , processID);
        return 1;
    }
    printf("[+] Open target process handle\n");

    // Getting targt memory address for the dll path
    LPVOID dllpathMemoryAddr = VirtualAllocEx(hProcess, NULL, strlen(dllpath) + 1, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);
    if (dllpathMemoryAddr == NULL) {

        //close handles
        CloseHandle(hProcess);

        printf("[!] Unable to get memory address of target process for the dllpath");
        return 1;
    }
    printf("[+] Allocate the memory address to store the dllpath\n");

    // Writing the dll path to the target memory address
    BOOL succeedWrite = WriteProcessMemory(hProcess, dllpathMemoryAddr, dllpath, strlen(dllpath) + 1, NULL);
    if (!succeedWrite) {

        //close handles
        CloseHandle(hProcess);

        printf("[!] Unable to write to the memory address of target process the dllpath\n");
        return 1;
    }
    printf("[+] Writed the dllpath to memory\n");

    // Getting LoadLibreryA address
    FARPROC loadLibAddr = 
        (GetModuleHandle(TEXT("kernel32.dll")), "LoadLibraryA");
    if (loadLibAddr == NULL) {
        // free the memory 
        VirtualFreeEx(hProcess, dllpathMemoryAddr, 0, MEM_RELEASE);

        //close handles
        CloseHandle(hProcess);

        printf("[!] Unable to get the memory address of LoadLibraryA function\n");
        return 1;
    }
    printf("[+] Allocate the memory address to LoadLibraryA function\n");

    // Create remote thread on the remote process to load the dll
    HANDLE rThread = CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE)loadLibAddr, dllpathMemoryAddr, 0, NULL);
    if (rThread == NULL) {
        // free the memory 
        VirtualFreeEx(hProcess, dllpathMemoryAddr, 0, MEM_RELEASE);

        //close handles
        CloseHandle(hProcess);

        printf("[!] Unable to create thread to execute the LoadLibraryA function\n the error: %u\n", GetLastError());
        return 1;
    }
    printf("[+] Created remote thread to execute the dll\n");
    // Waiting to opertion to complete
    WaitForSingleObject(rThread, INFINITE);

    // free the memory 
    VirtualFreeEx(hProcess, dllpathMemoryAddr, 0, MEM_RELEASE);

    //close handles
    CloseHandle(hProcess);
    CloseHandle(rThread);

    printf("#### DLL INJECTED ####\n");


    return TRUE;
}

DLL

#define WIN32_LEAN_AND_MEAN
#include <stdio.h>
#include <windows.h>

extern "C" __declspec(dllexport)
BOOL APIENTRY DllMain(HMODULE hModule,
                      DWORD ul_reason_for_call,
                      LPVOID lpReserved) {
  switch (ul_reason_for_call) {
    case DLL_PROCESS_ATTACH:
      MessageBox(NULL, "Hello world!", "Hello World!", NULL);
      break;
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
      break;
  }
  return TRUE;
}

output:

#### Starting ####
[+] Open target process handle
[+] Allocate the memory address to store the dllpath
[+] Writed the dllpath to memory
[+] Allocate the memory address to LoadLibraryA function
[+] Created remote thread to execute the dll
#### DLL INJECTED ####

Solution

  • If I understand the comments of the OP correctly, the main problem was that the OP had originally used the following line (before editing the question):

    BOOL succeedWrite = WriteProcessMemory(hProcess, dllpathMemoryAddr, dllpath, strlen(dllpath), NULL);

    By writing strlen(dllpath) instead of strlen(dllpath) + 1 bytes, the OP did not write the terminating null character of the string into the remote process. Therefore, the remote process likely crashed when that non-terminated string was passed as a function parameter to LoadLibraryA.

    As pointed out in the comments section, there were also some other problems with the code, but it is unlikely that these were the cause of the crash.