Search code examples
cwindowsdlldll-injection

C Windows DLL Injection Notepad crashes


i have tryed a DLL Injection on the Programm Notepad.exe

But if i start my Injector, notepad Crashes. Here is my Injector Code:

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

char const Path[]="C:\\Users\\IEUser\\Desktop\\Mydll.dll";
int main(void) {

    HANDLE hWnd, hProcess, AllocAdresse, hRemoteThread;
        DWORD PID;

        hWnd = FindWindow(0,"Untitled - Notepad");
        GetWindowThreadProcessId((HWND)hWnd, &PID);

        hProcess = OpenProcess(PROCESS_ALL_ACCESS, false, PID);

        AllocAdresse = VirtualAllocEx(hProcess, 0, sizeof(Path), MEM_COMMIT, PAGE_EXECUTE_READWRITE);
        WriteProcessMemory(hProcess, (void*)AllocAdresse, (void*)Path, sizeof(Path), 0);
        hRemoteThread=CreateRemoteThread(hProcess, 0, 0, (LPTHREAD_START_ROUTINE) GetProcAddress(GetModuleHandle("kernel32.dll"),"LoadLibraryA"), AllocAdresse, 0, 0);
        WaitForSingleObject(hRemoteThread, INFINITE);
        VirtualFreeEx(hProcess, AllocAdresse, sizeof(Path), MEM_DECOMMIT);
        CloseHandle(hProcess);
        return 0;
}

And this is my Code for my DLL File:

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

void InjNachricht() {
    MessageBox(0, "It Works", "My DLL File", 0);
}

int WINAPI DllMain(HINSTANCE hInst,DWORD reason,LPVOID reserved) {
    if(reason==DLL_PROCESS_ATTACH)
        CreateThread(0, 0, (LPTHREAD_START_ROUTINE) InjNachricht, 0, 0, 0);
    return 0;
}

I compile this Code in my Linux machine with MinGW:

(Injector) i686-w64-mingw32-gcc -o Injector.exe injector.c
(DLL-File) i686-w64-mingw32-gcc -o Mydll.dll mydll.c

I also written a Function for Setting Debug Privileges:

void SetDebugPrivilege() {
    HANDLE hProcess=GetCurrentProcess(), hToken;
    TOKEN_PRIVILEGES priv;
    LUID luid;

    OpenProcessToken(hProcess, TOKEN_ADJUST_PRIVILEGES, &hToken);
    LookupPrivilegeValue(0, "seDebugPrivilege", &luid);

    priv.PrivilegeCount = 1;
    priv.Privileges[0].Luid = luid;
    priv.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, false, &priv, 0, 0, 0);

    CloseHandle(hToken);
}

And if i Run my Program in my Virtual Machine: Notepad.exe Crash

Why is notepad crashing? If i inject my dll File with the Program it works: enter image description here

And please do not come with me now "Then I use the program instead of writing a separate injector" !! That does not help me any further !!


Solution

  • Firstly, you can use strlen/wcslen (first is for Ascii encoding, latter for Unicode encoding) instead for calculating the length of a buffer. It's more appropriate in my opinion.

    Here's a properly working variant of DLL injection via remote threads which I've written as a demonstration example for you. It is a quick example so don't expect too much, extremely simplistic. You can improve it by using shell-code injection and then utilise a manual map loader or LdrLoadDll.

    BOOLEAN InjectDll(
        HANDLE ProcessHandle,
        CHAR *DllPath
    )
    {
        BOOLEAN BlStatus = FALSE;
        HANDLE ThreadHandle = 0;
        PVOID LoadLibraryAddress = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
        PVOID DllMemory = 0;
        SIZE_T DllLength = strlen(DllPath);
    
        if (!ProcessHandle ||
            !DllPath ||
            !LoadLibraryAddress)
        {
            return FALSE;
        }
    
        DllMemory = VirtualAllocEx(ProcessHandle,
            NULL,
            DllLength,
            MEM_RESERVE | MEM_COMMIT,
            PAGE_READWRITE);
    
        if (!DllMemory)
        {
            return FALSE;
        }
    
        BlStatus = WriteProcessMemory(ProcessHandle,
            DllMemory,
            DllPath,
            DllLength,
            NULL);
    
        if (!BlStatus)
        {
            goto cleanup;
        }
    
        ThreadHandle = CreateRemoteThread(ProcessHandle,
            NULL,
            0,
            (LPTHREAD_START_ROUTINE)LoadLibraryAddress,
            DllMemory,
            0,
            0);
    
    cleanup:
        if (!ThreadHandle)
        {
            if (DllMemory)
            {
                VirtualFree(DllMemory,
                    NULL,
                    MEM_RELEASE);
            }
    
            BlStatus = FALSE;
        }
        else
        {
            BlStatus = TRUE;
        }
    
        return BlStatus;
    }
    

    On that note, you may be interested in NtOpenProcess, NtAllocateVirtualMemory, NtWriteVirtualMemory, RtlCreateUserThread/NtCreateThreadEx and NtAdjustPrivilegesToken. As for CreateRemoteThread, it won't work with processes on other user accounts, whereas RtlCreateUserThread/NtCreateThreadEx both will (as long as you have debugging rights - SeDebugPrivilege).

    As a last pointer, make sure you compile with /MT so the run-time is statically linked (especially for the DLL you're injecting). If my example code does not help you, and you still cannot fix the issue, try using a debugger to diagnose the issue. You should already have tried doing this, debuggers are there for a reason!