You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Golang通过CreateRemoteThread实现DLL注入无报错未生效问题求助

核心失效原因

  • 写入目标进程的DLL路径没有NULL终止符:LoadLibraryA依赖字符串末尾的\0判断路径结束,你直接转换[]byte(dllPath)没有追加终止符,导致函数读取到非法内存的乱码,加载路径错误直接失败。
  • 路径受Windows文件系统重定向影响:32位程序在64位系统下访问C:\Windows\System32会被自动重定向到C:\Windows\SysWOW64,如果目标路径下不存在对应DLL会加载失败。
  • 未等待远程线程执行完成:CreateRemoteThread是异步调用,你没有等待线程执行完毕就结束了注入进程,可能出现线程还没完成DLL加载就被系统回收资源的情况。
  • 内存分配大小不合理:你用LoadLibraryA(ANSI版本)不需要分配len(dllPath)*2的空间,该大小是给宽字符版本LoadLibraryW使用的,多余分配无意义,反而增加出错概率。
  • 缺少有效返回值校验:你只校验了error返回,没有判断Win32 API返回的句柄/地址是否为无效值,部分API执行失败时error可能为nil,但返回值为NULL代表执行失败。
  • 权限不足:注入其他进程需要管理员权限运行注入程序,普通用户权限下OpenProcess会静默获取到无效句柄,后续操作全部失效但无明显报错。

修复方案

  1. 给DLL路径追加NULL终止符
  2. 关闭文件系统重定向,或者改用Sysnative别名访问真实System32目录,或者直接把目标DLL放到不受重定向影响的路径(比如C:\test.dll)
  3. 调用WaitForSingleObject等待远程线程执行完成,再释放资源
  4. 校验所有Win32 API的返回值是否为无效值
  5. 以管理员身份运行编译后的注入程序
  6. 确认目标进程ID确实为32位Notepad++的进程ID

修复后参考代码

package main

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

func main() {
	// 建议先把测试dll放到C盘根目录避免重定向问题
	dllPath := "C:\\wevtapi.dll"
	// 给路径追加NULL终止符
	dllPathBytes := append([]byte(dllPath), 0)
	procID := 8124 // 请确认这里是32位Notepad++的正确进程ID

	hProc, handleErr := w32.OpenProcess(w32.PROCESS_ALL_ACCESS, false, uint32(procID))
	if handleErr != nil || hProc == 0 {
		fmt.Println("OpenProcess失败:", handleErr)
		return
	}
	defer w32.CloseHandle(hProc)

	kernel32DLL, dllLoadErr := syscall.LoadLibrary("kernel32.dll")
	if dllLoadErr != nil || kernel32DLL == 0 {
		fmt.Println("加载kernel32失败:", dllLoadErr)
		return
	}
	defer syscall.FreeLibrary(kernel32DLL)

	addr, addrErr := syscall.GetProcAddress(syscall.Handle(kernel32DLL), "LoadLibraryA")
	if addrErr != nil || addr == 0 {
		fmt.Println("获取LoadLibraryA地址失败:", addrErr)
		return
	}

	// 分配大小改为带终止符的实际路径长度
	arg, allocErr := w32.VirtualAllocEx(hProc, 0, len(dllPathBytes), w32.MEM_RESERVE|w32.MEM_COMMIT, w32.PAGE_READWRITE)
	if allocErr != nil || arg == 0 {
		fmt.Println("VirtualAllocEx失败:", allocErr)
		return
	}

	writeErr := w32.WriteProcessMemory(hProc, uint32(arg), dllPathBytes, 0)
	if writeErr != nil {
		fmt.Println("WriteProcessMemory失败:", writeErr)
		w32.VirtualFreeEx(hProc, arg, 0, w32.MEM_RELEASE)
		return
	}

	hThread, _, threadErr := w32.CreateRemoteThread(hProc, nil, 0, uint32(addr), arg, 0)
	if threadErr != nil || hThread == 0 {
		fmt.Println("CreateRemoteThread失败:", threadErr)
		w32.VirtualFreeEx(hProc, arg, 0, w32.MEM_RELEASE)
		return
	}
	defer w32.CloseHandle(hThread)
	// 等待远程线程执行完成,超时时间5秒
	w32.WaitForSingleObject(hThread, 5000)
	// 释放分配的远程内存
	w32.VirtualFreeEx(hProc, arg, 0, w32.MEM_RELEASE)

	fmt.Println("注入执行完成")
}

内容的提问来源于stack exchange,提问作者pepperoni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 12:54:02