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++:
I tired to inject the DLL file with Go like this:
But when the CreateRemoteThread()
function worked, Notepad++ was closed.
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?
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)
}
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.