从x64进程获取另一进程的32位PEB [英] Get 32bit PEB of another process from a x64 process
问题描述
我有一个64位进程,需要读取32位PEB的Wow64进程。
我可以得到它与 NtQueryInformationProcess
,但我意识到Wow64进程有两个PEB(64和32位)和 NtQueryInformationProcess
返回对应于调用者的位的PEB 64位在我的情况下),作为@Anders评论在这个解决方案:
这是我的场景:我试图从x64进程内获得一个Wow64进程的32位PEB。任何涉及改变这种情况的建议都是无用的。我也知道这种解决方案不推荐用于生产,这不是我的意图。
任何想法?
提前感谢。
如果您阅读了 NtQueryInterformationProcess()
文档在MSDN上, / p>
更新:我只是发现这个代码,说明上述将无法在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屋!