从x64进程获取另一进程的32位PEB [英] Get 32bit PEB of another process from a x64 process

查看:986
本文介绍了从x64进程获取另一进程的32位PEB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



我可以得到它与 NtQueryInformationProcess ,但我意识到Wow64进程有两个PEB(64和32位)和 NtQueryInformationProcess 返回对应于调用者的位的PEB 64位在我的情况下),作为@Anders评论在这个解决方案:



如何从extern进程获取进程环境块(PEB)?



这是我的场景:我试图从x64进程内获得一个Wow64进程的32位PEB。任何涉及改变这种情况的建议都是无用的。我也知道这种解决方案不推荐用于生产,这不是我的意图。



任何想法?



提前感谢。

解决方案

如果您阅读了 NtQueryInterformationProcess() 文档在MSDN上, / p>

看起来在(至少)Windows Vista中查询在wow64下运行的进程时,返回的PebBaseAddress实际上是64位的,位模块加载在wow64下。从一些初始调查,我做了看起来,通过采用PebBaseAddress并从其值减去一页(0x1000)可以找到与32位模块有关的PEB 。我通过检查进程的TIB并跟踪它们的PEB指针回到到目前为止,总是显示为从这个函数返回的PebBaseAddress值的-0x1000的地址,我最低限度地确认了这个假设。


更新:我只是发现这个代码,说明上述将无法在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);

/ *用于能够从PEB64获取32位PEB的0x1000偏移,但
Windows 8改变了所以我们从TEB * /
if(! hThread)
return;

/ *获取线程基本信息以获取64位TEB * /
ntrv = NtQueryInformationThread(hThread,ThreadBasicInformation,& tbi,sizeof(tbi),NULL);
if(ntrv!= 0){
goto out;
}

/ *使用magic查找32位TEB * /
teb32addr =(char *)tbi.TebBaseAddress + TEB32OFFSET; // Magic ...
ntrv = NtReadVirtualMemory(hProcess,teb32addr,& teb32,sizeof(teb32),NULL);
if(ntrv!= 0 || teb32.NtTib.Self!=(DWORD)teb32addr){//验证魔法...
goto out;
}

/ * TEB32有32位PEB的地址* /
ntrv = NtReadVirtualMemory(hProcess,(void *)teb32.ProcessEnvironmentBlock,& peb32,sizeof ), 空值);
if(ntrv!= 0){
goto out;
}

...


I have a 64 bit process that needs to read the 32bit PEB of a Wow64 process.

I'm able to get it with NtQueryInformationProcess, but I realized that Wow64 processes have two PEBs (64 and 32 bit) and NtQueryInformationProcess returns the PEB corresponding to the bitness of the caller (64bit in my case), as @Anders commented in this solution:

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

That's my scenario: I'm trying to get the 32bit PEB of a Wow64 process, from inside a x64 process. Any suggestions that involve changing that scenario are useless. I'm also aware that this kind of solution is not recommended for production and that's not my intention.

Any ideas?

Thanks in advance.

解决方案

If you read the NtQueryInterformationProcess() documentation on MSDN, there is a comment that says:

It appears that when querying a process running under wow64 in (at least) windows Vista the PebBaseAddress returned is actually for the 64-bit modules loaded under wow64. From some initial investigations I've done it appears that the PEB which pertains to 32-bit modules can be found by taking the PebBaseAddress and subtracting one page (0x1000) from its value. I have minimally confirmed this hypothesis by inspecting the process's TIB's and following their PEB pointers back to an address which, so far, has always shown to be -0x1000 from the PebBaseAddress value returned by this function.

Update: I just found this code that states the above will not work from Windows 8 onwards, but does provide an alternative solution:

#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;
    }

    ...

这篇关于从x64进程获取另一进程的32位PEB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆