DLL注入触发AccessException读写受保护内存 原因未知求排查
异常触发原因分析
- 栈不平衡(函数执行完抛出异常的核心诱因):C#与C的布尔类型封送不匹配。C#默认
bool为1字节,C的BOOL是4字节的别名,你当前的DllImport未对UseExtended参数做特殊封送处理,会导致调用栈被破坏,异常在函数执行完毕、栈回退时抛出。 - 内存分配/写入逻辑错误:
VirtualAllocEx和WriteProcessMemory中错误使用sizeof buffer、sizeof DllPath获取大小,这两个变量都是指针,最终获取的是指针本身的长度(32位环境4字节、64位环境8字节),远小于实际DLL路径字符串的长度。你写入目标进程的路径是不完整的,LoadLibrary读取不完整的字符串时会访问到非法内存,触发访问冲突。 - 路径写入对象错误:你已经调用
GetFullPathName把完整路径写入了buffer变量,但实际WriteProcessMemory写入的是原始输入的DllPath,没有使用已经处理好的完整路径,可能存在路径不合法的问题。 - 字符集封送风险:
DllImport未显式指定字符集,C#字符串默认封送行为受系统环境影响,可能导致传入C++的ANSI字符串出现乱码,最终LoadLibrary加载失败甚至触发非法访问。
修复&排查方案
- 修复C#互操作声明:
// 显式指定字符集为ANSI,布尔类型封送为4字节的Win32 BOOL [DllImport(path, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Ansi)] static extern int UserInject(uint ProcId, string DllPath, [MarshalAs(UnmanagedType.Bool)] bool UseExtended);
- 修正C++注入代码的内存操作逻辑:
// VirtualAllocEx 分配大小改为实际路径长度,内存属性仅需可读可写即可 memry = VirtualAllocEx( hProc, nullptr, length * sizeof(CHAR), MEM_COMMIT | MEM_RESERVE, // 替换你的SHELLCODE_ALLOCATION宏,确保是常规内存分配标记 PAGE_READWRITE ); AssertNonNull(memry, INVALID_BUFSIZE); // 写入处理好的完整路径buffer,长度匹配实际路径长度 WriteProcessMemory( hProc, memry, buffer, length * sizeof(CHAR), &write ); // 校验实际写入长度等于预期长度 if (write != length * sizeof(CHAR)) return ERR_SOLID_BUFFER;
- 补充资源释放逻辑:所有打开的进程句柄、线程句柄使用完调用
CloseHandle释放,new申请的buffer调用delete[]释放,避免资源泄漏。 - 临时调试验证:修复上述问题后如果仍有异常,可先固定传入短路径的测试DLL(比如
C:\\test.dll),排除路径长度、字符集相关问题后再逐步扩展场景。
内容的提问来源于stack exchange,提问作者wellinthatcase
相关产品推荐
相关产品推荐

