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

如何读取当前进程虚拟内存?读取Win32ThreadInfo失败求助

解决Win32ThreadInfo读取失败的问题

核心问题分析

你的代码存在几个关键错误,导致ReadProcessMemory读取Win32ThreadInfo失败:

  1. 字符串类型强制转换导致错误信息乱码,无法准确排查问题
  2. 64位地址被截断,导致进程句柄获取错误
  3. TEB/THREADINFO结构体定义不匹配系统实际结构
  4. 远程地址的类型转换错误
  5. 资源泄漏(未关闭进程句柄)

具体修复步骤

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 14:54:52