package main

import (
    "fmt"
    "golang.org/x/sys/windows"
)

func main() {
    pid := 1234 // 目标进程PID
    dllPath := "C:\\test.dll" // DLL路径

    err := injectDLL(pid, dllPath)
    if err != nil {
        fmt.Println("DLL注入失败:", err)
    } else {
        fmt.Println("DLL注入成功")
    }
}

func injectDLL(pid int, dllPath string) error {
    // 打开目标进程,获取句柄
    hProcess, err := windows.OpenProcess(windows.PROCESS_CREATE_THREAD|windows.PROCESS_QUERY_INFORMATION|windows.PROCESS_VM_OPERATION|windows.PROCESS_VM_WRITE|windows.PROCESS_VM_READ, false, uint32(pid))
    if err != nil {
        return err
    }
    defer windows.CloseHandle(hProcess)

    // 在目标进程中申请一段内存,用于存放DLL路径
    dllPathLength := len(dllPath) + 1
    remoteDllPath, err := windows.VirtualAllocEx(hProcess, 0, uint32(dllPathLength), windows.MEM_COMMIT, windows.PAGE_READWRITE)
    if err != nil {
        return err
    }
    defer windows.VirtualFreeEx(hProcess, remoteDllPath, 0, windows.MEM_RELEASE)

    // 将DLL路径写入目标进程中申请的内存中
    dllPathBytes := []byte(dllPath)
    _, err = windows.WriteProcessMemory(hProcess, uintptr(remoteDllPath), &dllPathBytes[0], uint32(dllPathLength), nil)
    if err != nil {
        return err
    }

    // 获取LoadLibraryA函数的地址
    kernel32 := windows.NewLazySystemDLL("kernel32.dll")
    loadLibraryAddr := kernel32.NewProc("LoadLibraryA").Addr()

    // 在目标进程中创建远程线程,调用LoadLibraryA函数,将DLL路径作为参数传入
    remoteThread, err := windows.CreateRemoteThread(hProcess, nil, 0, uintptr(loadLibraryAddr), remoteDllPath, 0, nil)
    if err != nil {
        return err
    }
    defer windows.CloseHandle(remoteThread)

    // 等待远程线程结束
    _, err = windows.WaitForSingleObject(remoteThread, windows.INFINITE)
    if err != nil {
        return err
    }

    return nil
}