如何读取当前进程虚拟内存?读取Win32ThreadInfo失败求助
解决Win32ThreadInfo读取失败的问题
核心问题分析
你的代码存在几个关键错误,导致ReadProcessMemory读取Win32ThreadInfo失败:
- 字符串类型强制转换导致错误信息乱码,无法准确排查问题
- 64位地址被截断,导致进程句柄获取错误
- TEB/THREADINFO结构体定义不匹配系统实际结构
- 远程地址的类型转换错误
- 资源泄漏(未关闭进程句柄)
具体修复步骤
1. 修复字符串显示问题
所有MessageBox调用使用MessageBoxA(匹配ASCII字符串),避免强制转换导致的乱码:
// 替换前 MessageBox(NULL,(LPCWSTR)"Error: Unable to create snapshot!!! ", ...); // 替换后 MessageBoxA(NULL, "Error: Unable to create snapshot!!! ", "FUNC STATE", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2);
2. 修复64位地址截断问题
由于你是在注入后的进程内执行代码,直接使用GetCurrentProcess()获取当前进程句柄即可,无需重新打开,避免进程ID转换错误:
// 替换原OpenProcess代码 HANDLE processHandle = GetCurrentProcess();
3. 使用正确的TEB/THREADINFO结构体定义
Windows x64下TEB的Win32ThreadInfo偏移为0x4E8,THREADINFO的结构体需匹配系统定义,以下是简化版(确保偏移正确):
// x64 TEB结构体(仅保留关键字段) typedef struct _TEB { PVOID Reserved1[12]; PVOID ProcessEnvironmentBlock; PVOID Reserved2[399]; BYTE Reserved3[1952]; PVOID TlsSlots[64]; BYTE Reserved4[8]; PVOID Reserved5[26]; PVOID ReservedForOle; PVOID Reserved6[4]; PVOID TlsExpansionSlots; PVOID Win32ThreadInfo; // 偏移0x4E8 } TEB, *PTEB; // THREADINFO结构体(简化版,保留_DESKTOP相关字段) typedef struct _THREADINFO { // 省略其他字段,需根据系统实际定义补充 PVOID rpdesk; // 对应_DESKTOP指针 } THREADINFO, *PTHREADINFO;
注:可通过WinDbg执行dt ntdll!_TEB和dt win32k!_THREADINFO确认结构体的准确偏移和字段。
4. 修复ReadProcessMemory的地址参数
teb.Win32ThreadInfo是远程进程内的地址,直接传递给ReadProcessMemory即可,无需强制转换为本地指针:
// 替换原错误代码 if (ReadProcessMemory(processHandle, teb.Win32ThreadInfo, &thread_info, sizeof(thread_info), &threadInfo_t)) { MessageBoxA(NULL, "Successfully read process memory", "FUNC STATE", MB_CANCELTRYCONTINUE | MB_DEFBUTTON2); } else { char errMsg[100]; sprintf(errMsg, "Error: Unable to read Win32ThreadInfo. Error code: %d", GetLastError()); MessageBoxA(NULL, errMsg, "FUNC STATE", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2); }
5. 优化线程获取逻辑
无需遍历所有线程,直接获取当前执行线程的TEB(x64下通过GS寄存器读取):
// 定义获取当前TEB的宏 #define NtCurrentTeb() ((PTEB)__readgsqword(0x30)) // 在代码中直接使用 PTEB teb = NtCurrentTeb(); // 无需再通过NtQueryInformationThread获取TebBaseAddress
6. 清理资源
确保关闭所有打开的句柄(如线程快照句柄、线程句柄),避免资源泄漏。
完整修复后的核心代码片段
DWORD RemoteFunc(LPVOID lpParam) { // 获取当前线程TEB #define NtCurrentTeb() ((PTEB)__readgsqword(0x30)) PTEB teb = NtCurrentTeb(); HANDLE processHandle = GetCurrentProcess(); SIZE_T threadInfo_t = 0; THREADINFO thread_info; // 直接读取Win32ThreadInfo(无需先读取整个TEB) if (ReadProcessMemory(processHandle, teb->Win32ThreadInfo, &thread_info, sizeof(thread_info), &threadInfo_t)) { MessageBoxA(NULL, "Successfully read Win32ThreadInfo", "FUNC STATE", MB_CANCELTRYCONTINUE | MB_DEFBUTTON2); // 访问_DESKTOP字段(即thread_info.rpdesk) } else { char errMsg[100]; sprintf(errMsg, "Error: Unable to read Win32ThreadInfo. Error code: %d", GetLastError()); MessageBoxA(NULL, errMsg, "FUNC STATE", MB_ICONWARNING | MB_CANCELTRYCONTINUE | MB_DEFBUTTON2); } return 0; }
额外注意事项
- 确保你的DLL是x64架构编译,匹配Windows 11 x64环境
- 管理员权限已足够,但需确保目标进程未启用Protected Process Light(PPL)等防护机制
- 不同Windows版本的TEB/THREADINFO结构体可能有变化,需根据实际系统版本调整结构体定义
内容的提问来源于stack exchange,提问作者Flint0fWalrus
相关产品推荐
相关产品推荐

