gowinapihookinjectdll-injection

How to do dll injection


I tried to do DLL injection with Go, but failed.

I am preparing the DLL file that I will inject with C++. Is that the problem?

DLL prepared with C++:

image

I tired to inject the DLL file with Go like this:

image

But when the CreateRemoteThread() function worked, Notepad++ was closed.

image

Why did I fail? Where did I go wrong?

TestD.dll code:

#include "pch.h"    

BOOL APIENTRY DllMain(HMODULE hModule,
    DWORD  ul_reason_for_call,
    LPVOID lpReserved
)
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
    {
        MessageBox(NULL, L"DLL_PROCESS_ATTACH STARTED", L"DLL_PROCESS_ATTACH TITLE", MB_RETRYCANCEL);
    }
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

Go InjectApp code:

var dllPath = "C:\\Users\\RecaiCingoz\\go\\src\\TestD.dll"
    className := syscall.StringToUTF16Ptr("Notepad++")
    hwnd := win32services.FindWindowW(className, nil)
    fmt.Println("Process HWND", hwnd)

    _, processID := win32services.GetWindowThreadProcessId(hwnd)
    hProcess, _ := win32services.OpenProcess(win32services.PROCESS_ALL_ACCESS, false, uint32(processID))

    baseAddress, _ := win32services.VirtualAllocEx(hProcess, 0, len(dllPath), win32services.MEM_COMMIT, win32services.PAGE_READWRITE)
    err := win32services.WriteProcessMemory(hProcess, uint32(baseAddress), []byte(dllPath), 0)
    if err != nil {
        fmt.Println(err)
    }

    modLib, _ := syscall.LoadLibrary("kernel32.dll")
    loadLib, err := syscall.GetProcAddress(modLib, "LoadLibraryA")
    if err != nil {
        fmt.Println(err)
    }

    hRemoteThread, _, err := win32services.CreateRemoteThread(hProcess, nil, 0, loadLib, baseAddress, 0)
fmt.Println(hRemoteThread)

}

CreateRemoteProccess func:

func CreateRemoteThread(hprocess HANDLE, sa *syscall.SecurityAttributes,
    stackSize uint32, startAddress uintptr, parameter uintptr, creationFlags uint32) (HANDLE, uint32, error) {
    var threadId uint32
    r1, _, e1 := procCreateRemoteThread.Call(
        uintptr(hprocess),
        uintptr(unsafe.Pointer(sa)),
        uintptr(stackSize),
        startAddress,
        parameter,
        uintptr(creationFlags),
        uintptr(unsafe.Pointer(&threadId)))

    if int(r1) == 0 {
        return INVALID_HANDLE, 0, e1
    }
    return HANDLE(r1), threadId, e1
}

How can I do DLL injection in Go? Can anyone help me?

WriteProcessMemory

Edited to added

Codes have been updated. Current code.

Application crash continues. (Notepad++)

package main

import (
    "github.com/JamesHovious/w32"
    "syscall"
)

func main() {
    dllPath, _ := syscall.FullPath("DTest.dll")

    className, _ := syscall.UTF16PtrFromString("Notepad++")
    hwnd := w32.FindWindowW(className, nil)
    _, processId := w32.GetWindowThreadProcessId(hwnd)

    var dwMemSize int
    var hProc w32.HANDLE
    var err error
    var lpRemoteRem, lpLoadLibrary uintptr

    hProc, err = w32.OpenProcess(w32.PROCESS_ALL_ACCESS, false, uint32(processId))
    if err == nil {
        dwMemSize = len(dllPath) + 1
        lpRemoteRem, err = w32.VirtualAllocEx(hProc, 0, dwMemSize, w32.MEM_RESERVE|w32.MEM_COMMIT, w32.PAGE_READWRITE)
        if err == nil {
            err = w32.WriteProcessMemory(hProc, uint32(lpRemoteRem), []byte(dllPath), uint(dwMemSize))
            if err == nil {
                modulKernel, _ := syscall.LoadLibrary("kernel32.dll")
                lpLoadLibrary, err = syscall.GetProcAddress(modulKernel, "LoadLibraryA")
                if err == nil {
                    hTread, _, err := w32.CreateRemoteThread(hProc, nil, 0, uint32(lpLoadLibrary), lpRemoteRem, 0)
                    if err == nil {
                        w32.ResumeThread(hTread)
                        w32.WaitForSingleObject(hTread, syscall.INFINITE)
                        _, err := w32.GetExitCodeProcess(hProc)
                        if err == nil {
                            w32.CloseHandle(hTread)
                        } else {
                            panic(err)
                        }
                    } else {

                    }
                } else {
                    panic(err)
                }
            } else {
                panic(err)
            }
        } else {
            w32.VirtualFreeEx(hProc, lpRemoteRem, 0, w32.MEM_RELEASE)
            panic(err)
        }
    } else {
        panic(err)
    }

    w32.CloseHandle(hProc)

}

Error message i see when i llok at the event log


Solution

  • LoadLibrary return type: syscall.Handle - type Handle uintptr . Return value: 140715276042240 GetProcAddress return type uintptr. Return value: 140715276174480

    140715276042240 and 140715276174480 are truncated x64 addresses. The maximum address of x86 is 0xFFFFFFFF, which becomes 4294967295 after converting to decimal.

    You use GO(x64 version) to compile the program, and use uint32 to convert the address to x86 address. Finally, you get an invalid address. This is why notepad++ crashed.

    Solution: Use GO(x86) to compile the program.