【问题标题】:Get 32bit PEB of another process from a x64 process从 x64 进程获取另一个进程的 32 位 PEB
【发布时间】:2016-01-12 05:09:51
【问题描述】:

我有一个 64 位进程,需要读取 Wow64 进程的 32 位 PEB。

我可以使用NtQueryInformationProcess 获得它,但我意识到 Wow64 进程有两个 PEB(64 位和 32 位),NtQueryInformationProcess 返回与调用者位数相对应的 PEB(在我的情况下为 64 位) ,正如@Anders 在此解决方案中评论的那样:

How to get the Process Environment Block (PEB) from extern process?

这是我的场景:我正在尝试从 x64 进程内部获取 Wow64 进程的 32 位 PEB。任何涉及更改该场景的建议都是无用的。我也知道这种解决方案不推荐用于生产,这不是我的意图。

有什么想法吗?

提前致谢。

【问题讨论】:

    标签: c++ winapi


    【解决方案1】:

    如果你阅读了 MSDN 上的NtQueryInterformationProcess() 文档,有一条评论说:

    似乎在(至少)Windows Vista 中查询在 wow64 下运行的进程时,返回的 PebBaseAddress 实际上是在 wow64 下加载的 64 位模块。从我所做的一些初步调查来看,与 32 位模块有关的 PEB 似乎可以通过获取 PebBaseAddress 并从其值中减去一页 (0x1000) 来找到。我已经通过检查进程的 TIB 并按照它们的 PEB 指针返回到一个地址来最低限度地证实了这一假设,到目前为止,该地址始终显示为与此函数返回的 PebBaseAddress 值相比为 -0x1000。

    更新:我只是 found this code 指出上述内容从 Windows 8 开始将不起作用,但确实提供了替代解决方案:

    #define TEB32OFFSET 0x2000
    
    void interceptNtDll32(HANDLE hProcess)
    {
        THREAD_BASIC_INFORMATION tbi;
        NTSTATUS ntrv;
        TEB32 teb32;
        void *teb32addr;
        PEB_LDR_DATA32 ldrData;
        PEB32 peb32;
        LIST_ENTRY32 *pMark = NULL;
        LDR_DATA_TABLE_ENTRY32 ldrDataTblEntry;
        size_t bytes_read;
        HANDLE hThread = getThreadHandle(hProcess);
    
        /* Used to be able to get 32 bit PEB from PEB64 with 0x1000 offset but
           Windows 8 changed that so we do it indirectly from the TEB */
        if(!hThread)
            return;
    
        /* Get thread basic information to get 64 bit TEB */
        ntrv = NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), NULL);
        if(ntrv != 0){
            goto out;
        }
    
        /* Use magic to find 32 bit TEB */
        teb32addr = (char *)tbi.TebBaseAddress + TEB32OFFSET; // Magic...
        ntrv = NtReadVirtualMemory(hProcess, teb32addr, &teb32, sizeof(teb32), NULL);
        if(ntrv != 0 || teb32.NtTib.Self != (DWORD)teb32addr){  // Verify magic...
            goto out;
        }
    
        /* TEB32 has address for 32 bit PEB.*/
        ntrv = NtReadVirtualMemory(hProcess, (void *)teb32.ProcessEnvironmentBlock, &peb32, sizeof(peb32), NULL);
        if(ntrv != 0){
            goto out;
        }
    
        ...
    

    【讨论】:

    【解决方案2】:

    你可以使用 NtQueryInformationProcess

    https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess#ulong_ptr

    将 ProcessInformationClass 设置为 ProcessWow64Information

    设置一个指针来接收 ProcessInformation 的值

    调用api时,ProcessInformation的值如果不为零,则为wow64进程的pebBaseAddr

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-05
      • 1970-01-01
      • 2011-11-18
      • 2015-08-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多